Skip to content

Commit 966dbc0

Browse files
authored
Merge pull request #1565 from DimensionDev/feature/swiftui_performance
optimize swiftui performance
2 parents d28ab81 + cf69182 commit 966dbc0

File tree

6 files changed

+112
-132
lines changed

6 files changed

+112
-132
lines changed

compose-ui/src/iosMain/kotlin/dev/dimension/flare/ui/presenter/SettingsPresenter.kt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ import dev.dimension.flare.data.model.TabSettings
99
import dev.dimension.flare.data.repository.SettingsRepository
1010
import dev.dimension.flare.ui.model.UiState
1111
import dev.dimension.flare.ui.model.collectAsUiState
12+
import kotlinx.coroutines.Dispatchers
1213
import kotlinx.coroutines.launch
14+
import kotlinx.coroutines.withContext
1315
import org.koin.core.component.KoinComponent
1416
import org.koin.core.component.inject
1517

@@ -31,19 +33,25 @@ public class SettingsPresenter :
3133

3234
override fun updateAppearanceSettings(block: AppearanceSettings.() -> AppearanceSettings) {
3335
scope.launch {
34-
repository.updateAppearanceSettings(block)
36+
withContext(Dispatchers.Main) {
37+
repository.updateAppearanceSettings(block)
38+
}
3539
}
3640
}
3741

3842
override fun updateAppSettings(block: AppSettings.() -> AppSettings) {
3943
scope.launch {
40-
repository.updateAppSettings(block)
44+
withContext(Dispatchers.Main) {
45+
repository.updateAppSettings(block)
46+
}
4147
}
4248
}
4349

4450
override fun updateTabSettings(block: TabSettings.() -> TabSettings) {
4551
scope.launch {
46-
repository.updateTabSettings(block)
52+
withContext(Dispatchers.Main) {
53+
repository.updateTabSettings(block)
54+
}
4755
}
4856
}
4957
}

iosApp/flare/UI/Component/MediaView.swift

Lines changed: 30 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -6,55 +6,35 @@ import AVFoundation
66

