Skip to content

Commit a7dc1f0

Browse files
committed
Update for iOS 15
- Support some links
1 parent d5db27c commit a7dc1f0

File tree

7 files changed

+160
-87
lines changed

7 files changed

+160
-87
lines changed

claw.xcodeproj/project.pbxproj

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -822,7 +822,7 @@
822822
"@executable_path/Frameworks",
823823
"@executable_path/../../Frameworks",
824824
);
825-
MARKETING_VERSION = 1.1.8;
825+
MARKETING_VERSION = 1.1.9;
826826
PRODUCT_BUNDLE_IDENTIFIER = "com.twodayslate.claw.hottest-widget";
827827
PRODUCT_NAME = "$(TARGET_NAME)";
828828
SKIP_INSTALL = YES;
@@ -846,7 +846,7 @@
846846
"@executable_path/Frameworks",
847847
"@executable_path/../../Frameworks",
848848
);
849-
MARKETING_VERSION = 1.1.8;
849+
MARKETING_VERSION = 1.1.9;
850850
PRODUCT_BUNDLE_IDENTIFIER = "com.twodayslate.claw.hottest-widget";
851851
PRODUCT_NAME = "$(TARGET_NAME)";
852852
SKIP_INSTALL = YES;
@@ -906,7 +906,7 @@
906906
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
907907
GCC_WARN_UNUSED_FUNCTION = YES;
908908
GCC_WARN_UNUSED_VARIABLE = YES;
909-
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
909+
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
910910
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
911911
MTL_FAST_MATH = YES;
912912
ONLY_ACTIVE_ARCH = YES;
@@ -961,7 +961,7 @@
961961
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
962962
GCC_WARN_UNUSED_FUNCTION = YES;
963963
GCC_WARN_UNUSED_VARIABLE = YES;
964-
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
964+
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
965965
MTL_ENABLE_DEBUG_INFO = NO;
966966
MTL_FAST_MATH = YES;
967967
SDKROOT = iphoneos;
@@ -984,12 +984,12 @@
984984
DEVELOPMENT_TEAM = C6L3992RFB;
985985
ENABLE_PREVIEWS = YES;
986986
INFOPLIST_FILE = claw/Info.plist;
987-
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
987+
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
988988
LD_RUNPATH_SEARCH_PATHS = (
989989
"$(inherited)",
990990
"@executable_path/Frameworks",
991991
);
992-
MARKETING_VERSION = 1.1.8;
992+
MARKETING_VERSION = 1.1.9;
993993
PRODUCT_BUNDLE_IDENTIFIER = com.twodayslate.claw;
994994
PRODUCT_NAME = "$(TARGET_NAME)";
995995
SUPPORTS_MACCATALYST = NO;
@@ -1012,12 +1012,12 @@
10121012
DEVELOPMENT_TEAM = C6L3992RFB;
10131013
ENABLE_PREVIEWS = YES;
10141014
INFOPLIST_FILE = claw/Info.plist;
1015-
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
1015+
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
10161016
LD_RUNPATH_SEARCH_PATHS = (
10171017
"$(inherited)",
10181018
"@executable_path/Frameworks",
10191019
);
1020-
MARKETING_VERSION = 1.1.8;
1020+
MARKETING_VERSION = 1.1.9;
10211021
PRODUCT_BUNDLE_IDENTIFIER = com.twodayslate.claw;
10221022
PRODUCT_NAME = "$(TARGET_NAME)";
10231023
SUPPORTS_MACCATALYST = NO;
@@ -1126,7 +1126,7 @@
11261126
"@executable_path/Frameworks",
11271127
"@executable_path/../../Frameworks",
11281128
);
1129-
MARKETING_VERSION = 1.1.8;
1129+
MARKETING_VERSION = 1.1.9;
11301130
PRODUCT_BUNDLE_IDENTIFIER = "com.twodayslate.claw.opener-action";
11311131
PRODUCT_NAME = "$(TARGET_NAME)";
11321132
SKIP_INSTALL = YES;
@@ -1150,7 +1150,7 @@
11501150
"@executable_path/Frameworks",
11511151
"@executable_path/../../Frameworks",
11521152
);
1153-
MARKETING_VERSION = 1.1.8;
1153+
MARKETING_VERSION = 1.1.9;
11541154
PRODUCT_BUNDLE_IDENTIFIER = "com.twodayslate.claw.opener-action";
11551155
PRODUCT_NAME = "$(TARGET_NAME)";
11561156
SKIP_INSTALL = YES;
@@ -1224,15 +1224,15 @@
12241224
repositoryURL = "https://github.com/scinfu/SwiftSoup.git";
12251225
requirement = {
12261226
kind = upToNextMajorVersion;
1227-
minimumVersion = 2.3.2;
1227+
minimumVersion = 2.4.3;
12281228
};
12291229
};
12301230
F6F2012225D5C130008BA024 /* XCRemoteSwiftPackageReference "BetterSafariView" */ = {
12311231
isa = XCRemoteSwiftPackageReference;
12321232
repositoryURL = "https://github.com/stleamist/BetterSafariView.git";
12331233
requirement = {
12341234
kind = upToNextMajorVersion;
1235-
minimumVersion = 2.3.1;
1235+
minimumVersion = 2.4.0;
12361236
};
12371237
};
12381238
/* End XCRemoteSwiftPackageReference section */

