Improvements to profile settings.
This commit is contained in:
parent
87605e7d94
commit
81e5bf5af0
2 changed files with 79 additions and 13 deletions
|
|
@ -1365,7 +1365,7 @@ routes:
|
||||||
profile.threadCount =
|
profile.threadCount =
|
||||||
getValue(db, sql("select count(*) " & threadsFrom), userID).parseInt()
|
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])
|
profile.email = some(userRow[1])
|
||||||
|
|
||||||
for row in db.getAllRows(postsQuery, username):
|
for row in db.getAllRows(postsQuery, username):
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import options, httpcore, json, sugar, times
|
import options, httpcore, json, sugar, times, strformat
|
||||||
|
|
||||||
import threadlist, post, category, error, user
|
import threadlist, post, category, error, user
|
||||||
|
|
||||||
|
|
@ -22,8 +22,13 @@ when defined(js):
|
||||||
ProfileTab* = enum
|
ProfileTab* = enum
|
||||||
Overview, Settings
|
Overview, Settings
|
||||||
|
|
||||||
|
ProfileSettings* = object
|
||||||
|
email: kstring
|
||||||
|
rank: Rank
|
||||||
|
|
||||||
ProfileState* = ref object
|
ProfileState* = ref object
|
||||||
profile: Option[Profile]
|
profile: Option[Profile]
|
||||||
|
settings: ProfileSettings
|
||||||
currentTab: ProfileTab
|
currentTab: ProfileTab
|
||||||
loading: bool
|
loading: bool
|
||||||
status: HttpCode
|
status: HttpCode
|
||||||
|
|
@ -32,9 +37,21 @@ when defined(js):
|
||||||
ProfileState(
|
ProfileState(
|
||||||
loading: false,
|
loading: false,
|
||||||
status: Http200,
|
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) =
|
proc onProfile(httpStatus: int, response: kstring, state: ProfileState) =
|
||||||
# TODO: Try to abstract these.
|
# TODO: Try to abstract these.
|
||||||
state.loading = false
|
state.loading = false
|
||||||
|
|
@ -45,6 +62,7 @@ when defined(js):
|
||||||
let profile = to(parsed, Profile)
|
let profile = to(parsed, Profile)
|
||||||
|
|
||||||
state.profile = some(profile)
|
state.profile = some(profile)
|
||||||
|
resetSettings(state)
|
||||||
|
|
||||||
proc genPostLink(link: PostLink): VNode =
|
proc genPostLink(link: PostLink): VNode =
|
||||||
let url = renderPostUrl(link)
|
let url = renderPostUrl(link)
|
||||||
|
|
@ -60,6 +78,14 @@ when defined(js):
|
||||||
p(title=title):
|
p(title=title):
|
||||||
text renderActivity(link.creation)
|
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*(
|
proc render*(
|
||||||
state: ProfileState,
|
state: ProfileState,
|
||||||
username: string,
|
username: string,
|
||||||
|
|
@ -77,16 +103,34 @@ when defined(js):
|
||||||
let profile = state.profile.get()
|
let profile = state.profile.get()
|
||||||
let isAdmin = currentUser.isSome() and currentUser.get().rank == Admin
|
let isAdmin = currentUser.isSome() and currentUser.get().rank == Admin
|
||||||
|
|
||||||
# TODO: Surely there is a better way to handle this.
|
let rankSelect = buildHtml(tdiv()):
|
||||||
let rankSelect = buildHtml():
|
|
||||||
if isAdmin:
|
if isAdmin:
|
||||||
select(class="form-select", value = $profile.user.rank):
|
select(class="form-select", value = $state.settings.rank):
|
||||||
for r in Rank:
|
for r in Rank:
|
||||||
option(text $r)
|
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:
|
else:
|
||||||
select(class="form-select", value = $profile.user.rank, disabled=""):
|
input(class="form-input",
|
||||||
for r in Rank:
|
`type`="text", value = $state.settings.rank, disabled="")
|
||||||
option(text $r)
|
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():
|
result = buildHtml():
|
||||||
section(class="container grid-xl"):
|
section(class="container grid-xl"):
|
||||||
|
|
@ -135,7 +179,7 @@ when defined(js):
|
||||||
),
|
),
|
||||||
onClick=(e: Event, n: VNode) => (state.currentTab = Overview)
|
onClick=(e: Event, n: VNode) => (state.currentTab = Overview)
|
||||||
):
|
):
|
||||||
a():
|
a(class="c-hand"):
|
||||||
text "Overview"
|
text "Overview"
|
||||||
li(class=class(
|
li(class=class(
|
||||||
{"active": state.currentTab == Settings},
|
{"active": state.currentTab == Settings},
|
||||||
|
|
@ -143,8 +187,9 @@ when defined(js):
|
||||||
),
|
),
|
||||||
onClick=(e: Event, n: VNode) => (state.currentTab = Settings)
|
onClick=(e: Event, n: VNode) => (state.currentTab = Settings)
|
||||||
):
|
):
|
||||||
a():
|
a(class="c-hand"):
|
||||||
text "Settings"
|
italic(class="fas fa-cog")
|
||||||
|
text " Settings"
|
||||||
|
|
||||||
case state.currentTab
|
case state.currentTab
|
||||||
of Overview:
|
of Overview:
|
||||||
|
|
@ -173,13 +218,26 @@ when defined(js):
|
||||||
`type`="text",
|
`type`="text",
|
||||||
value=profile.user.name,
|
value=profile.user.name,
|
||||||
disabled="")
|
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="form-group"):
|
||||||
tdiv(class="col-3 col-sm-12"):
|
tdiv(class="col-3 col-sm-12"):
|
||||||
label(class="form-label"):
|
label(class="form-label"):
|
||||||
text "Email"
|
text "Email"
|
||||||
tdiv(class="col-9 col-sm-12"):
|
tdiv(class="col-9 col-sm-12"):
|
||||||
input(class="form-input",
|
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="form-group"):
|
||||||
tdiv(class="col-3 col-sm-12"):
|
tdiv(class="col-3 col-sm-12"):
|
||||||
label(class="form-label"):
|
label(class="form-label"):
|
||||||
|
|
@ -187,3 +245,11 @@ when defined(js):
|
||||||
tdiv(class="col-9 col-sm-12"):
|
tdiv(class="col-9 col-sm-12"):
|
||||||
rankSelect
|
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"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue