Skip to content

Commit b957c99

Browse files
committed
iOS 15 improvements
- Update TagList view to scroll - Fix some previews and some formatting issues - Update version number - Fix some HTMLView issues - Convert UserAvatarLoader to AsyncImage - Migrate to .task where appropriate - Add UA to TagFetcher and make async
1 parent a7dc1f0 commit b957c99

21 files changed

+526
-292
lines changed

claw.xcodeproj/project.pbxproj

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
F6010B9828E90B4E009A759C /* URLRequest+UA.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6010B9728E90B4E009A759C /* URLRequest+UA.swift */; };
11+
F6010B9928EA4AB0009A759C /* URLRequest+UA.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6010B9728E90B4E009A759C /* URLRequest+UA.swift */; };
1012
F608CD1B26BF598E00F98817 /* GenericArrayFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = F608CD1A26BF598E00F98817 /* GenericArrayFetcher.swift */; };
1113
F61CC1BE253676FC00CC7785 /* Font.swift in Sources */ = {isa = PBXBuildFile; fileRef = F61CC1BD253676FC00CC7785 /* Font.swift */; };
1214
F61CC1C4253A876D00CC7785 /* SettingsTextSizeSlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = F61CC1C3253A876D00CC7785 /* SettingsTextSizeSlider.swift */; };
@@ -75,7 +77,6 @@
7577
F6E9EDCC251EE005005E2B1C /* NewestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6E9EDCB251EE005005E2B1C /* NewestView.swift */; };
7678
F6E9EDDB251EE081005E2B1C /* UserFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6E9EDDA251EE081005E2B1C /* UserFetcher.swift */; };
7779
F6E9EDE1251EE0B2005E2B1C /* UserView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6E9EDE0251EE0B2005E2B1C /* UserView.swift */; };
78-
F6E9EDE7251EE0E1005E2B1C /* ImageLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6E9EDE6251EE0E1005E2B1C /* ImageLoader.swift */; };
7980
F6E9EE16251EE548005E2B1C /* SettingsLinkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6E9EE15251EE548005E2B1C /* SettingsLinkView.swift */; };
8081
F6E9EE20251EE5EB005E2B1C /* ZZLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6E9EE1F251EE5EB005E2B1C /* ZZLabel.swift */; };
8182
F6E9EE26251EE675005E2B1C /* HorizontallyAlignedLayoutStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6E9EE25251EE675005E2B1C /* HorizontallyAlignedLayoutStyle.swift */; };
@@ -133,6 +134,7 @@
133134
/* End PBXCopyFilesBuildPhase section */
134135

135136
/* Begin PBXFileReference section */
137+
F6010B9728E90B4E009A759C /* URLRequest+UA.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URLRequest+UA.swift"; sourceTree = "<group>"; };
136138
F608CD1A26BF598E00F98817 /* GenericArrayFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenericArrayFetcher.swift; sourceTree = "<group>"; };
137139
F61CC1BD253676FC00CC7785 /* Font.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Font.swift; sourceTree = "<group>"; };
138140
F61CC1C3253A876D00CC7785 /* SettingsTextSizeSlider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsTextSizeSlider.swift; sourceTree = "<group>"; };
@@ -204,7 +206,6 @@
204206
F6E9EDCB251EE005005E2B1C /* NewestView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = NewestView.swift; path = claw/Stories/Newest/NewestView.swift; sourceTree = SOURCE_ROOT; };
205207
F6E9EDDA251EE081005E2B1C /* UserFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = UserFetcher.swift; path = claw/User/UserFetcher.swift; sourceTree = SOURCE_ROOT; };
206208
F6E9EDE0251EE0B2005E2B1C /* UserView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = UserView.swift; path = claw/User/UserView.swift; sourceTree = SOURCE_ROOT; };
207-
F6E9EDE6251EE0E1005E2B1C /* ImageLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageLoader.swift; sourceTree = "<group>"; };
208209
F6E9EE15251EE548005E2B1C /* SettingsLinkView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SettingsLinkView.swift; path = claw/Settings/SettingsLinkView.swift; sourceTree = SOURCE_ROOT; };
209210
F6E9EE1F251EE5EB005E2B1C /* ZZLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZZLabel.swift; sourceTree = "<group>"; };
210211
F6E9EE25251EE675005E2B1C /* HorizontallyAlignedLayoutStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HorizontallyAlignedLayoutStyle.swift; sourceTree = "<group>"; };
@@ -264,6 +265,7 @@
264265
children = (
265266
F669C99C250EE5AA00B1FF42 /* UIColor.swift */,
266267
F61CC1BD253676FC00CC7785 /* Font.swift */,
268+
F6010B9728E90B4E009A759C /* URLRequest+UA.swift */,
267269
);
268270
path = Extensions;
269271
sourceTree = "<group>";
@@ -398,7 +400,6 @@
398400
F6876706251A82FE003090D2 /* ShareSheet.swift */,
399401
F608CD1A26BF598E00F98817 /* GenericArrayFetcher.swift */,
400402
F6F2013425D5CCD6008BA024 /* ObservableURL.swift */,
401-
F6E9EDE6251EE0E1005E2B1C /* ImageLoader.swift */,
402403
F6F2015925D63C04008BA024 /* ActiveSheet.swift */,
403404
F669C997250ECD6200B1FF42 /* SGNavigationLink.swift */,
404405
F669C933250C5DDE00B1FF42 /* Assets.xcassets */,
@@ -682,6 +683,7 @@
682683
isa = PBXSourcesBuildPhase;
683684
buildActionMask = 2147483647;
684685
files = (
686+
F6010B9928EA4AB0009A759C /* URLRequest+UA.swift in Sources */,
685687
F6291171251057E70065C3E9 /* hottest_widget.swift in Sources */,
686688
F6E9EDC6251EDFB9005E2B1C /* HottestFetcher.swift in Sources */,
687689
F629118C25105A440065C3E9 /* NewestUser.swift in Sources */,
@@ -702,11 +704,11 @@
702704
F6F2015A25D63C04008BA024 /* ActiveSheet.swift in Sources */,
703705
F6E9EDCC251EE005005E2B1C /* NewestView.swift in Sources */,
704706
F6E9EE20251EE5EB005E2B1C /* ZZLabel.swift in Sources */,
705-
F6E9EDE7251EE0E1005E2B1C /* ImageLoader.swift in Sources */,
706707
F656F65E252525DC006FFAFD /* TagStoryView.swift in Sources */,
707708
F656F67C25268709006FFAFD /* SelectedTagsView.swift in Sources */,
708709
F6E9EDB7251EDF98005E2B1C /* NewestStory.swift in Sources */,
709710
F656F65825252563006FFAFD /* TagStoryFetcher.swift in Sources */,
711+
F6010B9828E90B4E009A759C /* URLRequest+UA.swift in Sources */,
710712
F687667325141A27003090D2 /* MailView.swift in Sources */,
711713
F608CD1B26BF598E00F98817 /* GenericArrayFetcher.swift in Sources */,
712714
F629118B25105A3E0065C3E9 /* NewestUser.swift in Sources */,
@@ -814,15 +816,15 @@
814816
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
815817
CODE_SIGN_ENTITLEMENTS = hottest.widgetExtension.entitlements;
816818
CODE_SIGN_STYLE = Automatic;
817-
CURRENT_PROJECT_VERSION = 1;
819+
CURRENT_PROJECT_VERSION = 2;
818820
DEVELOPMENT_TEAM = C6L3992RFB;
819821
INFOPLIST_FILE = hottest.widget/Info.plist;
820822
LD_RUNPATH_SEARCH_PATHS = (
821823
"$(inherited)",
822824
"@executable_path/Frameworks",
823825
"@executable_path/../../Frameworks",
824826
);
825-
MARKETING_VERSION = 1.1.9;
827+
MARKETING_VERSION = 1.2.0;
826828
PRODUCT_BUNDLE_IDENTIFIER = "com.twodayslate.claw.hottest-widget";
827829
PRODUCT_NAME = "$(TARGET_NAME)";
828830
SKIP_INSTALL = YES;
@@ -838,15 +840,15 @@
838840
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
839841
CODE_SIGN_ENTITLEMENTS = hottest.widgetExtension.entitlements;
840842
CODE_SIGN_STYLE = Automatic;
841-
CURRENT_PROJECT_VERSION = 1;
843+
CURRENT_PROJECT_VERSION = 2;
842844
DEVELOPMENT_TEAM = C6L3992RFB;
843845
INFOPLIST_FILE = hottest.widget/Info.plist;
844846
LD_RUNPATH_SEARCH_PATHS = (
845847
"$(inherited)",
846848
"@executable_path/Frameworks",
847849
"@executable_path/../../Frameworks",
848850
);
849-
MARKETING_VERSION = 1.1.9;
851+
MARKETING_VERSION = 1.2.0;
850852
PRODUCT_BUNDLE_IDENTIFIER = "com.twodayslate.claw.hottest-widget";
851853
PRODUCT_NAME = "$(TARGET_NAME)";
852854
SKIP_INSTALL = YES;
@@ -979,7 +981,7 @@
979981
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
980982
CODE_SIGN_ENTITLEMENTS = claw/claw.entitlements;
981983
CODE_SIGN_STYLE = Automatic;
982-
CURRENT_PROJECT_VERSION = 1;
984+
CURRENT_PROJECT_VERSION = 2;
983985
DEVELOPMENT_ASSET_PATHS = "\"claw/Preview Content\"";
984986
DEVELOPMENT_TEAM = C6L3992RFB;
985987
ENABLE_PREVIEWS = YES;
@@ -989,7 +991,7 @@
989991
"$(inherited)",
990992
"@executable_path/Frameworks",
991993
);
992-
MARKETING_VERSION = 1.1.9;
994+
MARKETING_VERSION = 1.2.0;
993995
PRODUCT_BUNDLE_IDENTIFIER = com.twodayslate.claw;
994996
PRODUCT_NAME = "$(TARGET_NAME)";
995997
SUPPORTS_MACCATALYST = NO;
@@ -1007,7 +1009,7 @@
10071009
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
10081010
CODE_SIGN_ENTITLEMENTS = claw/claw.entitlements;
10091011
CODE_SIGN_STYLE = Automatic;
1010-
CURRENT_PROJECT_VERSION = 1;
1012+
CURRENT_PROJECT_VERSION = 2;
10111013
DEVELOPMENT_ASSET_PATHS = "\"claw/Preview Content\"";
10121014
DEVELOPMENT_TEAM = C6L3992RFB;
10131015
ENABLE_PREVIEWS = YES;
@@ -1017,7 +1019,7 @@
10171019
"$(inherited)",
10181020
"@executable_path/Frameworks",
10191021
);
1020-
MARKETING_VERSION = 1.1.9;
1022+
MARKETING_VERSION = 1.2.0;
10211023
PRODUCT_BUNDLE_IDENTIFIER = com.twodayslate.claw;
10221024
PRODUCT_NAME = "$(TARGET_NAME)";
10231025
SUPPORTS_MACCATALYST = NO;
@@ -1117,7 +1119,7 @@
11171119
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
11181120
CODE_SIGN_ENTITLEMENTS = "opener-action/opener-action.entitlements";
11191121
CODE_SIGN_STYLE = Automatic;
1120-
CURRENT_PROJECT_VERSION = 1;
1122+
CURRENT_PROJECT_VERSION = 2;
11211123
DEVELOPMENT_TEAM = C6L3992RFB;
11221124
INFOPLIST_FILE = "opener-action/Info.plist";
11231125
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
@@ -1126,7 +1128,7 @@
11261128
"@executable_path/Frameworks",
11271129
"@executable_path/../../Frameworks",
11281130
);
1129-
MARKETING_VERSION = 1.1.9;
1131+
MARKETING_VERSION = 1.2.0;
11301132
PRODUCT_BUNDLE_IDENTIFIER = "com.twodayslate.claw.opener-action";
11311133
PRODUCT_NAME = "$(TARGET_NAME)";
11321134
SKIP_INSTALL = YES;
@@ -1141,7 +1143,7 @@
11411143
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
11421144
CODE_SIGN_ENTITLEMENTS = "opener-action/opener-action.entitlements";
11431145
CODE_SIGN_STYLE = Automatic;
1144-
CURRENT_PROJECT_VERSION = 1;
1146+
CURRENT_PROJECT_VERSION = 2;
11451147
DEVELOPMENT_TEAM = C6L3992RFB;
11461148
INFOPLIST_FILE = "opener-action/Info.plist";
11471149
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
@@ -1150,7 +1152,7 @@
11501152
"@executable_path/Frameworks",
11511153
"@executable_path/../../Frameworks",
11521154
);
1153-
MARKETING_VERSION = 1.1.9;
1155+
MARKETING_VERSION = 1.2.0;
11541156
PRODUCT_BUNDLE_IDENTIFIER = "com.twodayslate.claw.opener-action";
11551157
PRODUCT_NAME = "$(TARGET_NAME)";
11561158
SKIP_INSTALL = YES;

