๐Ÿ“๐Ÿ–ผ๏ธ๐Ÿน A small thing where I can upload a file and get a link back. https://media.strawmelonjuice.com/
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

cherry on top!

+70 -50
+59 -46
dashboard/src/strawmediajuice_fe.gleam
··· 10 10 import gleam/javascript/promise 11 11 import gleam/json 12 12 import gleam/list 13 - import gleam/option.{Some} 13 + import gleam/option.{None, Some} 14 14 import gleam/order 15 15 import gleam/string 16 16 import lustre ··· 67 67 } 68 68 #( 69 69 Model( 70 - username: option.None, 71 - password: option.None, 70 + username: None, 71 + password: None, 72 72 files: [], 73 - error_message: option.None, 74 - successfully_uploaded_dialog: option.None, 73 + error_message: None, 74 + successfully_uploaded_dialog: None, 75 75 is_loading: False, 76 - selected_file: option.None, 77 - selected_filename: option.None, 76 + selected_file: None, 77 + selected_filename: None, 78 78 ), 79 79 eff, 80 80 ) ··· 132 132 case username, password { 133 133 Some(u), Some(p) if u != "" && p != "" -> { 134 134 #( 135 - Model(..model, error_message: option.None, is_loading: True), 135 + Model(..model, error_message: None, is_loading: True), 136 136 authenticate(u, p), 137 137 ) 138 138 } 139 139 _, _ -> { 140 140 #( 141 141 Model( 142 - username: option.None, 143 - password: option.None, 142 + username: None, 143 + password: None, 144 144 files: model.files, 145 145 error_message: Some("Please enter both username and password"), 146 - successfully_uploaded_dialog: option.None, 146 + successfully_uploaded_dialog: None, 147 147 is_loading: False, 148 148 selected_file: model.selected_file, 149 149 selected_filename: model.selected_filename, ··· 163 163 username: Some(username), 164 164 password: Some(password), 165 165 files: [], 166 - error_message: option.None, 166 + error_message: None, 167 167 is_loading: True, 168 - selected_file: option.None, 169 - selected_filename: option.None, 170 - successfully_uploaded_dialog: option.None, 168 + selected_file: None, 169 + selected_filename: None, 170 + successfully_uploaded_dialog: None, 171 171 ), 172 172 fetch_files(username, password), 173 173 ) ··· 181 181 files: model.files, 182 182 error_message: Some("Invalid username or password"), 183 183 is_loading: False, 184 - successfully_uploaded_dialog: option.None, 184 + successfully_uploaded_dialog: None, 185 185 selected_file: model.selected_file, 186 186 selected_filename: model.selected_filename, 187 187 ), ··· 273 273 case filename { 274 274 Some(fname) if fname != "" -> { 275 275 #( 276 - Model(..model, is_loading: True, error_message: option.None), 276 + Model(..model, is_loading: True, error_message: None), 277 277 upload_file(username, password, fname, file_content), 278 278 ) 279 279 } ··· 285 285 } 286 286 } 287 287 } 288 - _, _, option.None -> { 288 + _, _, None -> { 289 289 #( 290 290 Model(..model, error_message: Some("Please select a file")), 291 291 effect.none(), ··· 306 306 #( 307 307 Model( 308 308 ..model, 309 - selected_file: option.None, 310 - selected_filename: option.None, 309 + selected_file: None, 310 + selected_filename: None, 311 311 is_loading: False, 312 - error_message: option.None, 312 + error_message: None, 313 313 successfully_uploaded_dialog: Some(file_id), 314 314 ), 315 315 fetch_files(username, password), ··· 573 573 ), 574 574 html.span([attribute.class("text-sm")], [html.text(error)]), 575 575 ]) 576 - option.None -> html.text("") 576 + None -> html.text("") 577 577 }, 578 578 ], 579 579 ), ··· 640 640 event.on("change", decode.success(FileSelected)), 641 641 ]), 642 642 ]), 643 - html.div([attribute.class("form-control")], [ 644 - html.label([attribute.class("label")], [ 645 - html.span([attribute.class("label-text")], [ 646 - html.text("Filename"), 643 + // Filename input 644 + html.div( 645 + [ 646 + attribute.class("form-control"), 647 + case model.selected_file { 648 + Some(..) -> attribute.none() 649 + None -> attribute.class("hidden") 650 + }, 651 + ], 652 + [ 653 + html.label([attribute.class("label")], [ 654 + html.span([attribute.class("label-text")], [ 655 + html.text("Filename"), 656 + ]), 647 657 ]), 648 - ]), 649 - html.input([ 650 - attribute.type_("text"), 651 - attribute.name("filename"), 652 - attribute.placeholder("Enter filename"), 653 - attribute.class( 654 - "input input-bordered input-primary w-full", 655 - ), 656 - case model.selected_filename { 657 - Some(filename) -> attribute.value(filename) 658 - option.None -> attribute.value("") 659 - }, 660 - ]), 661 - ]), 658 + html.input([ 659 + attribute.type_("text"), 660 + attribute.name("filename"), 661 + attribute.placeholder("Enter filename"), 662 + attribute.class( 663 + "input input-bordered input-primary w-full", 664 + ), 665 + case model.selected_filename { 666 + Some(filename) -> attribute.value(filename) 667 + None -> attribute.value("") 668 + }, 669 + ]), 670 + ], 671 + ), 672 + // end 662 673 // base64 field 663 674 html.div([attribute.class("form-control hidden")], [ 664 675 html.label([attribute.class("label")], [ ··· 941 952 ), 942 953 html.span([], [html.text(error)]), 943 954 ]) 944 - option.None -> html.text("") 955 + None -> html.text("") 945 956 }, 946 957 ]), 947 958 ]) ··· 1013 1024 ], 1014 1025 ), 1015 1026 ]) 1016 - option.None -> element.none() 1027 + None -> element.none() 1017 1028 }, 1018 1029 ]), 1019 1030 ], ··· 1022 1033 Some(file_id) -> 1023 1034 html.div( 1024 1035 [ 1025 - attribute.class("alert alert-vertical sm:alert-horizontal"), 1036 + attribute.class( 1037 + "alert alert-vertical sm:alert-horizontal bg-secondary text-secondary-content", 1038 + ), 1026 1039 attribute.role("alert"), 1027 1040 ], 1028 1041 [ ··· 1054 1067 html.a( 1055 1068 [ 1056 1069 attribute.href(window.origin() <> "/file/" <> file_id), 1057 - attribute.class("link link-success"), 1070 + attribute.class("link"), 1058 1071 ], 1059 1072 [html.text(window.origin() <> "/file/" <> file_id)], 1060 1073 ), ··· 1076 1089 ), 1077 1090 ], 1078 1091 ) 1079 - option.None -> element.none() 1092 + None -> element.none() 1080 1093 }, 1081 1094 case model.username { 1082 1095 Some(_) -> view_home(model) 1083 - option.None -> view_login_form(model) 1096 + None -> view_login_form(model) 1084 1097 }, 1085 1098 ]) 1086 1099 }
+11 -4
index.ts
··· 72 72 console.log("All files in database:"); 73 73 console.table(allFiles); 74 74 // for users, log without passwords 75 - const allUsers = db.query(`SELECT * FROM users`).all(); 75 + const allUsersRaw = db.query(`SELECT * FROM users`).all(); 76 + const allUsers = allUsersRaw.map((u: any) => ({ 77 + username: u.username, 78 + "password": u.password_hash, 79 + "megabyte quota": u.max_megabytes, 80 + "used megabytes": u.used_megabytes, 81 + "is admin": u.is_admin, 82 + })); 76 83 console.log("All users in database:"); 77 84 console.table( 78 85 allUsers 79 - .map((u) => ({ ...u, password_hash: "****" })) 80 - .map((u) => ({ ...u, is_admin: u.is_admin ? "yes" : "no" })) 86 + .map((u) => ({ ...u, password: "****" })) 87 + .map((u) => ({ ...u, "is admin": u["is admin"] ? "yes" : "no" })) 81 88 .map((u) => ({ 82 89 ...u, 83 - max_megabytes: u.max_megabytes === 0 ? "unlimited" : u.max_megabytes, 90 + "megabyte quota": u["megabyte quota"] === 0 ? "unlimited" : u["megabyte quota"], 84 91 })), 85 92 ); 86 93