Skip to content

Commit 67c4c86

Browse files
authored
Improve rename account UX (beyond-all-reason#1217)
Changes Recover/Change UI in account settings" Fixes beyond-all-reason#1214 Provides error message if username is over 20 characters. States maximum allowed character length as well as stating maximum username changing frequency. Text no longer clips. <img width="643" height="798" alt="image" src="https://github.com/user-attachments/assets/1b989493-5030-4ede-890d-ebeca40a0a4a" /> used codex for formatting
1 parent 1a9d28f commit 67c4c86

1 file changed

Lines changed: 134 additions & 60 deletions

File tree

LuaMenu/widgets/chobby/components/login_window.lua

Lines changed: 134 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,10 @@ function LoginWindow:init(failFunction, cancelText, windowClassname, params)
5959
Log.Error("Tried to spawn duplicate login window")
6060
return
6161
end
62+
local ww, wh = Spring.GetWindowGeometry()
6263
self.emailRequired = (params and params.emailRequired) or false
63-
self.windowHeight = (params and params.windowHeight) or (self.emailRequired and 460+200) or 420+200
64+
local defaultWindowHeight = (params and params.windowHeight) or (self.emailRequired and 800) or 800
65+
self.windowHeight = math.min(defaultWindowHeight, math.max(740, wh - 20))
6466
self.loginAfterRegister = (params and params.loginAfterRegister) or false
6567

6668
local registerChildren = {}
@@ -557,41 +559,30 @@ function LoginWindow:init(failFunction, cancelText, windowClassname, params)
557559
x = pad + formw * 0 ,
558560
y = pad + formh * 0 ,
559561
width = formw * 3 ,
560-
height = formh * 2 ,
562+
height = 60 ,
561563
-- caption = i18n("register_long"),
562-
text = "Change user name. You must be logged in, and will be logged out on successful change.",
564+
text = "Change username. You must be logged in, and will be logged out on successful change. Max: 20 characters. Cooldown: no more than twice a week, 3/month.",
563565
objectOverrideFont = WG.Chobby.Configuration:GetFont(1),
564566
objectOverrideHintFont = WG.Chobby.Configuration:GetFont(1),
565567
}
566568
recoverChildren[#recoverChildren+1] = self.txtChangeUserName
567569

568-
self.lblChangeUserName = Label:New {
569-
x = pad + formw * 0 ,
570-
y = pad + formh * 1 ,
571-
width = formw * 1 ,
572-
height = formh * 1 ,
573-
-- caption = i18n("register_long"),
574-
caption = "New user name:",
575-
objectOverrideFont = WG.Chobby.Configuration:GetFont(1),
576-
}
577-
recoverChildren[#recoverChildren+1] = self.lblChangeUserName
578-
579570
self.ebChangeUserName = EditBox:New {
580-
x = pad + formw * 1 ,
581-
y = pad + formh * 2 ,
582-
width = formw * 1 ,
571+
x = pad ,
572+
y = 80 ,
573+
width = 350 ,
583574
height = formh * 1 ,
584575
text = Configuration.userName or Configuration.suggestedNameFromSteam or "",
585576
objectOverrideFont = WG.Chobby.Configuration:GetFont(1),
586577
objectOverrideHintFont = WG.Chobby.Configuration:GetFont(1),
587-
tooltip = 'User name may contain only letters, numbers, square brackets and underscores',
578+
tooltip = '3-20 characters. Letters, numbers, square brackets, and underscores only.',
588579
}
589580
recoverChildren[#recoverChildren+1] = self.ebChangeUserName
590581

591582
self.btnChangeUserName = Button:New {
592-
x = pad + formw * 2 ,
593-
y = pad + formh * 2 ,
594-
width = formw * 1 ,
583+
x = pad + 360 ,
584+
y = 80 ,
585+
width = 150 ,
595586
height = formh * 1 ,
596587
caption = i18n("change_username"),
597588
objectOverrideFont = WG.Chobby.Configuration:GetFont(1),
@@ -604,25 +595,36 @@ function LoginWindow:init(failFunction, cancelText, windowClassname, params)
604595
}
605596
recoverChildren[#recoverChildren+1] = self.btnChangeUserName
606597

607-
self.txtErrorChangeUserName = TextBox:New {
598+
self.txtHelpChangeUserName = TextBox:New {
608599
x = pad + formw * 0 ,
609-
y = 4 + pad + formh * 3 ,
610-
width = formw * 3 ,
600+
y = 105 ,
601+
width = formw * 3 + 60 ,
611602
height = formh * 1 ,
612-
text = "If this doesnt work contact us on Discord",
603+
text = "If this doesnt work contact us on Discord.",
604+
objectOverrideFont = WG.Chobby.Configuration:GetFont(1),
605+
objectOverrideHintFont = WG.Chobby.Configuration:GetFont(1),
606+
}
607+
recoverChildren[#recoverChildren+1] = self.txtHelpChangeUserName
608+
609+
self.txtErrorChangeUserName = TextBox:New {
610+
x = pad + formw * 0 ,
611+
y = 128 ,
612+
width = formw * 3 + 60 ,
613+
height = 28 ,
614+
text = "",
613615
objectOverrideFont = WG.Chobby.Configuration:GetFont(1),
614616
objectOverrideHintFont = WG.Chobby.Configuration:GetFont(1),
615617
}
616618
recoverChildren[#recoverChildren+1] = self.txtErrorChangeUserName
617619

618-
recoverChildren[#recoverChildren+1] = Line:New{x=5,y=formh * 5,right=5, height = 1}
620+
recoverChildren[#recoverChildren+1] = Line:New{x=5,y=160,right=5, height = 1}
619621

620622
------------------------------RESET PASSWORD----------------------------------
621623
self.txtResetPassword = TextBox:New {
622624
x = pad + formw * 0 ,
623-
y = pad + formh * 5 ,
625+
y = 168 ,
624626
width = formw * 3 ,
625-
height = formh * 1 ,
627+
height = formh * 2 ,
626628
-- caption = i18n("register_long"),
627629
text = "Reset forgotten password: You need to use your web browser to reset a forgotten password.",
628630
objectOverrideFont = WG.Chobby.Configuration:GetFont(1),
@@ -632,7 +634,7 @@ function LoginWindow:init(failFunction, cancelText, windowClassname, params)
632634

633635
self.btnResetPassword = Button:New {
634636
x = pad + formw * 0 ,
635-
y = pad + formh * 7 ,
637+
y = 220 ,
636638
width = formw * 3 ,
637639
height = formh * 2 ,
638640
caption = "Reset your password via a browser link",
@@ -646,7 +648,7 @@ function LoginWindow:init(failFunction, cancelText, windowClassname, params)
646648
}
647649
recoverChildren[#recoverChildren+1] = self.btnResetPassword
648650

649-
recoverChildren[#recoverChildren+1] = Line:New{x=5,y=formh * 11,right=5, height = 1}
651+
recoverChildren[#recoverChildren+1] = Line:New{x=5,y=280,right=5, height = 1}
650652
--[[
651653
652654
@@ -745,9 +747,9 @@ function LoginWindow:init(failFunction, cancelText, windowClassname, params)
745747
---------------------------Change Password--------------------------------
746748
self.txtChangePassword = TextBox:New {
747749
x = pad + formw * 0 ,
748-
y = pad + formh * 11 ,
750+
y = 292 ,
749751
width = formw * 3 ,
750-
height = formh * 1 ,
752+
height = formh * 2 ,
751753
-- caption = i18n("register_long"),
752754
text = "Change Password: You must be logged in, enter your old and your new password",
753755
objectOverrideFont = WG.Chobby.Configuration:GetFont(1),
@@ -757,7 +759,7 @@ function LoginWindow:init(failFunction, cancelText, windowClassname, params)
757759

758760
self.btnChangePassword = Button:New {
759761
x = pad + formw * 0 ,
760-
y = pad + formh * 13 ,
762+
y = 342 ,
761763
width = formw * 3 ,
762764
height = formh * 2 ,
763765
caption = "Edit your password via a browser link",
@@ -770,7 +772,7 @@ function LoginWindow:init(failFunction, cancelText, windowClassname, params)
770772
},
771773
}
772774
recoverChildren[#recoverChildren+1] = self.btnChangePassword
773-
recoverChildren[#recoverChildren+1] = Line:New{x=5,y=formh * 17,right=5, height = 1}
775+
recoverChildren[#recoverChildren+1] = Line:New{x=5,y=410,right=5, height = 1}
774776

775777
--[[
776778
self.lblChangePasswordOld = Label:New {
@@ -851,9 +853,9 @@ function LoginWindow:init(failFunction, cancelText, windowClassname, params)
851853
---------------------------Change Email-------------------------------
852854
self.txtChangeEmail = TextBox:New {
853855
x = pad + formw * 0 ,
854-
y = pad + formh * 17 ,
855-
width = formw * 3 ,
856-
height = formh * 1 ,
856+
y = 420 ,
857+
width = 520 ,
858+
height = 82 ,
857859
-- caption = i18n("register_long"),
858860
text = "Change email address associated with your account. You must be logged in. Enter the new email address you wish to use, then enter the validation code sent to the new email address.",
859861
objectOverrideFont = WG.Chobby.Configuration:GetFont(1),
@@ -863,19 +865,21 @@ function LoginWindow:init(failFunction, cancelText, windowClassname, params)
863865

864866
self.lblChangeEmailEmail = Label:New {
865867
x = pad + formw * 0 ,
866-
y = pad + formh * 20 ,
867-
width = formw * 1 ,
868+
y = 510 ,
869+
width = 170 ,
868870
height = formh * 1 ,
871+
autosize = false,
872+
valign = "center",
869873
-- caption = i18n("register_long"),
870874
caption = "New email address:",
871875
objectOverrideFont = WG.Chobby.Configuration:GetFont(1),
872876
}
873877
recoverChildren[#recoverChildren+1] = self.lblChangeEmailEmail
874878

875879
self.ebChangeEmailEmail = EditBox:New {
876-
x = pad + formw * 1 ,
877-
y = pad + formh * 20 ,
878-
width = formw * 1 ,
880+
x = 190 ,
881+
y = 510 ,
882+
width = 210 ,
879883
height = formh * 1 ,
880884
text = "",
881885
objectOverrideFont = WG.Chobby.Configuration:GetFont(1),
@@ -886,19 +890,21 @@ function LoginWindow:init(failFunction, cancelText, windowClassname, params)
886890

887891
self.lblChangeEmailVerification = Label:New {
888892
x = pad + formw * 0 ,
889-
y = pad + formh * 19 ,
890-
width = formw * 1 ,
893+
y = 540 ,
894+
width = 170 ,
891895
height = formh * 1 ,
896+
autosize = false,
897+
valign = "center",
892898
-- caption = i18n("register_long"),
893899
caption = "Verification Code:",
894900
objectOverrideFont = WG.Chobby.Configuration:GetFont(1),
895901
}
896902
recoverChildren[#recoverChildren+1] = self.lblChangeEmailVerification
897903

898904
self.ebChangeEmailVerification = EditBox:New {
899-
x = pad + formw * 1 ,
900-
y = pad + formh * 21 ,
901-
width = formw * 1 ,
905+
x = 190 ,
906+
y = 540 ,
907+
width = 210 ,
902908
height = formh * 1 ,
903909
text = "",
904910
objectOverrideFont = WG.Chobby.Configuration:GetFont(1),
@@ -908,9 +914,9 @@ function LoginWindow:init(failFunction, cancelText, windowClassname, params)
908914
recoverChildren[#recoverChildren+1] = self.ebChangeEmailVerification
909915

910916
self.btnChangeEmail = Button:New {
911-
x = pad + formw * 2 ,
912-
y = pad + formh * 20 ,
913-
width = formw * 1 ,
917+
x = 405 ,
918+
y = 510 ,
919+
width = 155 ,
914920
height = formh * 1 ,
915921
caption = i18n("submit_email"),
916922
objectOverrideFont = WG.Chobby.Configuration:GetFont(1),
@@ -924,9 +930,9 @@ function LoginWindow:init(failFunction, cancelText, windowClassname, params)
924930
recoverChildren[#recoverChildren+1] = self.btnChangeEmail
925931

926932
self.btnChangeEmailVerification = Button:New {
927-
x = pad + formw * 2 ,
928-
y = pad + formh * 21 ,
929-
width = formw * 1 ,
933+
x = 405 ,
934+
y = 540 ,
935+
width = 155 ,
930936
height = formh * 1 ,
931937
caption = i18n("submit_verification"),
932938
objectOverrideFont = WG.Chobby.Configuration:GetFont(1),
@@ -941,8 +947,8 @@ function LoginWindow:init(failFunction, cancelText, windowClassname, params)
941947

942948
self.txtErrorChangeEmail = TextBox:New {
943949
x = pad + formw * 0 ,
944-
y = 4 + pad + formh * 22 ,
945-
width = formw * 3 ,
950+
y = 570 ,
951+
width = 560 ,
946952
height = formh * 1 ,
947953
text = "If this doesnt work contact us on Discord",
948954
objectOverrideFont = WG.Chobby.Configuration:GetFont(1),
@@ -997,11 +1003,10 @@ function LoginWindow:init(failFunction, cancelText, windowClassname, params)
9971003

9981004
recoverChildren[#recoverChildren+1] = self.btnTeiserver
9991005

1000-
local ww, wh = Spring.GetWindowGeometry()
1001-
local width = 3 * (formw + 30) --used to be bout tree fiddy
1006+
local width = math.min(620, math.max(580, ww - 20))
10021007

10031008
self.window = Window:New {
1004-
x = math.floor((ww - width) / 2),
1009+
x = math.floor(math.max(0, (ww - width) / 2)),
10051010
y = math.floor(math.max(0,(wh - self.windowHeight) / 2)),
10061011
width = width,
10071012
height = self.windowHeight,
@@ -1070,7 +1075,8 @@ function LoginWindow:init(failFunction, cancelText, windowClassname, params)
10701075
right = 5,
10711076
y = 30,
10721077
bottom = 4,
1073-
horizontalScrollbar = true,
1078+
horizontalScrollbar = false,
1079+
verticalScrollbar = false,
10741080
children = {
10751081
self.tabPanel,
10761082
self.btnCancel
@@ -1097,6 +1103,7 @@ function LoginWindow:init(failFunction, cancelText, windowClassname, params)
10971103
end
10981104

10991105
function LoginWindow:RemoveListeners()
1106+
self:ClearRenameListeners()
11001107
if self.onAgreementEnd then
11011108
lobby:RemoveListener("OnAgreementEnd", self.onAgreementEnd)
11021109
self.onAgreementEnd = nil
@@ -1119,6 +1126,22 @@ function LoginWindow:RemoveListeners()
11191126
end
11201127
end
11211128

1129+
function LoginWindow:ClearRenameListeners()
1130+
self.pendingRenameUserName = nil
1131+
if self.onRenameServerMSG then
1132+
lobby:RemoveListener("OnServerMSG", self.onRenameServerMSG)
1133+
self.onRenameServerMSG = nil
1134+
end
1135+
if self.onRenameDenied then
1136+
lobby:RemoveListener("OnDenied", self.onRenameDenied)
1137+
self.onRenameDenied = nil
1138+
end
1139+
if self.onRenameDisconnected then
1140+
lobby:RemoveListener("OnDisconnected", self.onRenameDisconnected)
1141+
self.onRenameDisconnected = nil
1142+
end
1143+
end
1144+
11221145
function LoginWindow:MayBeDisconnectBeforeTryLogin()
11231146
if lobby:GetConnectionStatus() ~= "connected" then
11241147
self:tryLogin()
@@ -1341,16 +1364,67 @@ end
13411364

13421365
function LoginWindow:tryChangeUserName()
13431366
Spring.Echo("lobby:GetConnectionStatus()",lobby:GetConnectionStatus())
1367+
self:ClearRenameListeners()
13441368
local newusername = self.ebChangeUserName.text
13451369
local isinValidUserName = isInValidUserName(newusername)
13461370
if isinValidUserName then
13471371
self.txtErrorChangeUserName:SetText(Configuration:GetErrorColor() .. isinValidUserName)
13481372
return
13491373
end
13501374
if lobby:GetConnectionStatus() == "connected" then
1375+
local function SetRenameButtonEnabled(enabled)
1376+
if self.btnChangeUserName then
1377+
self.btnChangeUserName:SetEnabled(enabled)
1378+
end
1379+
end
1380+
1381+
local function FinishRenameRequest(message, color)
1382+
self.pendingRenameUserName = nil
1383+
SetRenameButtonEnabled(true)
1384+
if self.txtErrorChangeUserName then
1385+
self.txtErrorChangeUserName:SetText((color or "") .. message)
1386+
end
1387+
self:ClearRenameListeners()
1388+
end
1389+
1390+
local function GetRenameResponseColor(message)
1391+
local lowerMessage = string.lower(tostring(message or ""))
1392+
if lowerMessage:find("success", 1, true) or lowerMessage:find("renamed", 1, true) then
1393+
return Configuration:GetSuccessColor()
1394+
end
1395+
if lowerMessage:find("fail", 1, true) or lowerMessage:find("denied", 1, true) or lowerMessage:find("taken", 1, true) or lowerMessage:find("already", 1, true) or lowerMessage:find("cooldown", 1, true) or lowerMessage:find("week", 1, true) or lowerMessage:find("month", 1, true) or lowerMessage:find("max", 1, true) or lowerMessage:find("too ", 1, true) then
1396+
return Configuration:GetErrorColor()
1397+
end
1398+
return Configuration:GetWarningColor()
1399+
end
1400+
13511401
WG.Analytics.SendOnetimeEvent("lobby:try_changeusername")
1402+
self.pendingRenameUserName = newusername
1403+
SetRenameButtonEnabled(false)
1404+
self.txtErrorChangeUserName:SetText(Configuration:GetWarningColor() .. "Sending rename request for: " .. newusername)
1405+
1406+
self.onRenameServerMSG = function(listener, message)
1407+
FinishRenameRequest(tostring(message or "No message"), GetRenameResponseColor(message))
1408+
end
1409+
lobby:AddListener("OnServerMSG", self.onRenameServerMSG)
1410+
1411+
self.onRenameDenied = function(listener, reason)
1412+
FinishRenameRequest("Rename denied: " .. tostring(reason or "No reason provided"), Configuration:GetErrorColor())
1413+
end
1414+
lobby:AddListener("OnDenied", self.onRenameDenied)
1415+
1416+
self.onRenameDisconnected = function(listener)
1417+
FinishRenameRequest("Disconnected after rename request. This usually means success; log in as: " .. newusername, Configuration:GetWarningColor())
1418+
end
1419+
lobby:AddListener("OnDisconnected", self.onRenameDisconnected)
1420+
1421+
WG.Delay(function()
1422+
if self.pendingRenameUserName == newusername then
1423+
FinishRenameRequest("No reply yet. Check whether you are still connected, then try again if needed.", Configuration:GetWarningColor())
1424+
end
1425+
end, 30)
1426+
13521427
lobby:RenameAccount(newusername)
1353-
self.txtErrorChangeUserName:SetText("You will be disconnected on success. Your new user name is: " .. newusername)
13541428
else
13551429
self.txtErrorChangeUserName:SetText(Configuration:GetErrorColor() .. "Must be logged in to change user name!")
13561430
end

0 commit comments

Comments
 (0)