claw/CommentHierarchy.swift

Lines changed: 61 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,19 @@ import SwiftUI
33
// From https://fivestars.blog/code/swiftui-hierarchy-list.html
44

55
public struct HierarchyList<RowContent, HeaderContent>: View where RowContent: View, HeaderContent: View {
6-
6+
77
let data: [CommentStructure]
88
let header: (CommentStructure) -> HeaderContent
99
let rowContent: (CommentStructure) -> RowContent
1010
@State var sharedComment: Comment?
11-
11+
1212
public var body: some View {
13-
// this should be a LazyVStack but there is a bug
14-
// https://developer.apple.com/forums/thread/658199
15-
VStack(alignment: .leading, spacing: 0) {
13+
// this should be a LazyVStack but there is a bug
14+
// https://developer.apple.com/forums/thread/658199
15+
LazyVStack(alignment: .leading, spacing: 0) {
1616
RecursiveView(data: data, header: header, rowContent: rowContent, indentLevel: 0, sharedComment: $sharedComment)
17-
}.sheet(item: $sharedComment, content: { item in
17+
}
18+
.sheet(item: $sharedComment, content: { item in
1819
ShareSheet(activityItems: [URL(string: item.short_id_url)!])
1920
})
2021
}
@@ -27,12 +28,12 @@ private struct RecursiveView<RowContent, HeaderContent>: View where RowContent:
2728
let indentLevel: Int
2829

2930
@Binding var sharedComment: Comment?
30-
31-
var body: some View {
32-
ForEach(data) { child in
33-
HierarchyCommentView(header: header, rowContent: rowContent, indentLevel: indentLevel, child: child, sharedComment: $sharedComment, last: child == data.last!)
31+
32+
var body: some View {
33+
ForEach(data) { child in
34+
HierarchyCommentView(header: header, rowContent: rowContent, indentLevel: indentLevel, child: child, sharedComment: $sharedComment, last: child == data.last!)
35+
}
3436
}
35-
}
3637
}
3738

3839
struct HierarchyCommentView<RowContent, HeaderContent>: View where RowContent: View, HeaderContent: View {
@@ -51,20 +52,20 @@ struct HierarchyCommentView<RowContent, HeaderContent>: View where RowContent: V
5152

5253
var commentColor: Color {
5354
switch(indentLevel % 7) {
54-
case 0:
55-
return Color.blue.opacity(0.5)
56-
case 1:
57-
return Color.green.opacity(0.5)
58-
case 2:
59-
return Color.orange.opacity(0.5)
60-
case 3:
61-
return Color.pink.opacity(0.5)
62-
case 4:
63-
return Color.red.opacity(0.5)
64-
case 5:
65-
return Color.yellow.opacity(0.5)
66-
default:
67-
return Color.purple.opacity(0.5)
55+
case 0:
56+
return Color.blue.opacity(0.5)
57+
case 1:
58+
return Color.green.opacity(0.5)
59+
case 2:
60+
return Color.orange.opacity(0.5)
61+
case 3:
62+
return Color.pink.opacity(0.5)
63+
case 4:
64+
return Color.red.opacity(0.5)
65+
case 5:
66+
return Color.yellow.opacity(0.5)
67+
default:
68+
return Color.purple.opacity(0.5)
6869
}
6970
}
7071

@@ -77,7 +78,7 @@ struct HierarchyCommentView<RowContent, HeaderContent>: View where RowContent: V
7778
DisclosureGroup(
7879
isExpanded: $isExpanded,
7980
content: {
80-
VStack(alignment: .leading, spacing: 0) {
81+
LazyVStack(alignment: .leading, spacing: 0) {
8182
rowContent(child).padding([.leading])
8283
if let subChildren = child.children {
8384
Divider().padding([.top, .leading])
@@ -87,46 +88,49 @@ struct HierarchyCommentView<RowContent, HeaderContent>: View where RowContent: V
8788
},
8889
label: {
8990
header(child).padding([.leading])
90-
}).padding([.top], 6.0).padding(indentLevel > 0 ? [.trailing] : [], 4.0)
91+
}
92+
)
93+
.padding([.top], 6.0)
94+
.padding(indentLevel > 0 ? [.trailing] : [], 4.0)
9195
if !last {
9296
Divider().padding([.horizontal])
9397
}
9498
}.padding(indentLevel == 0 ? [.trailing] : []).background(backgroundColorState.edgesIgnoringSafeArea(.all)).contextMenu(menuItems: {
95-
// for some reason the share sheet won't display if the comment isn't
96-
//if indentLevel == 0 {
97-
Button(action: {
98-
sharedComment = child.comment
99-
}, label: {
100-
Label("Share", systemImage: "square.and.arrow.up")
101-
})
102-
//}
103-
Button(action: {
104-
withAnimation(.easeIn) {
105-
isExpanded.toggle()
106-
}
107-
}, label: {Label(isExpanded ? "Collapse" : "Expand", systemImage: "rectangle.expand.vertical")})
108-
}).onTapGesture(count: /*@START_MENU_TOKEN@*/1/*@END_MENU_TOKEN@*/, perform: {
99+
// for some reason the share sheet won't display if the comment isn't
100+
//if indentLevel == 0 {
101+
Button(action: {
102+
sharedComment = child.comment
103+
}, label: {
104+
Label("Share", systemImage: "square.and.arrow.up")
105+
})
106+
//}
107+
Button(action: {
109108
withAnimation(.easeIn) {
110-
backgroundColorState = Color(UIColor.systemGray4)
111-
withAnimation(.easeOut) {
112-
backgroundColorState = Color(UIColor.systemBackground)
113-
}
114109
isExpanded.toggle()
115110
}
116-
})
111+
}, label: {Label(isExpanded ? "Collapse" : "Expand", systemImage: "rectangle.expand.vertical")})
112+
}).onTapGesture(count: /*@START_MENU_TOKEN@*/1/*@END_MENU_TOKEN@*/, perform: {
113+
withAnimation(.easeIn) {
114+
backgroundColorState = Color(UIColor.systemGray4)
115+
withAnimation(.easeOut) {
116+
backgroundColorState = Color(UIColor.systemBackground)
117+
}
118+
isExpanded.toggle()
119+
}
120+
})
117121
}
118122
}
119123

