a mini social media app for small communities

add nicknaming

+6
build.maple
··· 48 48 category = 'run' 49 49 run = '${v} -d veb_livereload watch run ${v_main} config.maple' 50 50 } 51 + 52 + task:run.real = { 53 + description = 'Run beep using config.real.maple' 54 + category = 'run' 55 + run = '${v} -d veb_livereload watch run ${v_main} config.real.maple' 56 + }
+1 -1
config.maple
··· 23 23 username_pattern = '[a-z0-9_.]+' 24 24 nickname_min_len = 1 25 25 nickname_max_len = 20 26 - nickname_pattern = '.+' 26 + nickname_pattern = '\S.*' 27 27 password_min_len = 12 28 28 password_max_len = 72 29 29 password_pattern = '.+'
+20
src/api.v
··· 123 123 return ctx.redirect('/login') 124 124 } 125 125 126 + @['/api/user/set_nickname'; post] 127 + fn (mut app App) api_user_set_nickname(mut ctx Context) veb.Result { 128 + mut nickname := ?string(ctx.form['nickname'] or { '' }) 129 + if (nickname or { '' }) == '' { 130 + nickname = none 131 + } 132 + user := app.whoami(mut ctx) or { 133 + ctx.error('you are not logged in!') 134 + return ctx.redirect('/login') 135 + } 136 + sql app.db { 137 + update User set nickname = nickname where id == user.id 138 + } or { 139 + ctx.error('failed to change nickname') 140 + eprintln('failed to update nickname for ${user} (${user.nickname} -> ${nickname})') 141 + return ctx.redirect('/me') 142 + } 143 + return ctx.redirect('/me') 144 + } 145 + 126 146 ////// Posts ////// 127 147 128 148 @['/api/post/new_post'; post]
+10 -10
src/app.v
··· 5 5 import db.pg 6 6 import entity { User, Post } 7 7 8 - pub struct Context { 9 - veb.Context 10 - pub mut: 11 - title string 12 - } 13 - 14 8 pub struct App { 15 9 pub: 16 10 config Config ··· 86 80 return none 87 81 } 88 82 89 - pub fn (ctx &Context) is_logged_in() bool { 90 - return ctx.get_cookie('token') or { '' } != '' 83 + pub fn (app &App) get_unknown_user() User { 84 + return User{ username: 'unknown' } 91 85 } 92 86 93 - pub fn (app &App) get_unknown_user() User { 94 - return User{ username: 'unknown' } 87 + pub struct Context { 88 + veb.Context 89 + pub mut: 90 + title string 91 + } 92 + 93 + pub fn (ctx &Context) is_logged_in() bool { 94 + return ctx.get_cookie('token') or { '' } != '' 95 95 }
+18 -2
src/templates/login.html
··· 13 13 @else 14 14 <form action="/api/user/login" method="post"> 15 15 <label for="username">username:</label> 16 - <input type="text" name="username" id="username"> 16 + <input 17 + type="text" 18 + name="username" 19 + id="username" 20 + pattern="@app.config.user.username_pattern" 21 + minlength="@app.config.user.username_min_len" 22 + maxlength="@app.config.user.username_max_len" 23 + required 24 + > 17 25 <br> 18 26 <label for="password">password:</label> 19 - <input type="password" name="password" id="password"> 27 + <input 28 + type="password" 29 + name="password" 30 + id="password" 31 + pattern="@app.config.user.password_pattern" 32 + minlength="@app.config.user.password_min_len" 33 + maxlength="@app.config.user.password_max_len" 34 + required 35 + > 20 36 <br> 21 37 <input type="submit" value="log in"> 22 38 </form>
+24
src/templates/me.html
··· 12 12 id="title" 13 13 minlength="1" 14 14 maxlength="@app.config.post.title_max_len" 15 + placeholder="title" 15 16 > 16 17 <br> 17 18 <textarea ··· 19 20 id="body" 20 21 minlength="1" 21 22 maxlength="@app.config.post.body_max_len" 23 + rows="10" 24 + cols="30" 25 + placeholder="body" 22 26 ></textarea> 23 27 <br> 24 28 <input type="submit" value="post!"> ··· 37 41 <p>display name: @user.get_name()</p> 38 42 <p><a href="/api/user/logout">log out</a></p> 39 43 <p><a href="/api/user/full_logout">log out of all devices</a></p> 44 + </div> 45 + <div> 46 + <h2>settings:</h2> 47 + <form action="/api/user/set_nickname" method="post"> 48 + <label for="nickname">nickname:</label> 49 + <input 50 + type="text" 51 + name="nickname" 52 + id="nickname" 53 + pattern="@app.config.user.nickname_pattern" 54 + minlength="@app.config.user.nickname_min_len" 55 + maxlength="@app.config.user.nickname_max_len" 56 + value="@{user.nickname or { '' }}" 57 + required 58 + > 59 + <input type="submit" value="update"> 60 + </form> 61 + <form action="/api/user/set_nickname" method="post"> 62 + <input type="submit" value="reset nickname"> 63 + </form> 40 64 </div> 41 65 42 66 @else
+18 -2
src/templates/register.html
··· 13 13 @else 14 14 <form action="/api/user/register" method="post"> 15 15 <label for="username">username:</label> 16 - <input type="text" name="username" id="username"> 16 + <input 17 + type="text" 18 + name="username" 19 + id="username" 20 + pattern="@app.config.user.username_pattern" 21 + minlength="@app.config.user.username_min_len" 22 + maxlength="@app.config.user.username_max_len" 23 + required 24 + > 17 25 <br> 18 26 <label for="password">password:</label> 19 - <input type="password" name="password" id="password"> 27 + <input 28 + type="password" 29 + name="password" 30 + id="password" 31 + pattern="@app.config.user.password_pattern" 32 + minlength="@app.config.user.password_min_len" 33 + maxlength="@app.config.user.password_max_len" 34 + required 35 + > 20 36 <br> 21 37 <input type="submit" value="register"> 22 38 </form>