77
struct MediaView: View {
88
let data: UiMedia
9-
let expandToFullSize: Bool
109

11-
init(data: UiMedia, expandToFullSize: Bool = false) {
10+
init(data: UiMedia) {
1211
self.data = data
13-
self.expandToFullSize = expandToFullSize
1412
}
1513

1614
var body: some View {
17-
switch onEnum(of: data) {
18-
case .image(let image):
19-
AdaptiveSizeMediaContainerView(
20-
expandToFullSize: expandToFullSize
21-
) {
22-
NetworkImage(data: image.previewUrl)
23-
}
24-
case .video(let video):
25-
MediaVideoView(data: video, expandToFullSize: expandToFullSize)
26-
case .gif(let gif):
27-
AdaptiveSizeMediaContainerView(
28-
expandToFullSize: expandToFullSize
29-
) {
30-
NetworkImage(data: gif.url)
15+
ZStack {
16+
switch onEnum(of: data) {
17+
case .image(let image):
18+
Color.gray
19+
.opacity(0.2)
20+
.overlay {
21+
NetworkImage(data: image.previewUrl)
22+
.allowsHitTesting(false)
23+
}
24+
.clipped()
25+
case .video(let video):
26+
MediaVideoView(data: video)
27+
case .gif(let gif):
28+
Color.gray
29+
.opacity(0.2)
30+
.overlay {
31+
NetworkImage(data: gif.url)
32+
.allowsHitTesting(false)
33+
}
34+
.clipped()
35+
case .audio(let audio):
36+
EmptyView()
3137
}
32-
case .audio(let audio):
33-
EmptyView()
34-
}
35-
}
36-
}
37-
38-
struct AdaptiveSizeMediaContainerView<Content: View>: View {
39-
let expandToFullSize: Bool
40-
@ViewBuilder let content: () -> Content
41-
42-
init(expandToFullSize: Bool, @ViewBuilder content: @escaping () -> Content) {
43-
self.expandToFullSize = expandToFullSize
44-
self.content = content
45-
}
46-
47-
var body: some View {
48-
if expandToFullSize {
49-
content()
50-
} else {
51-
Color.gray
52-
.opacity(0.2)
53-
.overlay {
54-
content()
55-
.allowsHitTesting(false)
56-
}
57-
.clipped()
5838
}
5939
}
6040
}
@@ -68,7 +48,6 @@ struct MediaVideoView: View {
6848
@State private var time: CMTime = .zero
6949
@State private var isAppeared: Bool = false
7050
let data: UiMediaVideo
71-
let expandToFullSize: Bool
7251

7352
func canPlay() -> Bool {
7453
switch themeSettings.appearanceSettings.videoAutoplay {
@@ -82,11 +61,13 @@ struct MediaVideoView: View {
8261
}
8362

8463
var body: some View {
85-
AdaptiveSizeMediaContainerView(
86-
expandToFullSize: expandToFullSize
87-
) {
88-
NetworkImage(data: data.thumbnailUrl)
89-
}
64+
Color.gray
65+
.opacity(0.2)
66+
.overlay {
67+
NetworkImage(data: data.thumbnailUrl)
68+
.allowsHitTesting(false)
69+
}
70+
.clipped()
9071
.overlay {
9172
VideoPlayer(url: .init(string: data.url)!, play: $play, time: $time)
9273
.mute(true)

iosApp/flare/UI/Component/NetworkImage.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ struct NetworkImage: View {
66
let placeholder: URL?
77
let customHeader: [String: String]?
88
var body: some View {
9-
KFAnimatedImage(data)
9+
KFImage(data)
10+
.resizable()
1011
.requestModifier({ request in
1112
if let customHeader {
1213
for (key, value) in customHeader {

iosApp/flare/UI/Component/Status/StatusActionView.swift

Lines changed: 35 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,10 @@ struct StatusActionsView: View {
1010
HStack {
1111
ForEach(0..<data.count, id: \.self) { index in
1212
let item = data[index]
13+
if index == data.count - 1 {
14+
Spacer()
15+
}
1316
StatusActionView(data: item, useText: useText, isFixedWidth: index != data.count - 1)
14-
.if(index == data.count - 1) { view in
15-
view.frame(maxWidth: .infinity, alignment: .trailing)
16-
} else: { view in
17-
view
18-
}
19-
2017
}
2118
}
2219
.backport
@@ -92,7 +89,8 @@ struct StatusActionView: View {
9289
}
9390
}
9491
case .asyncActionItem(let asyncItem):
95-
AsyncStatusActionView(data: asyncItem)
92+
EmptyView()
93+
// AsyncStatusActionView(data: asyncItem)
9694
}
9795
}
9896
}
@@ -259,54 +257,37 @@ struct StatusActionIcon: View {
259257
let item: StatusActionItem
260258

261259
var body: some View {
262-
Group {
263-
switch onEnum(of: item) {
264-
case .bookmark(let bookmarked):
265-
if bookmarked.bookmarked {
266-
Image("fa-bookmark.fill")
267-
} else {
268-
Image("fa-bookmark")
269-
}
270-
271-
case .delete:
272-
Image("fa-trash")
273-
274-
case .like(let liked):
275-
if liked.liked {
276-
Image("fa-heart.fill")
277-
} else {
278-
Image("fa-heart")
279-
}
280-
281-
case .more:
282-
Image("fa-ellipsis")
283-
284-
case .quote:
285-
Image("fa-quote-left")
286-
287-
case .reaction(let reacted):
288-
if reacted.reacted {
289-
Image("fa-minus")
290-
} else {
291-
Image("fa-plus")
292-
}
293-
294-
case .reply:
295-
Image("fa-reply")
296-
297-
case .report:
298-
Image("fa-circle-info")
299-
300-
case .retweet:
301-
Image("fa-retweet")
260+
Image(item.imageName)
261+
}
262+
}
302263

303-
case .comment:
304-
Image("fa-comment-dots")
305-
case .share:
306-
Image(.faShareNodes)
307-
case .fxShare:
308-
Image(.faShareNodes)
309-
}
264+
extension StatusActionItem {
265+
var imageName: String {
266+
switch onEnum(of: self) {
267+
case .bookmark(let bookmarked):
268+
return bookmarked.bookmarked ? "fa-bookmark.fill" : "fa-bookmark"
269+
case .delete:
270+
return "fa-trash"
271+
case .like(let liked):
272+
return liked.liked ? "fa-heart.fill" : "fa-heart"
273+
case .more:
274+
return "fa-ellipsis"
275+
case .quote:
276+
return "fa-quote-left"
277+
case .reaction(let reacted):
278+
return reacted.reacted ? "fa-minus" : "fa-plus"
279+
case .reply:
280+
return "fa-reply"
281+
case .report:
282+
return "fa-circle-info"
283+
case .retweet:
284+
return "fa-retweet"
285+
case .comment:
286+
return "fa-comment-dots"
287+
case .share:
288+
return "fa-share-nodes"
289+
case .fxShare:
290+
return "fa-share-nodes"
310291
}
311292
}
312293
}

iosApp/flare/UI/Component/Status/StatusMediaView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ struct StatusMediaView: View {
2020
) {
2121
ForEach(0..<data.count, id: \.self) { index in
2222
let item = data[index]
23-
MediaView(data: item, expandToFullSize: themeSettings.appearanceSettings.expandMediaSize && data.count == 1)
23+
MediaView(data: item)
2424
.onTapGesture {
2525
if !sensitive || !isBlur {
2626
selectedIndex = index

iosApp/flare/UI/Component/Status/StatusView.swift

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ struct StatusView: View {
1111
let withLeadingPadding: Bool
1212
let showMedia: Bool
1313
@State private var expand = false
14-
@State private var expandMedia = false
1514
private var showAsFullWidth: Bool {
1615
(!themeSettings.appearanceSettings.fullWidthPost || withLeadingPadding) && !isQuote && !isDetail
1716
}
@@ -148,23 +147,7 @@ struct StatusView: View {
148147
}
149148

150149
if !data.images.isEmpty, showMedia {
151-
if themeSettings.appearanceSettings.showMedia || expandMedia {
152-
StatusMediaView(data: data.images, sensitive: !(themeSettings.appearanceSettings.showSensitiveContent) && data.sensitive)
153-
} else {
154-
Button {
155-
withAnimation {
156-
expandMedia = true
157-
}
158-
} label: {
159-
Label {
160-
Text("show_media_button", comment: "Button to show media attachments" )
161-
} icon: {
162-
Image("fa-image")
163-
}
164-
}
165-
.backport
166-
.glassButtonStyle(fallbackStyle: .bordered)
167-
}
150+
StatusMediaContent(data: data.images, sensitive: data.sensitive)
168151
}
169152

170153
if let card = data.card, showMedia, data.images.isEmpty, data.quote.isEmpty, themeSettings.appearanceSettings.showLinkPreview {
@@ -212,12 +195,12 @@ struct StatusView: View {
212195
}
213196
}
214197
}
215-
.if(!isDetail) { view in
216-
view
217-
.contextMenu {
218-
StatusActionsView(data: data.actions, useText: true)
219-
}
220-
}
198+
// .if(!isDetail) { view in
199+
// view
200+
// .contextMenu {
201+
// StatusActionsView(data: data.actions, useText: true)
202+
// }
203+
// }
221204
}
222205
}
223206
.contentShape(.rect)
@@ -245,6 +228,32 @@ struct StatusView: View {
245228
}
246229
}
247230

231+
struct StatusMediaContent: View {
232+
@Environment(\.themeSettings) private var themeSettings
233+
@State private var expandMedia = false
234+
let data: [any UiMedia]
235+
let sensitive: Bool
236+
var body: some View {
237+
if themeSettings.appearanceSettings.showMedia || expandMedia {
238+
StatusMediaView(data: data, sensitive: !(themeSettings.appearanceSettings.showSensitiveContent) && sensitive)
239+
} else {
240+
Button {
241+
withAnimation {
242+
expandMedia = true
243+
}
244+
} label: {
245+
Label {
246+
Text("show_media_button", comment: "Button to show media attachments" )
247+
} icon: {
248+
Image("fa-image")
249+
}
250+
}
251+
.backport
252+
.glassButtonStyle(fallbackStyle: .bordered)
253+
}
254+
}
255+
}
256+
248257
extension StatusView {
249258
init(data: UiTimeline.ItemContentStatus, isDetail: Bool) {
250259
self.data = data

0 commit comments

Comments
 (0)