Skip to content

Commit e5cc29a

Browse files
Rahkeentrevor-e
andauthored
Settings Screen Design (#306)
Adding the New Settings Screen Components: - Login Row - Settings Row for Links --------- Co-authored-by: Trevor Elkins <trevor@emergetools.com>
1 parent 99d31cd commit e5cc29a

File tree

6 files changed

+227
-20
lines changed

6 files changed

+227
-20
lines changed

ios/HackerNews.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@
4949
EC882BB22D23A8A70065FEC0 /* LoginScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC882BB12D23A8A70065FEC0 /* LoginScreen.swift */; };
5050
ECC0BC8C2D39CDCB00ABB263 /* CommentComposer.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECC0BC8B2D39CDCB00ABB263 /* CommentComposer.swift */; };
5151
ECC0BC8F2D3A34A600ABB263 /* Bookmarks.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECC0BC8E2D3A34A600ABB263 /* Bookmarks.swift */; };
52+
ECC0BC912D3B1FEC00ABB263 /* LoginRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECC0BC902D3B1FEC00ABB263 /* LoginRow.swift */; };
53+
ECC0BC932D3B268C00ABB263 /* SettingsRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECC0BC922D3B268C00ABB263 /* SettingsRow.swift */; };
5254
ECCE8F262D03815300349733 /* Pager.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECCE8F252D03815300349733 /* Pager.swift */; };
5355
ECE608562D338B3E008B1618 /* ibm_plex_sans_medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = ECE608532D338B3E008B1618 /* ibm_plex_sans_medium.ttf */; };
5456
ECE608572D338B3E008B1618 /* ibm_plex_sans_bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = ECE608522D338B3E008B1618 /* ibm_plex_sans_bold.ttf */; };
@@ -155,6 +157,8 @@
155157
EC882BB12D23A8A70065FEC0 /* LoginScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginScreen.swift; sourceTree = "<group>"; };
156158
ECC0BC8B2D39CDCB00ABB263 /* CommentComposer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommentComposer.swift; sourceTree = "<group>"; };
157159
ECC0BC8E2D3A34A600ABB263 /* Bookmarks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bookmarks.swift; sourceTree = "<group>"; };
160+
ECC0BC902D3B1FEC00ABB263 /* LoginRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginRow.swift; sourceTree = "<group>"; };
161+
ECC0BC922D3B268C00ABB263 /* SettingsRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsRow.swift; sourceTree = "<group>"; };
158162
ECCE8F252D03815300349733 /* Pager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Pager.swift; sourceTree = "<group>"; };
159163
ECE608522D338B3E008B1618 /* ibm_plex_sans_bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = ibm_plex_sans_bold.ttf; sourceTree = "<group>"; };
160164
ECE608532D338B3E008B1618 /* ibm_plex_sans_medium.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = ibm_plex_sans_medium.ttf; sourceTree = "<group>"; };
@@ -206,6 +210,8 @@
206210
EC072CA92CEF02A500D00B8D /* StoryRowV2.swift */,
207211
EC0B1C742D1A34110000C3AC /* CommentsHeader.swift */,
208212
ECC0BC8B2D39CDCB00ABB263 /* CommentComposer.swift */,
213+
ECC0BC902D3B1FEC00ABB263 /* LoginRow.swift */,
214+
ECC0BC922D3B268C00ABB263 /* SettingsRow.swift */,
209215
);
210216
path = Components;
211217
sourceTree = "<group>";
@@ -628,12 +634,14 @@
628634
A427057D2A4293B10057E439 /* HNApp.swift in Sources */,
629635
EC70E1612D1DD82B00582023 /* HNWebClient.swift in Sources */,
630636
A434C2E02A8E75960002F488 /* WebView.swift in Sources */,
637+
ECC0BC932D3B268C00ABB263 /* SettingsRow.swift in Sources */,
631638
A49933942AA28B5900DED8B1 /* CommentsViewModel.swift in Sources */,
632639
A47309B62AA7D1F600201376 /* CommentRow.swift in Sources */,
633640
A49933952AA28B6500DED8B1 /* CommentsScreen.swift in Sources */,
634641
A42705A72A42949D0057E439 /* AppViewModel.swift in Sources */,
635642
ECC0BC8F2D3A34A600ABB263 /* Bookmarks.swift in Sources */,
636643
A42705AD2A429D2E0057E439 /* HNApi.swift in Sources */,
644+
ECC0BC912D3B1FEC00ABB263 /* LoginRow.swift in Sources */,
637645
ECC0BC8C2D39CDCB00ABB263 /* CommentComposer.swift in Sources */,
638646
A423B0682BAE05FB00267DDB /* NetworkDebugger.swift in Sources */,
639647
ECCE8F262D03815300349733 /* Pager.swift in Sources */,
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//
2+
// LoginRow.swift
3+
// HackerNews
4+
//
5+
// Created by Rikin Marfatia on 1/17/25.
6+
//
7+
8+
import Foundation
9+
import SwiftUI
10+
11+
struct LoginRow: View {
12+
let loggedIn: Bool
13+
let tapped: () -> Void
14+
15+
var body: some View {
16+
HStack(alignment: .center, spacing: 8) {
17+
Circle()
18+
.fill(glowColor())
19+
.frame(
20+
width: 8
21+
)
22+
Text(loginText())
23+
.font(.custom("IBMPlexMono-Bold", size: 16))
24+
Spacer()
25+
Image(systemName: "message.fill")
26+
.font(.system(size: 12))
27+
.foregroundStyle(messageColor())
28+
Image(systemName: "arrow.up")
29+
.font(.system(size: 12))
30+
.foregroundStyle(likeColor())
31+
}
32+
.frame(maxWidth: .infinity, alignment: .leading)
33+
.padding(16)
34+
.background(.surface)
35+
.clipShape(.rect(cornerRadius: 16))
36+
.onTapGesture {
37+
tapped()
38+
}
39+
}
40+
41+
func loginText() -> String {
42+
return loggedIn ? "Logout" : "Login"
43+
}
44+
45+
func glowColor() -> Color {
46+
return loggedIn ? .green : .onBackground.opacity(0.2)
47+
}
48+
49+
func messageColor() -> Color {
50+
return loggedIn ? .blue : .onBackground.opacity(0.2)
51+
}
52+
53+
func likeColor() -> Color {
54+
return loggedIn ? .green : .onBackground.opacity(0.2)
55+
}
56+
}
57+
58+
#Preview {
59+
LoginRow(loggedIn: true, tapped: {})
60+
}
61+
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//
2+
// SettingsRow.swift
3+
// HackerNews
4+
//
5+
// Created by Rikin Marfatia on 1/17/25.
6+
//
7+
8+
import Foundation
9+
import SwiftUI
10+
11+
struct SettingsRow<Leading: View, Trailing: View>: View {
12+
let text: String
13+
@ViewBuilder let leadingIcon: () -> Leading
14+
@ViewBuilder let trailingIcon: () -> Trailing
15+
let action: () -> Void
16+
17+
var body: some View {
18+
HStack(alignment: .center, spacing: 8) {
19+
leadingIcon()
20+
Text(text)
21+
.font(.custom("IBMPlexMono-Bold", size: 16))
22+
Spacer()
23+
trailingIcon()
24+
}
25+
.frame(maxWidth: .infinity, alignment: .leading)
26+
.padding(16)
27+
.background(.surface)
28+
.clipShape(.rect(cornerRadius: 16))
29+
.onTapGesture {
30+
action()
31+
}
32+
}
33+
}
34+
35+
#Preview {
36+
SettingsRow(
37+
text: "Follow Emerge",
38+
leadingIcon: {
39+
Image(systemName: "person.crop.circle")
40+
.font(.system(size: 12))
41+
},
42+
trailingIcon: {
43+
Image(systemName: "arrow.up.right")
44+
.font(.system(size: 12))
45+
},
46+
action: {}
47+
)
48+
}