120124
struct FSDisclosureGroup<Label, Content>: View where Label: View, Content: View {
121-
@State var isExpanded: Bool = true
122-
var content: () -> Content
123-
var label: () -> Label
124-
125-
var body: some View {
126-
DisclosureGroup(
127-
isExpanded: $isExpanded,
128-
content: content,
129-
label: label
130-
)
131-
}
125+
@State var isExpanded: Bool = true
126+
var content: () -> Content
127+
var label: () -> Label
128+
129+
var body: some View {
130+
DisclosureGroup(
131+
isExpanded: $isExpanded,
132+
content: content,
133+
label: label
134+
)
135+
}
132136
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//
2+
// URLRequest+UA.swift
3+
// claw
4+
//
5+
// Created by Zachary Gorak on 10/1/22.
6+
//
7+
8+
import Foundation
9+
import UIKit
10+
11+
import MachO
12+
13+
extension UIDevice {
14+
var modelIdentifier: String {
15+
if let simulatorModelIdentifier = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] { return simulatorModelIdentifier }
16+
var sysinfo = utsname()
17+
uname(&sysinfo) // ignore return value
18+
return String(bytes: Data(bytes: &sysinfo.machine, count: Int(_SYS_NAMELEN)), encoding: .ascii)!.trimmingCharacters(in: .controlCharacters)
19+
}
20+
}
21+
22+
public extension URLRequest {
23+
mutating func setUserAgent() {
24+
// per @pushcx
25+
// $APP_NAME/$VERSION ($ARCH; $OS; +https://contact.link/for/the/app)
26+
let app_name = "claw"
27+
let version = (Bundle.main.infoDictionary?["CFBundleShortVersionString"] as! String)
28+
let help_url = "https://zac.gorak.us/ios"
29+
30+
let ua = "\(app_name)/\(version) (\(UIDevice.current.modelIdentifier); \(UIDevice.current.systemName) \(UIDevice.current.systemVersion); +\(help_url))"
31+
32+
self.setValue(ua, forHTTPHeaderField: "User-Agent")
33+
}
34+
}

0 commit comments

Comments
 (0)