a mini social media app for small communities

add favicons and separate user settings from the user page

+4 -1
doc/todo.md
··· 4 5 ## in-progress 6 7 ## planing 8 9 - - [ ] post:replies 10 - [ ] post:tags ('hashtags') 11 - [ ] post:images (should have a config.maple toggle to enable/disable) 12 - [ ] post:saving (add the post to a list of saved posts that a user can view later) 13 14 ## ideas 15
··· 4 5 ## in-progress 6 7 + - [ ] post:replies 8 + 9 ## planing 10 11 - [ ] post:tags ('hashtags') 12 - [ ] post:images (should have a config.maple toggle to enable/disable) 13 - [ ] post:saving (add the post to a list of saved posts that a user can view later) 14 + - [ ] user:change password 15 + - [ ] user:change username 16 17 ## ideas 18
+9
src/pages.v
··· 33 return ctx.redirect('/user/${user.username}') 34 } 35 36 fn (mut app App) admin(mut ctx Context) veb.Result { 37 ctx.title = '${app.config.instance.name} dashboard' 38 user := app.whoami(mut ctx) or { User{} }
··· 33 return ctx.redirect('/user/${user.username}') 34 } 35 36 + fn (mut app App) settings(mut ctx Context) veb.Result { 37 + user := app.whoami(mut ctx) or { 38 + ctx.error('not logged in') 39 + return ctx.redirect('/login') 40 + } 41 + ctx.title = '${app.config.instance.name} - settings' 42 + return $veb.html() 43 + } 44 + 45 fn (mut app App) admin(mut ctx Context) veb.Result { 46 ctx.title = '${app.config.instance.name} dashboard' 47 user := app.whoami(mut ctx) or { User{} }
src/static/favicon/favicon-144x.png

This is a binary file and will not be displayed.

src/static/favicon/favicon-16x.png

This is a binary file and will not be displayed.

src/static/favicon/favicon-32x.png

This is a binary file and will not be displayed.

src/static/favicon/favicon-48x.png

This is a binary file and will not be displayed.

src/static/favicon/favicon-64x.png

This is a binary file and will not be displayed.

src/static/favicon/favicon-96x.png

This is a binary file and will not be displayed.

src/static/favicon/favicon.ico

This is a binary file and will not be displayed.

+15 -5
src/templates/partial/footer.html
··· 1 </main> 2 3 <footer> 4 - <p>powered by beep</p> 5 - <p><a href="https://github.com/emmathemartian/beep">source</a></p> 6 - @if app.config.dev_mode 7 - <p>token: @{ctx.get_cookie('token')}</p> 8 - @end 9 </footer> 10 11 </body>
··· 1 </main> 2 3 <footer> 4 + <p> 5 + <a href="/settings">settings</a> 6 + - 7 + 8 + @if app.config.dev_mode || (ctx.is_logged_in() && user.admin) 9 + <a href="/admin">admin</a> 10 + - 11 + @end 12 + 13 + @if ctx.is_logged_in() 14 + <a href="/api/user/logout">log out</a> 15 + @end 16 + </p> 17 + 18 + <p>powered by <a href="https://github.com/emmathemartian/beep">beep</a></p> 19 </footer> 20 21 </body>
+4 -7
src/templates/partial/header.html
··· 7 <link rel="icon" href="/favicon.png" /> 8 <meta name="viewport" content="width=device-width, initial-scale=1" /> 9 <title>@ctx.title</title> 10 @include 'assets/style.html' 11 @if ctx.is_logged_in() && user.theme != none 12 <link rel="stylesheet" href="@user.get_theme()"> 13 @else if app.config.instance.default_theme != '' 14 <link rel="stylesheet" href="@app.config.instance.default_theme"> 15 @endif 16 </head> 17 18 <body> ··· 26 <a href="/">home</a> 27 - 28 29 - @if app.config.dev_mode || (ctx.is_logged_in() && user.admin) 30 - <a href="/admin">admin</a> 31 - - 32 - @end 33 - 34 @if ctx.is_logged_in() 35 <a href="/me">profile</a> 36 - 37 <a href="/inbox">inbox@{app.get_notification_count_for_frontend(user.id, 99)}</a> 38 - - 39 - <a href="/api/user/logout">log out</a> 40 @else 41 <a href="/login">log in</a> 42 <span>or</span>
··· 7 <link rel="icon" href="/favicon.png" /> 8 <meta name="viewport" content="width=device-width, initial-scale=1" /> 9 <title>@ctx.title</title> 10 + 11 @include 'assets/style.html' 12 + 13 @if ctx.is_logged_in() && user.theme != none 14 <link rel="stylesheet" href="@user.get_theme()"> 15 @else if app.config.instance.default_theme != '' 16 <link rel="stylesheet" href="@app.config.instance.default_theme"> 17 @endif 18 + 19 + <link rel="shortcut icon" href="/static/favicon/favicon.ico" type="image/png" sizes="16x16 32x32"> 20 </head> 21 22 <body> ··· 30 <a href="/">home</a> 31 - 32 33 @if ctx.is_logged_in() 34 <a href="/me">profile</a> 35 - 36 <a href="/inbox">inbox@{app.get_notification_count_for_frontend(user.id, 99)}</a> 37 @else 38 <a href="/login">log in</a> 39 <span>or</span>
+117
src/templates/settings.html
···
··· 1 + @include 'partial/header.html' 2 + 3 + @if ctx.is_logged_in() 4 + <h1>user settings:</h1> 5 + 6 + <form action="/api/user/set_bio" method="post"> 7 + <label for="bio">bio:</label> 8 + <br> 9 + <textarea 10 + name="bio" 11 + id="bio" 12 + cols="30" 13 + rows="10" 14 + minlength="@app.config.user.bio_min_len" 15 + maxlength="@app.config.user.bio_max_len" 16 + required 17 + >@user.bio</textarea> 18 + <br> 19 + <input type="submit" value="save"> 20 + </form> 21 + 22 + <hr> 23 + 24 + <form action="/api/user/set_pronouns" method="post"> 25 + <label for="pronouns">pronouns:</label> 26 + <input 27 + type="text" 28 + name="pronouns" 29 + id="pronouns" 30 + minlength="@app.config.user.pronouns_min_len" 31 + maxlength="@app.config.user.pronouns_max_len" 32 + pattern="@app.config.user.pronouns_pattern" 33 + value="@user.pronouns" 34 + required 35 + > 36 + <input type="submit" value="save"> 37 + </form> 38 + 39 + <hr> 40 + 41 + <form action="/api/user/set_nickname" method="post"> 42 + <label for="nickname">nickname:</label> 43 + <input 44 + type="text" 45 + name="nickname" 46 + id="nickname" 47 + pattern="@app.config.user.nickname_pattern" 48 + minlength="@app.config.user.nickname_min_len" 49 + maxlength="@app.config.user.nickname_max_len" 50 + value="@{user.nickname or { '' }}" 51 + required 52 + > 53 + <input type="submit" value="save"> 54 + </form> 55 + 56 + <form action="/api/user/set_nickname" method="post"> 57 + <input type="submit" value="reset nickname"> 58 + </form> 59 + 60 + @if app.config.instance.allow_changing_theme 61 + <hr> 62 + <form action="/api/user/set_theme" method="post"> 63 + <label for="url">theme:</label> 64 + <input type="url" name="url" id="url" value="@{user.theme or { '' }}"> 65 + <input type="submit" value="save"> 66 + </form> 67 + @end 68 + 69 + <hr> 70 + 71 + <details> 72 + <summary>dangerous settings (click to reveal)</summary> 73 + <div> 74 + <details> 75 + <summary>account deletion (click to reveal)</summary> 76 + <form action="/api/user/delete" autocomplete="off"> 77 + <input 78 + type="number" 79 + name="id" 80 + id="id" 81 + value="@user.id" 82 + required 83 + readonly 84 + hidden 85 + aria-hidden 86 + > 87 + <p><strong>there is NO GOING BACK after deleting your account.</strong></p> 88 + <p><strong>EVERY ONE of your posts, notifications, likes, dislikes, and ALL OTHER USER DATA WILL BE PERMANENTLY DELETED</strong></p> 89 + <div> 90 + <input type="checkbox" name="are-you-sure" id="are-you-sure" required> 91 + <label for="are-you-sure">click to confirm</label> 92 + </div> 93 + <br> 94 + <div> 95 + <input type="checkbox" name="are-you-really-sure" id="are-you-really-sure" required> 96 + <label for="are-you-really-sure">click to doubly confirm</label> 97 + </div> 98 + <br> 99 + <div> 100 + <input type="checkbox" name="are-you-absolutely-sure" id="are-you-absolutely-sure" required> 101 + <label for="are-you-absolutely-sure">click to triply confirm</label> 102 + </div> 103 + <br> 104 + <details> 105 + <summary>(click to reveal deletion button)</summary> 106 + <input type="submit" value="delete your account"> 107 + </details> 108 + </form> 109 + </details> 110 + </div> 111 + </details> 112 + 113 + @else 114 + <p>uh oh, you need to be logged in to view this page!</p> 115 + @end 116 + 117 + @include 'partial/footer.html'
+1 -97
src/templates/user.html
··· 75 @end 76 </div> 77 78 - @if app.logged_in_as(mut ctx, viewing.id) 79 - <div> 80 - <h2>user settings:</h2> 81 - <form action="/api/user/set_bio" method="post"> 82 - <label for="bio">bio:</label> 83 - <br> 84 - <textarea 85 - name="bio" 86 - id="bio" 87 - cols="30" 88 - rows="10" 89 - minlength="@app.config.user.bio_min_len" 90 - maxlength="@app.config.user.bio_max_len" 91 - required 92 - >@user.bio</textarea> 93 - <input type="submit" value="save"> 94 - </form> 95 - <form action="/api/user/set_pronouns" method="post"> 96 - <label for="pronouns">pronouns:</label> 97 - <input 98 - type="text" 99 - name="pronouns" 100 - id="pronouns" 101 - minlength="@app.config.user.pronouns_min_len" 102 - maxlength="@app.config.user.pronouns_max_len" 103 - pattern="@app.config.user.pronouns_pattern" 104 - value="@user.pronouns" 105 - required 106 - > 107 - <br> 108 - <input type="submit" value="save"> 109 - </form> 110 - <form action="/api/user/set_nickname" method="post"> 111 - <label for="nickname">nickname:</label> 112 - <input 113 - type="text" 114 - name="nickname" 115 - id="nickname" 116 - pattern="@app.config.user.nickname_pattern" 117 - minlength="@app.config.user.nickname_min_len" 118 - maxlength="@app.config.user.nickname_max_len" 119 - value="@{user.nickname or { '' }}" 120 - required 121 - > 122 - <input type="submit" value="save"> 123 - </form> 124 - <form action="/api/user/set_nickname" method="post"> 125 - <input type="submit" value="reset nickname"> 126 - </form> 127 - @if app.config.instance.allow_changing_theme 128 - <br> 129 - <form action="/api/user/set_theme" method="post"> 130 - <label for="url">theme:</label> 131 - <input type="url" name="url" id="url" value="@{user.theme or { '' }}"> 132 - <input type="submit" value="save"> 133 - </form> 134 - @end 135 - <br> 136 - <details> 137 - <summary>dangerous settings (click to reveal)</summary> 138 - <div> 139 - <form action="/api/user/delete" autocomplete="off"> 140 - <input 141 - type="number" 142 - name="id" 143 - id="id" 144 - value="@user.id" 145 - required 146 - readonly 147 - hidden 148 - aria-hidden 149 - > 150 - <p><strong>there is NO GOING BACK after deleting your account.</strong></p> 151 - <p><strong>EVERY ONE of your posts, notifications, likes, dislikes, and ALL OTHER USER DATA WILL BE PERMANENTLY DELETED</strong></p> 152 - <div> 153 - <input type="checkbox" name="are-you-sure" id="are-you-sure" required> 154 - <label for="are-you-sure">click to confirm</label> 155 - </div> 156 - <br> 157 - <div> 158 - <input type="checkbox" name="are-you-really-sure" id="are-you-really-sure" required> 159 - <label for="are-you-really-sure">click to doubly confirm</label> 160 - </div> 161 - <br> 162 - <div> 163 - <input type="checkbox" name="are-you-absolutely-sure" id="are-you-absolutely-sure" required> 164 - <label for="are-you-absolutely-sure">click to triply confirm</label> 165 - </div> 166 - <br> 167 - <input type="submit" value="delete your account"> 168 - </form> 169 - </div> 170 - </details> 171 - </div> 172 - @end 173 - 174 @if ctx.is_logged_in() && user.admin 175 <div> 176 <h2>admin powers:</h2> ··· 214 </div> 215 @end 216 217 - @include 'partial/footer.html'
··· 75 @end 76 </div> 77 78 @if ctx.is_logged_in() && user.admin 79 <div> 80 <h2>admin powers:</h2> ··· 118 </div> 119 @end 120 121 + @include 'partial/footer.html'