Improvements to profile settings.

This commit is contained in:
Dominik Picheta 2018-05-17 12:54:50 +01:00
commit 81e5bf5af0
2 changed files with 79 additions and 13 deletions

View file

@ -1365,7 +1365,7 @@ routes:
profile.threadCount =
getValue(db, sql("select count(*) " & threadsFrom), userID).parseInt()
if c.rank >= Admin:
if c.rank >= Admin or c.username == username:
profile.email = some(userRow[1])
for row in db.getAllRows(postsQuery, username):

View file

@ -1,4 +1,4 @@
import options, httpcore, json, sugar, times
import options, httpcore, json, sugar, times, strformat
import threadlist, post, category, error, user
@ -22,8 +22,13 @@ when defined(js):
ProfileTab* = enum
Overview, Settings
ProfileSettings* = object
email: kstring
rank: Rank
ProfileState* = ref object
profile: Option[Profile]
settings: ProfileSettings
currentTab: ProfileTab
loading: bool
status: HttpCode
@ -32,9 +37,21 @@ when defined(js):
ProfileState(
loading: false,
status: Http200,
currentTab: Overview
currentTab: Overview,
settings: ProfileSettings(
email: "",
rank: Spammer
)
)
proc resetSettings(state: ProfileState) =
let profile = state.profile.get()
if profile.email.isSome():
state.settings = ProfileSettings(
email: profile.email.get(),
rank: profile.user.rank
)
proc onProfile(httpStatus: int, response: kstring, state: ProfileState) =
# TODO: Try to abstract these.
state.loading = false
@ -45,6 +62,7 @@ when defined(js):
let profile = to(parsed, Profile)
state.profile = some(profile)
resetSettings(state)
proc genPostLink(link: PostLink): VNode =
let url = renderPostUrl(link)
@ -60,6 +78,14 @@ when defined(js):
p(title=title):
text renderActivity(link.creation)
proc onEmailChange(event: Event, node: VNode, state: ProfileState) =
state.settings.email = node.value
if state.settings.email != state.profile.get().email.get():
state.settings.rank = EmailUnconfirmed
else:
state.settings.rank = state.profile.get().user.rank
proc render*(
state: ProfileState,
username: string,
@ -77,16 +103,34 @@ when defined(js):
let profile = state.profile.get()
let isAdmin = currentUser.isSome() and currentUser.get().rank == Admin
# TODO: Surely there is a better way to handle this.
let rankSelect = buildHtml():
let rankSelect = buildHtml(tdiv()):
if isAdmin:
select(class="form-select", value = $profile.user.rank):
select(class="form-select", value = $state.settings.rank):
for r in Rank:
option(text $r)
p(class="form-input-hint text-warning"):
text "As an admin you can modify anyone's rank. Remember: with " &
"great power comes great responsibility."
else:
select(class="form-select", value = $profile.user.rank, disabled=""):
for r in Rank:
option(text $r)
input(class="form-input",
`type`="text", value = $state.settings.rank, disabled="")
p(class="form-input-hint"):
text "Your rank determines the actions you can perform " &
"on the forum."
case state.settings.rank:
of Spammer, Troll:
p(class="form-input-hint text-warning"):
text "Your account was banned."
of EmailUnconfirmed:
p(class="form-input-hint text-warning"):
text "You cannot post until you confirm your email."
of Moderated:
p(class="form-input-hint text-warning"):
text "Your account is under moderation. This is a spam prevention "&
"measure. You can write posts but only moderators and admins "&
"will see them until your account is verified by them."
else:
discard
result = buildHtml():
section(class="container grid-xl"):
@ -135,7 +179,7 @@ when defined(js):
),
onClick=(e: Event, n: VNode) => (state.currentTab = Overview)
):
a():
a(class="c-hand"):
text "Overview"
li(class=class(
{"active": state.currentTab == Settings},
@ -143,8 +187,9 @@ when defined(js):
),
onClick=(e: Event, n: VNode) => (state.currentTab = Settings)
):
a():
text "Settings"
a(class="c-hand"):
italic(class="fas fa-cog")
text " Settings"
case state.currentTab
of Overview:
@ -173,13 +218,26 @@ when defined(js):
`type`="text",
value=profile.user.name,
disabled="")
p(class="form-input-hint"):
text fmt("Users can refer to you by writing" &
" @{profile.user.name} in their posts.")
tdiv(class="form-group"):
tdiv(class="col-3 col-sm-12"):
label(class="form-label"):
text "Email"
tdiv(class="col-9 col-sm-12"):
input(class="form-input",
`type`="text", value=profile.email.get())
`type`="text", value=state.settings.email,
oninput=(e: Event, n: VNode) =>
onEmailChange(e, n, state)
)
p(class="form-input-hint"):
text "Your avatar is linked to this email and can be " &
"changed at "
a(href="https://gravatar.com/emails"):
text "gravatar.com"
text ". Note that any changes to your email will " &
"require email verification."
tdiv(class="form-group"):
tdiv(class="col-3 col-sm-12"):
label(class="form-label"):
@ -187,3 +245,11 @@ when defined(js):
tdiv(class="col-9 col-sm-12"):
rankSelect
tdiv(class="float-right"):
button(class="btn btn-link",
onClick=(e: Event, n: VNode) => (resetSettings(state))):
text "Cancel"
button(class="btn btn-primary"):
italic(class="fas fa-check")
text " Save"