Merge pull request 'Main' (#7) from main into production
Reviewed-on: admin/step3#7
This commit is contained in:
+122
-32
@@ -25,7 +25,9 @@ var reset_view: VBoxContainer
|
||||
var steam_view: VBoxContainer
|
||||
var login_input: LineEdit
|
||||
var password_input: LineEdit
|
||||
var password_reveal_button: Button
|
||||
var password_reveal_entries: Array[Dictionary] = []
|
||||
var legal_consent_texts: Array[RichTextLabel] = []
|
||||
var legal_consent_squares: Array[Panel] = []
|
||||
var registration_username_input: LineEdit
|
||||
var registration_email_input: LineEdit
|
||||
var registration_password_input: LineEdit
|
||||
@@ -124,8 +126,8 @@ func _build_ui() -> void:
|
||||
page_margin.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
||||
page_margin.add_theme_constant_override("margin_left", 52)
|
||||
page_margin.add_theme_constant_override("margin_right", 52)
|
||||
page_margin.add_theme_constant_override("margin_top", 56)
|
||||
page_margin.add_theme_constant_override("margin_bottom", 56)
|
||||
page_margin.add_theme_constant_override("margin_top", 28)
|
||||
page_margin.add_theme_constant_override("margin_bottom", 28)
|
||||
add_child(page_margin)
|
||||
|
||||
var columns := HBoxContainer.new()
|
||||
@@ -189,23 +191,34 @@ func _build_ui() -> void:
|
||||
panel_center.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
columns.add_child(panel_center)
|
||||
auth_panel = PanelContainer.new()
|
||||
auth_panel.custom_minimum_size = Vector2(710, 820)
|
||||
auth_panel.custom_minimum_size = Vector2(710, 1000)
|
||||
panel_center.add_child(auth_panel)
|
||||
var scroll := ScrollContainer.new()
|
||||
scroll.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED
|
||||
auth_panel.add_child(scroll)
|
||||
panel_gutter = MarginContainer.new()
|
||||
panel_gutter.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
panel_gutter.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
panel_gutter.add_theme_constant_override("margin_right", 28)
|
||||
scroll.add_child(panel_gutter)
|
||||
panel_content = VBoxContainer.new()
|
||||
panel_content.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
panel_content.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
panel_content.add_theme_constant_override("separation", 24)
|
||||
panel_gutter.add_child(panel_content)
|
||||
|
||||
# main_column holds everything except the legal footer and is the part
|
||||
# that should center vertically when a view (e.g. login) is shorter than
|
||||
# the panel - the footer stays pinned to the very bottom either way.
|
||||
var main_column := VBoxContainer.new()
|
||||
main_column.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
main_column.alignment = BoxContainer.ALIGNMENT_CENTER
|
||||
main_column.add_theme_constant_override("separation", 16)
|
||||
panel_content.add_child(main_column)
|
||||
|
||||
var panel_header := HBoxContainer.new()
|
||||
panel_header.add_theme_constant_override("separation", 18)
|
||||
panel_content.add_child(panel_header)
|
||||
main_column.add_child(panel_header)
|
||||
var small_icon := TextureRect.new()
|
||||
small_icon.texture = Brand.ranaze_mark_texture()
|
||||
small_icon.custom_minimum_size = Vector2(72, 72)
|
||||
@@ -229,14 +242,14 @@ func _build_ui() -> void:
|
||||
reset_view = _build_reset_view()
|
||||
steam_view = _build_steam_view()
|
||||
for view in [login_view, register_view, reset_view, steam_view]:
|
||||
panel_content.add_child(view)
|
||||
main_column.add_child(view)
|
||||
|
||||
message_label = Label.new()
|
||||
message_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
message_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
message_label.add_theme_font_size_override("font_size", 14)
|
||||
message_label.add_theme_font_override("font", Brand.font)
|
||||
panel_content.add_child(message_label)
|
||||
main_column.add_child(message_label)
|
||||
var legal_footer := HBoxContainer.new()
|
||||
legal_footer.alignment = BoxContainer.ALIGNMENT_CENTER
|
||||
legal_footer.add_theme_constant_override("separation", 12)
|
||||
@@ -284,7 +297,8 @@ func _build_register_view() -> VBoxContainer:
|
||||
registration_email_input = _add_field(view, "Email", "[email protected]")
|
||||
registration_password_input = _add_field(view, "Password", "At least 8 characters", true)
|
||||
registration_confirm_input = _add_field(view, "Confirm password", "Re-enter your password", true)
|
||||
_add_show_password(view, [registration_password_input, registration_confirm_input])
|
||||
_add_password_reveal(registration_password_input)
|
||||
_add_password_reveal(registration_confirm_input)
|
||||
registration_legal_check = _add_legal_consent(view)
|
||||
_add_primary_button(view, "Create Account", _on_register_pressed)
|
||||
_add_back_button(view, "Already have an account? Sign in", "login")
|
||||
@@ -302,7 +316,8 @@ func _build_reset_view() -> VBoxContainer:
|
||||
reset_code_input.max_length = 6
|
||||
reset_password_input = _add_field(reset_confirm_group, "New password", "At least 8 characters", true)
|
||||
reset_confirm_input = _add_field(reset_confirm_group, "Confirm new password", "Re-enter your new password", true)
|
||||
_add_show_password(reset_confirm_group, [reset_password_input, reset_confirm_input])
|
||||
_add_password_reveal(reset_password_input)
|
||||
_add_password_reveal(reset_confirm_input)
|
||||
_add_primary_button(reset_confirm_group, "Update Password", _confirm_reset)
|
||||
_add_back_button(view, "Back to sign in", "login")
|
||||
reset_confirm_group.visible = false
|
||||
@@ -323,7 +338,7 @@ func _build_steam_view() -> VBoxContainer:
|
||||
steam_username_input = _add_field(view, "Username or email", "Choose a username")
|
||||
steam_email_input = _add_field(view, "Email", "[email protected]")
|
||||
steam_password_input = _add_field(view, "Password", "At least 8 characters", true)
|
||||
_add_show_password(view, [steam_password_input])
|
||||
_add_password_reveal(steam_password_input)
|
||||
steam_legal_check = _add_legal_consent(view)
|
||||
_add_primary_button(view, "Continue", _complete_steam)
|
||||
_add_back_button(view, "Cancel external sign in", "login")
|
||||
@@ -331,17 +346,84 @@ func _build_steam_view() -> VBoxContainer:
|
||||
|
||||
|
||||
func _add_legal_consent(parent: VBoxContainer) -> CheckBox:
|
||||
# A bare CheckBox's own word-wrap left-aligns every wrapped line flush
|
||||
# with the checkbox glyph, so a second line reads as un-indented. Split
|
||||
# the toggle from its text into a row instead - the RichTextLabel's own
|
||||
# wrapping then stays confined to its column, and "Terms of Service"/
|
||||
# "Privacy Policy" render as inline links rather than a duplicate row
|
||||
# of link buttons underneath.
|
||||
#
|
||||
# The actual toggle state lives on a real CheckBox (kept invisible and
|
||||
# out of the row's layout) because other code reads .button_pressed -
|
||||
# but Button/CheckBox reserves vertical space for a text baseline even
|
||||
# with an empty string, which was making the visible square non-square
|
||||
# no matter what custom_minimum_size said. Drawing the visible square
|
||||
# as a plain Panel sidesteps that entirely.
|
||||
var check := CheckBox.new()
|
||||
check.text = "I agree to the Terms of Service and acknowledge the Privacy Policy."
|
||||
check.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
check.visible = false
|
||||
parent.add_child(check)
|
||||
var links := HBoxContainer.new()
|
||||
links.add_theme_constant_override("separation", 12)
|
||||
parent.add_child(links)
|
||||
_add_legal_links(links)
|
||||
|
||||
var margin := MarginContainer.new()
|
||||
margin.add_theme_constant_override("margin_top", 8)
|
||||
margin.add_theme_constant_override("margin_bottom", 8)
|
||||
parent.add_child(margin)
|
||||
var center := CenterContainer.new()
|
||||
margin.add_child(center)
|
||||
var row := HBoxContainer.new()
|
||||
row.add_theme_constant_override("separation", 12)
|
||||
center.add_child(row)
|
||||
|
||||
var square := Panel.new()
|
||||
square.custom_minimum_size = Vector2(20, 20)
|
||||
square.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
|
||||
square.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||
square.mouse_filter = Control.MOUSE_FILTER_STOP
|
||||
square.set_meta("legal_consent_checkbox", check)
|
||||
square.gui_input.connect(func(event: InputEvent):
|
||||
if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT:
|
||||
check.button_pressed = not check.button_pressed
|
||||
)
|
||||
row.add_child(square)
|
||||
legal_consent_squares.append(square)
|
||||
check.toggled.connect(func(_pressed: bool): _refresh_legal_consent_square(square))
|
||||
|
||||
var consent_text := RichTextLabel.new()
|
||||
consent_text.bbcode_enabled = true
|
||||
consent_text.fit_content = true
|
||||
consent_text.scroll_active = false
|
||||
consent_text.meta_underlined = false
|
||||
consent_text.custom_minimum_size = Vector2(480, 0)
|
||||
consent_text.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||
consent_text.add_theme_font_override("normal_font", Brand.font)
|
||||
consent_text.add_theme_font_size_override("normal_font_size", 13)
|
||||
consent_text.meta_clicked.connect(func(meta: Variant): _open_legal_document(str(meta)))
|
||||
legal_consent_texts.append(consent_text)
|
||||
row.add_child(consent_text)
|
||||
return check
|
||||
|
||||
|
||||
func _refresh_legal_consent_text(consent_text: RichTextLabel, dark: bool) -> void:
|
||||
var text_hex := Brand.text_color(dark).to_html(false)
|
||||
var link_hex := (Brand.SKY_BLUE if dark else Brand.ROYAL_BLUE).to_html(false)
|
||||
consent_text.text = (
|
||||
"[color=#%s]I agree to the [/color][url=terms][color=#%s]Terms of Service[/color][/url][color=#%s] and acknowledge the [/color][url=privacy][color=#%s]Privacy Policy[/color][/url][color=#%s].[/color]"
|
||||
% [text_hex, link_hex, text_hex, link_hex, text_hex]
|
||||
)
|
||||
|
||||
|
||||
func _refresh_legal_consent_square(square: Panel) -> void:
|
||||
var dark := UIThemeService.is_dark_mode()
|
||||
var accent := Brand.SKY_BLUE if dark else Brand.ROYAL_BLUE
|
||||
var checked := square.get_meta("legal_consent_checkbox", null) as CheckBox
|
||||
var is_checked := checked != null and checked.button_pressed
|
||||
var box := StyleBoxFlat.new()
|
||||
box.bg_color = accent if is_checked else Color.TRANSPARENT
|
||||
box.border_color = accent
|
||||
box.set_border_width_all(2)
|
||||
box.set_corner_radius_all(5)
|
||||
square.add_theme_stylebox_override("panel", box)
|
||||
|
||||
|
||||
func _add_legal_links(parent: HBoxContainer) -> void:
|
||||
for spec in [["Terms of Service", "terms"], ["Privacy Policy", "privacy"]]:
|
||||
var link := Button.new()
|
||||
@@ -357,7 +439,7 @@ func _open_legal_document(kind: String) -> void:
|
||||
|
||||
func _new_form() -> VBoxContainer:
|
||||
var form := VBoxContainer.new()
|
||||
form.add_theme_constant_override("separation", 16)
|
||||
form.add_theme_constant_override("separation", 10)
|
||||
return form
|
||||
|
||||
|
||||
@@ -388,7 +470,7 @@ func _add_field(parent: VBoxContainer, label_text: String, placeholder: String,
|
||||
input.secret = secret
|
||||
input.caret_blink = true
|
||||
input.caret_blink_interval = 0.5
|
||||
input.custom_minimum_size = Vector2(0, 68)
|
||||
input.custom_minimum_size = Vector2(0, 56)
|
||||
input.add_theme_font_size_override("font_size", 17)
|
||||
input.add_theme_font_override("font", Brand.font)
|
||||
parent.add_child(input)
|
||||
@@ -396,19 +478,9 @@ func _add_field(parent: VBoxContainer, label_text: String, placeholder: String,
|
||||
return input
|
||||
|
||||
|
||||
func _add_show_password(parent: VBoxContainer, targets: Array) -> void:
|
||||
var toggle := CheckButton.new()
|
||||
toggle.text = "Show password"
|
||||
toggle.toggled.connect(func(should_reveal: bool):
|
||||
for target in targets:
|
||||
target.secret = not should_reveal
|
||||
)
|
||||
parent.add_child(toggle)
|
||||
|
||||
|
||||
func _add_password_reveal(input: LineEdit) -> void:
|
||||
var reveal := Button.new()
|
||||
password_reveal_button = reveal
|
||||
password_reveal_entries.append({"input": input, "button": reveal})
|
||||
reveal.text = ""
|
||||
reveal.tooltip_text = "Show password"
|
||||
reveal.flat = true
|
||||
@@ -487,6 +559,9 @@ func _update_responsive_layout() -> void:
|
||||
var layout_width := size.x
|
||||
if layout_width <= 0.0:
|
||||
layout_width = get_viewport_rect().size.x
|
||||
var layout_height := size.y
|
||||
if layout_height <= 0.0:
|
||||
layout_height = get_viewport_rect().size.y
|
||||
var compact_desktop := layout_width < 900.0
|
||||
var mobile_web := false
|
||||
if OS.has_feature("web"):
|
||||
@@ -505,7 +580,16 @@ func _update_responsive_layout() -> void:
|
||||
theme_button.custom_minimum_size = Vector2(44, 44)
|
||||
theme_button.position = Vector2(-58, 14)
|
||||
theme_button.add_theme_font_size_override("font_size", 20)
|
||||
auth_panel.custom_minimum_size = Vector2(640, 790) if compact_desktop else Vector2(710, 820)
|
||||
# 1000/1010 comfortably fits every view (login/register/reset/steam)
|
||||
# without the inner ScrollContainer kicking in, on any window tall
|
||||
# enough to hold it - but clamp to whatever height is actually
|
||||
# available so a short window shrinks the panel (and lets the
|
||||
# ScrollContainer take over) instead of the panel overflowing off
|
||||
# the top/bottom of the screen.
|
||||
var available_panel_height := layout_height - 56.0
|
||||
var target_height := 1010.0 if compact_desktop else 1000.0
|
||||
var panel_height := clampf(available_panel_height, 400.0, target_height)
|
||||
auth_panel.custom_minimum_size = Vector2(640 if compact_desktop else 710, panel_height)
|
||||
panel_gutter.add_theme_constant_override("margin_right", 28)
|
||||
_apply_compact_scale(panel_content, 1.0)
|
||||
_apply_theme()
|
||||
@@ -544,7 +628,13 @@ func _apply_theme() -> void:
|
||||
label.add_theme_color_override("font_color", Brand.text_color(dark))
|
||||
for input in fields:
|
||||
_style_auth_field(input, dark)
|
||||
for consent_text in legal_consent_texts:
|
||||
_refresh_legal_consent_text(consent_text, dark)
|
||||
for square in legal_consent_squares:
|
||||
_refresh_legal_consent_square(square)
|
||||
for button in find_children("*", "Button", true, false):
|
||||
if button is CheckBox:
|
||||
continue
|
||||
var typed := button as Button
|
||||
typed.add_theme_font_override("font", Brand.font)
|
||||
typed.add_theme_color_override("font_color", Brand.text_color(dark))
|
||||
@@ -565,8 +655,8 @@ func _apply_theme() -> void:
|
||||
theme_button.add_theme_stylebox_override("normal", theme_normal)
|
||||
theme_button.add_theme_stylebox_override("hover", theme_normal)
|
||||
theme_button.add_theme_color_override("font_color", Brand.AMBER)
|
||||
if password_reveal_button != null:
|
||||
_refresh_password_reveal(password_input, password_reveal_button)
|
||||
for entry in password_reveal_entries:
|
||||
_refresh_password_reveal(entry["input"], entry["button"])
|
||||
subheading.add_theme_color_override("font_color", Brand.muted_color(dark))
|
||||
message_label.add_theme_color_override("font_color", Brand.muted_color(dark))
|
||||
if brand_tagline != null:
|
||||
|
||||
@@ -2824,10 +2824,10 @@ func _build_report_modal() -> void:
|
||||
report_form_content.add_theme_constant_override("separation", 12)
|
||||
modal_body.add_child(report_form_content)
|
||||
|
||||
var category_label := Label.new()
|
||||
category_label.text = "What is the problem?"
|
||||
_set_scaled_label(category_label, 18, Style.CYAN)
|
||||
report_form_content.add_child(category_label)
|
||||
var report_category_label := Label.new()
|
||||
report_category_label.text = "What is the problem?"
|
||||
_set_scaled_label(report_category_label, 18, Style.CYAN)
|
||||
report_form_content.add_child(report_category_label)
|
||||
|
||||
var category_grid := GridContainer.new()
|
||||
category_grid.columns = 2
|
||||
|
||||
@@ -180,6 +180,8 @@
|
||||
letter-spacing: 0;
|
||||
line-height: 1;
|
||||
margin: 12px 0 0;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.wordmark-rana {
|
||||
@@ -207,7 +209,9 @@
|
||||
font-size: clamp(20px, 2.3vw, 28px);
|
||||
font-weight: 430;
|
||||
letter-spacing: 0;
|
||||
line-height: 1.3;
|
||||
margin: 17px 0 clamp(36px, 6vh, 54px);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.progress-row {
|
||||
@@ -239,6 +243,7 @@
|
||||
font-size: 22px;
|
||||
font-variant-numeric: tabular-nums;
|
||||
font-weight: 650;
|
||||
line-height: 1.3;
|
||||
min-width: 60px;
|
||||
}
|
||||
|
||||
@@ -246,8 +251,10 @@
|
||||
color: var(--muted);
|
||||
font-size: 19px;
|
||||
letter-spacing: 0;
|
||||
line-height: 1.3;
|
||||
margin: 24px 0 0;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#status-notice {
|
||||
|
||||
Reference in New Issue
Block a user