ios/HackerNews/Models/AppViewModel.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,10 @@ class AppViewModel: ObservableObject {
225225
}
226226
}
227227

228+
func openLink(url: URL) {
229+
navigationPath.append(AppNavigation.webLink(url: url, title: ""))
230+
}
231+
228232
func toggleBookmark(_ item: StoryContent) {
229233
feedState.stories = feedState.stories.map { current in
230234
if case .loaded(let content) = current {
@@ -247,7 +251,7 @@ class AppViewModel: ObservableObject {
247251
}
248252
}
249253

250-
func loginTapped(username: String, password: String) async {
254+
func loginSubmit(username: String, password: String) async {
251255
let status = await webClient.login(acct: username, pw: password )
252256
print("Login Status: \(status)")
253257
switch status {

ios/HackerNews/Screens/LoginScreen.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ struct LoginScreen: View {
2525
var body: some View {
2626
VStack(spacing: 8) {
2727

28-
Image(systemName: "bolt.horizontal.circle.fill")
28+
Image(systemName: "person.crop.circle.fill")
2929
.foregroundStyle(HNColors.orange)
3030
.font(.system(size: 64))
3131

@@ -45,14 +45,15 @@ struct LoginScreen: View {
4545
Button(
4646
action: {
4747
Task {
48-
await model.loginTapped(
48+
await model.loginSubmit(
4949
username: loginState.username,
5050
password: loginState.password
5151
)
5252
}
5353
},
5454
label: {
55-
Text("Login")
55+
Text("Submit")
56+
.font(.custom("IBMPlexMono-Bold", size: 16))
5657
.frame(maxWidth: .infinity)
5758
}
5859
)
@@ -61,7 +62,7 @@ struct LoginScreen: View {
6162
}
6263
.frame(maxWidth: .infinity, maxHeight: .infinity)
6364
.padding(32)
64-
.background(HNColors.background)
65+
.background(Color.background)
6566
}
6667
}
6768

ios/HackerNews/Screens/SettingsScreen.swift

Lines changed: 100 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,110 @@ struct SettingsScreen: View {
1212
@ObservedObject var model: AppViewModel
1313

1414
var body: some View {
15-
List {
16-
HStack {
17-
Circle()
18-
.fill(model.authState == AuthState.loggedIn ? Color.green : Color.red)
19-
.frame(width: 6)
20-
Text(model.authState == AuthState.loggedIn ? "Logout" : "Login")
15+
ScrollView {
16+
LazyVStack(spacing: 8) {
2117
Spacer()
22-
Image(systemName: "message.fill")
23-
.font(.system(size: 12))
24-
.foregroundStyle(model.authState == AuthState.loggedIn ? Color.blue : Color.gray)
25-
Image(systemName: "arrow.up")
26-
.font(.system(size: 12))
27-
.foregroundStyle(model.authState == AuthState.loggedIn ? Color.green : Color.gray)
18+
.frame(height: 68)
19+
VStack(alignment: .leading, spacing: 4) {
20+
Text("Profile")
21+
.font(.custom("IBMPlexSans-Medium", size: 12))
22+
LoginRow(loggedIn: model.authState == AuthState.loggedIn) {
23+
model.gotoLogin()
24+
}
25+
}
26+
27+
VStack(alignment: .leading, spacing: 4) {
28+
Text("About")
29+
.font(.custom("IBMPlexSans-Medium", size: 12))
30+
SettingsRow(
31+
text: "Follow Emerge",
32+
leadingIcon: {
33+
Image(systemName: "bird.fill")
34+
.font(.system(size: 12))
35+
.foregroundStyle(.blue)
36+
},
37+
trailingIcon: {
38+
Image(systemName: "arrow.up.right")
39+
.font(.system(size: 12))
40+
.foregroundStyle(.onBackground)
41+
42+
},
43+
action: {
44+
model.openLink(url: URL(string: "https://www.twitter.com/emergetools")!)
45+
46+
}
47+
)
48+
49+
SettingsRow(
50+
text: "Follow Supergooey",
51+
leadingIcon: {
52+
Image(systemName: "bird.fill")
53+
.font(.system(size: 12))
54+
.foregroundStyle(.blue)
55+
},
56+
trailingIcon: {
57+
Image(systemName: "arrow.up.right")
58+
.font(.system(size: 12))
59+
.foregroundStyle(.onBackground)
60+
61+
},
62+
action: {
63+
model.openLink(url: URL(string: "https://www.twitter.com/heyrikin")!)
64+
}
65+
)
66+
67+
SettingsRow(
68+
text: "Send Feedback",
69+
leadingIcon: {
70+
Image(systemName: "exclamationmark.triangle.fill")
71+
.font(.system(size: 12))
72+
.foregroundStyle(.yellow)
73+
},
74+
trailingIcon: {
75+
Image(systemName: "arrow.up.right")
76+
.font(.system(size: 12))
77+
.foregroundStyle(.onBackground)
78+
79+
},
80+
action: {
81+
model.openLink(url: URL(string: "https://forms.gle/YYno9sUehE5xuKAq9")!)
82+
}
83+
)
84+
85+
SettingsRow(
86+
text: "Privacy Policy",
87+
leadingIcon: {
88+
Image(systemName: "lock.fill")
89+
.font(.system(size: 12))
90+
.foregroundStyle(.hnRed)
91+
},
92+
trailingIcon: {
93+
Image(systemName: "arrow.up.right")
94+
.font(.system(size: 12))
95+
.foregroundStyle(.onBackground)
96+
97+
},
98+
action: {
99+
model.openLink(url: URL(string: "https://www.emergetools.com/HackerNewsPrivacyPolicy.html")! )
100+
}
101+
)
102+
}
28103
}
29-
.onTapGesture {
30-
model.gotoLogin()
104+
.padding(.horizontal, 8)
105+
}
106+
.overlay {
107+
ZStack(alignment: .leading) {
108+
Color.clear
109+
.background(.ultraThinMaterial)
110+
.containerShape(.rect(cornerRadius: 24, style: .continuous))
111+
112+
Text("Settings")
113+
.font(.custom("IBMPlexMono-Bold", size: 24))
114+
.padding(.horizontal, 16)
31115
}
116+
.frame(height: 60)
117+
.frame(maxHeight: .infinity, alignment: .top)
32118
}
33-
.navigationTitle("Settings")
34119
}
35120
}
36121

0 commit comments

Comments
 (0)