claw.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 20 additions & 22 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

claw/ContentView.swift

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,13 @@ struct ContentView: View {
171171
.environmentObject(settings)
172172
.environmentObject(self.observableSheet)
173173
.environment(\.managedObjectContext, viewContext)
174+
.environment(\.openURL, OpenURLAction { url in
175+
if settings.browser == .inAppSafari {
176+
urlToOpen.url = url
177+
return .handled
178+
}
179+
return .systemAction
180+
})
174181
case .user(let username):
175182
EZPanel{
176183
UserView(username).id(username)
@@ -179,6 +186,13 @@ struct ContentView: View {
179186
.environmentObject(settings)
180187
.environmentObject(self.observableSheet)
181188
.environment(\.managedObjectContext, viewContext)
189+
.environment(\.openURL, OpenURLAction { url in
190+
if settings.browser == .inAppSafari {
191+
urlToOpen.url = url
192+
return .handled
193+
}
194+
return .systemAction
195+
})
182196
case .url(let url):
183197
EZPanel {
184198
VStack {
@@ -190,6 +204,13 @@ struct ContentView: View {
190204
.environmentObject(settings)
191205
.environmentObject(self.observableSheet)
192206
.environment(\.managedObjectContext, viewContext)
207+
.environment(\.openURL, OpenURLAction { url in
208+
if settings.browser == .inAppSafari {
209+
urlToOpen.url = url
210+
return .handled
211+
}
212+
return .systemAction
213+
})
193214
case .share(let url):
194215
ShareSheet(activityItems: [url])
195216
default:
@@ -200,6 +221,13 @@ struct ContentView: View {
200221
.environment(\.managedObjectContext, viewContext)
201222
.environmentObject(self.observableSheet)
202223
.environmentObject(urlToOpen)
224+
.environment(\.openURL, OpenURLAction { url in
225+
if settings.browser == .inAppSafari {
226+
urlToOpen.url = url
227+
return .handled
228+
}
229+
return .systemAction
230+
})
203231
}
204232
})
205233
.environmentObject(settings)
@@ -208,6 +236,13 @@ struct ContentView: View {
208236
.environmentObject(urlToOpen)
209237
.accentColor(settings.accentColor)
210238
.font(Font(.body, sizeModifier: CGFloat(settings.textSizeModifier)))
239+
.environment(\.openURL, OpenURLAction { url in
240+
if settings.browser == .inAppSafari {
241+
urlToOpen.url = url
242+
return .handled
243+
}
244+
return .systemAction
245+
})
211246
}
212247
}
213248

claw/HTMLView.swift

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import SwiftUI
99
import SwiftSoup
1010

11-
1211
// inspired by
1312
// * https://github.com/lukasmoellerch/SwiftUIFormattedText
1413
// * https://github.com/Lambdo-Labs/MDText
@@ -66,8 +65,21 @@ struct NodesView: View {
6665
}
6766
} else if let element = n as? Element {
6867
if element.tagName() == "a" {
69-
let link: Text = getText(from:element).foregroundColor(.accentColor).underline()
70-
combined = combined + link
68+
// Support simple URLs via Apple's markdown parser
69+
if element.hasAttr("href"),
70+
let attr = try? element.attr("href"),
71+
let url = URL(string: attr),
72+
let html = try? element.html(),
73+
let text = try? element.text(),
74+
html == text {
75+
let link: Text = Text(.init("[\(text)](\(url.absoluteString))"))
76+
.foregroundColor(.accentColor)
77+
.underline()
78+
combined = combined + link
79+
} else {
80+
let link: Text = getText(from:element).foregroundColor(.accentColor).underline()
81+
combined = combined + link
82+
}
7183
hasAddedText = true
7284
} else if element.tagName() == "strong" {
7385
combined = combined + getText(from:element).bold()
@@ -259,7 +271,7 @@ struct HTMLView_Previews: PreviewProvider {
259271
}
260272
ScrollView {
261273
HTMLView(html: """
262-
<p>You might have heard of <a href="https://github.com/mawww/kakoune" rel="ugc">kakoune</a> and how it’s a bit like vim, except that verb and object are reversed. One interesting and rarely-mentioned consequence is that you can do manipulation that is very close to what is described in the <a href="http://doc.cat-v.org/bell_labs/structural_regexps/se.pdf" rel="ugc">structural regexp</a> document.</p>
274+
<p>You might have heard of <a href="https://github.com/mawww/kakoune" rel="ugc">kakoune</a> and how it’s a bit like vim, except that verb and <a href="https://google.com"><em>obj</em><code>e</code><strike>c</strike><del>t</del></a> are reversed. One interesting and rarely-mentioned <a href="#"><em>c</em><strong>o</strong>nsequence</a> is that you can do <a href="#">m<strike>an</strike>ipulation</a> that is very close to what is described in the <a href="http://doc.cat-v.org/bell_labs/structural_regexps/se.pdf" rel="ugc">structural regexp</a> document. <a href="#"><strong>Bold and <em>Italic</em></strong></a></p>
263275
<p>Consider this hypothetical structural regex <code>y/".*"/ y/’.*’/ x/[a-zA-Z0-9]+/ g/n/ v/../ c/num/</code> that they describe. Put simply, it is supposed to change each variable named <code>n</code> into <code>num</code> while being careful not to do so in strings (in <code>\n</code> for example).</p>
264276
<p>This exact processing can be done interactively in kakoune with the following key sequence: <code>S".*"&lt;ret&gt;S'.*'&lt;ret&gt;s[a-z-A-Z0-9]+&lt;ret&gt;&lt;a-k&gt;n&lt;ret&gt;&lt;a-K&gt;..&lt;ret&gt;cnum&lt;esc&gt;</code></p>
265277
<p>It looks cryptic, but it’s a sequence of the following operations:</p>
@@ -274,7 +286,7 @@ struct HTMLView_Previews: PreviewProvider {
274286
<p>And the nice thing about being interactive is that you don’t have to think up the entire command at once. You can simply do it progressively and see that your selections are narrowing down to exactly what you want to change.</p>
275287
""")
276288
}
277-
" ".join([Text("Hello"), Text("link").foregroundColor(.blue), Text("world!")])
289+
" ".join([Text("Hello"), Text("link").foregroundColor(.blue), Text("world!"), Text("**[bold](https://site.com)**")])
278290
}.previewLayout(.sizeThatFits).environmentObject(Settings(context: PersistenceController.preview.container.viewContext))
279291
}
280292
}

claw/Tags/SelectedTagsView.swift

Lines changed: 55 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -82,45 +82,7 @@ struct SelectTagsView: View {
8282
var body: some View {
8383
ScrollViewReader { scrollReader in
8484
ZStack(alignment: .topTrailing) {
85-
List {
86-
EmptyView().id("top")
87-
ForEach(alphabet, id: \.self) { letter in
88-
let filtered = fetcher.tags.filter({$0.tag.prefix(1).uppercased() == letter && (self.searchBar.text.isEmpty || $0.tag.lowercased().contains(self.searchBar.text.lowercased())) })
89-
if filtered.count > 0 {
90-
Section(header: Text(letter)) {
91-
ForEach(filtered) { tag in
92-
Button(action: {
93-
94-
if tags.contains(where: {$0 == tag.tag}) {
95-
if tags.count > 1 {
96-
tags.removeAll(where: {$0 == tag.tag})
97-
}
98-
} else {
99-
tags.append(tag.tag)
100-
}
101-
UserDefaults.standard.set(self.tags, forKey: "selectedTags")
102-
}, label: {
103-
HStack {
104-
VStack(alignment: .leading) {
105-
Text("\(tag.tag)").bold()
106-
Text("\(tag.description)").foregroundColor(.gray)
107-
}
108-
Spacer()
109-
if tags.contains(where: {$0 == tag.tag}) {
110-
Text("\(Image(systemName: "checkmark"))").bold().foregroundColor(.accentColor)
111-
}
112-
}
113-
})
114-
}
115-
}.id(letter)
116-
}
117-
}
118-
HStack {
119-
Spacer()
120-
Text("\(fetcher.tags.count) Tags").font(Font(.footnote, sizeModifier: CGFloat(settings.textSizeModifier))).foregroundColor(.gray)
121-
Spacer()
122-
}.id("bottom")
123-
}.listStyle(PlainListStyle()).add(self.searchBar)
85+
body_list
12486

12587
VStack(alignment: .trailing) {
12688
Spacer().background(DestinationDataSetter(destination: "top"))
@@ -176,4 +138,58 @@ struct SelectTagsView: View {
176138
})
177139
}
178140
}
141+
142+
@ViewBuilder
143+
var body_list: some View {
144+
List {
145+
EmptyView().id("top")
146+
ForEach(alphabet, id: \.self) { letter in
147+
let filtered = fetcher.tags.filter({$0.tag.prefix(1).uppercased() == letter && (self.searchBar.text.isEmpty || $0.tag.lowercased().contains(self.searchBar.text.lowercased())) })
148+
listSection(letter: letter, items: filtered)
149+
}
150+
bottom_list_item
151+
}.listStyle(PlainListStyle()).add(self.searchBar)
152+
}
153+
154+
@ViewBuilder
155+
var bottom_list_item: some View {
156+
HStack {
157+
Spacer()
158+
Text("\(fetcher.tags.count) Tags").font(Font(.footnote, sizeModifier: CGFloat(settings.textSizeModifier))).foregroundColor(.gray)
159+
Spacer()
160+
}.id("bottom")
161+
}
162+
163+
@ViewBuilder
164+
func listSection(letter: String, items filtered: [Tag]) -> some View {
165+
if filtered.count > 0 {
166+
Section(header: Text(letter)) {
167+
ForEach(filtered) { tag in
168+
Button(action: {
169+
170+
if tags.contains(where: {$0 == tag.tag}) {
171+
if tags.count > 1 {
172+
tags.removeAll(where: {$0 == tag.tag})
173+
}
174+
} else {
175+
tags.append(tag.tag)
176+
}
177+
UserDefaults.standard.set(self.tags, forKey: "selectedTags")
178+
}, label: {
179+
HStack {
180+
VStack(alignment: .leading) {
181+
Text("\(tag.tag)").bold()
182+
Text("\(tag.description)").foregroundColor(.gray)
183+
}
184+
Spacer()
185+
if tags.contains(where: {$0 == tag.tag}) {
186+
Text("\(Image(systemName: "checkmark"))").bold().foregroundColor(.accentColor)
187+
}
188+
}
189+
})
190+
}
191+
}
192+
.id(letter)
193+
}
194+
}
179195
}

0 commit comments

Comments
 (0)