Merge pull request #131 from tootsuite/fix/profile-and-fix-issue

Fix compose and home UI issue
This commit is contained in:
CMK 2021-05-07 11:28:01 +08:00 committed by GitHub
commit 8409331dd8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 67 additions and 52 deletions

View File

@ -205,6 +205,8 @@
DB2B3AE925E38850007045F9 /* UIViewPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB2B3AE825E38850007045F9 /* UIViewPreview.swift */; }; DB2B3AE925E38850007045F9 /* UIViewPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB2B3AE825E38850007045F9 /* UIViewPreview.swift */; };
DB2F073525E8ECF000957B2D /* AuthenticationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB2F073325E8ECF000957B2D /* AuthenticationViewModel.swift */; }; DB2F073525E8ECF000957B2D /* AuthenticationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB2F073325E8ECF000957B2D /* AuthenticationViewModel.swift */; };
DB2FF510260B113300ADA9FE /* ComposeStatusPollExpiresOptionCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB2FF50F260B113300ADA9FE /* ComposeStatusPollExpiresOptionCollectionViewCell.swift */; }; DB2FF510260B113300ADA9FE /* ComposeStatusPollExpiresOptionCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB2FF50F260B113300ADA9FE /* ComposeStatusPollExpiresOptionCollectionViewCell.swift */; };
DB35B0B32643D821006AC73B /* TwitterTextEditor in Frameworks */ = {isa = PBXBuildFile; productRef = DB35B0B22643D821006AC73B /* TwitterTextEditor */; };
DB35B0B42643D821006AC73B /* TwitterTextEditor in Embed Frameworks */ = {isa = PBXBuildFile; productRef = DB35B0B22643D821006AC73B /* TwitterTextEditor */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
DB35FC1F2612F1D9006193C9 /* ProfileRelationshipActionButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB35FC1E2612F1D9006193C9 /* ProfileRelationshipActionButton.swift */; }; DB35FC1F2612F1D9006193C9 /* ProfileRelationshipActionButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB35FC1E2612F1D9006193C9 /* ProfileRelationshipActionButton.swift */; };
DB35FC252612FD7A006193C9 /* ProfileFieldView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB35FC242612FD7A006193C9 /* ProfileFieldView.swift */; }; DB35FC252612FD7A006193C9 /* ProfileFieldView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB35FC242612FD7A006193C9 /* ProfileFieldView.swift */; };
DB35FC2F26130172006193C9 /* MastodonField.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB35FC2E26130172006193C9 /* MastodonField.swift */; }; DB35FC2F26130172006193C9 /* MastodonField.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB35FC2E26130172006193C9 /* MastodonField.swift */; };
@ -437,8 +439,6 @@
DBE54ABF2636C889004E7C0B /* UserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6D1B23263684C600ACB481 /* UserDefaults.swift */; }; DBE54ABF2636C889004E7C0B /* UserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6D1B23263684C600ACB481 /* UserDefaults.swift */; };
DBE54AC62636C89F004E7C0B /* NotificationPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE54AC52636C89F004E7C0B /* NotificationPreference.swift */; }; DBE54AC62636C89F004E7C0B /* NotificationPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE54AC52636C89F004E7C0B /* NotificationPreference.swift */; };
DBE54ACC2636C8FD004E7C0B /* NotificationPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE54AC52636C89F004E7C0B /* NotificationPreference.swift */; }; DBE54ACC2636C8FD004E7C0B /* NotificationPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE54AC52636C89F004E7C0B /* NotificationPreference.swift */; };
DBE64A8B260C49D200E6359A /* TwitterTextEditor in Frameworks */ = {isa = PBXBuildFile; productRef = DBE64A8A260C49D200E6359A /* TwitterTextEditor */; };
DBE64A8C260C49D200E6359A /* TwitterTextEditor in Embed Frameworks */ = {isa = PBXBuildFile; productRef = DBE64A8A260C49D200E6359A /* TwitterTextEditor */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
DBF8AE16263293E400C9C23C /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBF8AE15263293E400C9C23C /* NotificationService.swift */; }; DBF8AE16263293E400C9C23C /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBF8AE15263293E400C9C23C /* NotificationService.swift */; };
DBF8AE1A263293E400C9C23C /* NotificationService.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = DBF8AE13263293E400C9C23C /* NotificationService.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; DBF8AE1A263293E400C9C23C /* NotificationService.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = DBF8AE13263293E400C9C23C /* NotificationService.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
DBF8AE862632992800C9C23C /* Base85 in Frameworks */ = {isa = PBXBuildFile; productRef = DBF8AE852632992800C9C23C /* Base85 */; }; DBF8AE862632992800C9C23C /* Base85 in Frameworks */ = {isa = PBXBuildFile; productRef = DBF8AE852632992800C9C23C /* Base85 */; };
@ -548,8 +548,8 @@
dstSubfolderSpec = 10; dstSubfolderSpec = 10;
files = ( files = (
DB6804872637CD4C00430867 /* AppShared.framework in Embed Frameworks */, DB6804872637CD4C00430867 /* AppShared.framework in Embed Frameworks */,
DBE64A8C260C49D200E6359A /* TwitterTextEditor in Embed Frameworks */,
DB89BA0425C10FD0008580ED /* CoreDataStack.framework in Embed Frameworks */, DB89BA0425C10FD0008580ED /* CoreDataStack.framework in Embed Frameworks */,
DB35B0B42643D821006AC73B /* TwitterTextEditor in Embed Frameworks */,
); );
name = "Embed Frameworks"; name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -1012,6 +1012,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
DB35B0B32643D821006AC73B /* TwitterTextEditor in Frameworks */,
DB0140BD25C40D7500F9F3CF /* CommonOSLog in Frameworks */, DB0140BD25C40D7500F9F3CF /* CommonOSLog in Frameworks */,
DB89BA0325C10FD0008580ED /* CoreDataStack.framework in Frameworks */, DB89BA0325C10FD0008580ED /* CoreDataStack.framework in Frameworks */,
2D42FF6125C8177C004A627A /* ActiveLabel in Frameworks */, 2D42FF6125C8177C004A627A /* ActiveLabel in Frameworks */,
@ -1024,7 +1025,6 @@
DBF96326262EC0A6001D8D25 /* AuthenticationServices.framework in Frameworks */, DBF96326262EC0A6001D8D25 /* AuthenticationServices.framework in Frameworks */,
2D61336925C18A4F00CAE157 /* AlamofireNetworkActivityIndicator in Frameworks */, 2D61336925C18A4F00CAE157 /* AlamofireNetworkActivityIndicator in Frameworks */,
DB3D0FF325BAA61700EAA174 /* AlamofireImage in Frameworks */, DB3D0FF325BAA61700EAA174 /* AlamofireImage in Frameworks */,
DBE64A8B260C49D200E6359A /* TwitterTextEditor in Frameworks */,
2D5981BA25E4D7F8000FB903 /* ThirdPartyMailer in Frameworks */, 2D5981BA25E4D7F8000FB903 /* ThirdPartyMailer in Frameworks */,
87FFDA5D898A5C42ADCB35E7 /* Pods_Mastodon.framework in Frameworks */, 87FFDA5D898A5C42ADCB35E7 /* Pods_Mastodon.framework in Frameworks */,
DB6804C82637CE2F00430867 /* AppShared.framework in Frameworks */, DB6804C82637CE2F00430867 /* AppShared.framework in Frameworks */,
@ -2417,8 +2417,8 @@
2D5981B925E4D7F8000FB903 /* ThirdPartyMailer */, 2D5981B925E4D7F8000FB903 /* ThirdPartyMailer */,
2D939AC725EE14620076FA61 /* CropViewController */, 2D939AC725EE14620076FA61 /* CropViewController */,
DB9A487D2603456B008B817C /* UITextView+Placeholder */, DB9A487D2603456B008B817C /* UITextView+Placeholder */,
DBE64A8A260C49D200E6359A /* TwitterTextEditor */,
DBB525072611EAC0002F1F29 /* Tabman */, DBB525072611EAC0002F1F29 /* Tabman */,
DB35B0B22643D821006AC73B /* TwitterTextEditor */,
); );
productName = Mastodon; productName = Mastodon;
productReference = DB427DD225BAA00100D1B89D /* Mastodon.app */; productReference = DB427DD225BAA00100D1B89D /* Mastodon.app */;
@ -2605,10 +2605,10 @@
2D5981B825E4D7F8000FB903 /* XCRemoteSwiftPackageReference "ThirdPartyMailer" */, 2D5981B825E4D7F8000FB903 /* XCRemoteSwiftPackageReference "ThirdPartyMailer" */,
2D939AC625EE14620076FA61 /* XCRemoteSwiftPackageReference "TOCropViewController" */, 2D939AC625EE14620076FA61 /* XCRemoteSwiftPackageReference "TOCropViewController" */,
DB9A487C2603456B008B817C /* XCRemoteSwiftPackageReference "UITextView-Placeholder" */, DB9A487C2603456B008B817C /* XCRemoteSwiftPackageReference "UITextView-Placeholder" */,
DBE64A89260C49D200E6359A /* XCRemoteSwiftPackageReference "TwitterTextEditor" */,
DBB525062611EAC0002F1F29 /* XCRemoteSwiftPackageReference "Tabman" */, DBB525062611EAC0002F1F29 /* XCRemoteSwiftPackageReference "Tabman" */,
DBF8AE842632992700C9C23C /* XCRemoteSwiftPackageReference "Base85" */, DBF8AE842632992700C9C23C /* XCRemoteSwiftPackageReference "Base85" */,
DB6804722637CC1200430867 /* XCRemoteSwiftPackageReference "KeychainAccess" */, DB6804722637CC1200430867 /* XCRemoteSwiftPackageReference "KeychainAccess" */,
DB35B0B12643D821006AC73B /* XCRemoteSwiftPackageReference "TwitterTextEditor" */,
); );
productRefGroup = DB427DD325BAA00100D1B89D /* Products */; productRefGroup = DB427DD325BAA00100D1B89D /* Products */;
projectDirPath = ""; projectDirPath = "";
@ -3949,6 +3949,14 @@
minimumVersion = 0.1.1; minimumVersion = 0.1.1;
}; };
}; };
DB35B0B12643D821006AC73B /* XCRemoteSwiftPackageReference "TwitterTextEditor" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/twitter/TwitterTextEditor";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 1.1.0;
};
};
DB3D0FF125BAA61700EAA174 /* XCRemoteSwiftPackageReference "AlamofireImage" */ = { DB3D0FF125BAA61700EAA174 /* XCRemoteSwiftPackageReference "AlamofireImage" */ = {
isa = XCRemoteSwiftPackageReference; isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/Alamofire/AlamofireImage.git"; repositoryURL = "https://github.com/Alamofire/AlamofireImage.git";
@ -3989,14 +3997,6 @@
minimumVersion = 2.11.0; minimumVersion = 2.11.0;
}; };
}; };
DBE64A89260C49D200E6359A /* XCRemoteSwiftPackageReference "TwitterTextEditor" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/MainasuK/TwitterTextEditor";
requirement = {
branch = "feature/input-view";
kind = branch;
};
};
DBF8AE842632992700C9C23C /* XCRemoteSwiftPackageReference "Base85" */ = { DBF8AE842632992700C9C23C /* XCRemoteSwiftPackageReference "Base85" */ = {
isa = XCRemoteSwiftPackageReference; isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/MainasuK/Base85.git"; repositoryURL = "https://github.com/MainasuK/Base85.git";
@ -4042,6 +4042,11 @@
package = DB0140BB25C40D7500F9F3CF /* XCRemoteSwiftPackageReference "CommonOSLog" */; package = DB0140BB25C40D7500F9F3CF /* XCRemoteSwiftPackageReference "CommonOSLog" */;
productName = CommonOSLog; productName = CommonOSLog;
}; };
DB35B0B22643D821006AC73B /* TwitterTextEditor */ = {
isa = XCSwiftPackageProductDependency;
package = DB35B0B12643D821006AC73B /* XCRemoteSwiftPackageReference "TwitterTextEditor" */;
productName = TwitterTextEditor;
};
DB3D0FF225BAA61700EAA174 /* AlamofireImage */ = { DB3D0FF225BAA61700EAA174 /* AlamofireImage */ = {
isa = XCSwiftPackageProductDependency; isa = XCSwiftPackageProductDependency;
package = DB3D0FF125BAA61700EAA174 /* XCRemoteSwiftPackageReference "AlamofireImage" */; package = DB3D0FF125BAA61700EAA174 /* XCRemoteSwiftPackageReference "AlamofireImage" */;
@ -4072,11 +4077,6 @@
package = DBB525062611EAC0002F1F29 /* XCRemoteSwiftPackageReference "Tabman" */; package = DBB525062611EAC0002F1F29 /* XCRemoteSwiftPackageReference "Tabman" */;
productName = Tabman; productName = Tabman;
}; };
DBE64A8A260C49D200E6359A /* TwitterTextEditor */ = {
isa = XCSwiftPackageProductDependency;
package = DBE64A89260C49D200E6359A /* XCRemoteSwiftPackageReference "TwitterTextEditor" */;
productName = TwitterTextEditor;
};
DBF8AE852632992800C9C23C /* Base85 */ = { DBF8AE852632992800C9C23C /* Base85 */ = {
isa = XCSwiftPackageProductDependency; isa = XCSwiftPackageProductDependency;
package = DBF8AE842632992700C9C23C /* XCRemoteSwiftPackageReference "Base85" */; package = DBF8AE842632992700C9C23C /* XCRemoteSwiftPackageReference "Base85" */;

View File

@ -12,7 +12,7 @@
<key>CoreDataStack.xcscheme_^#shared#^_</key> <key>CoreDataStack.xcscheme_^#shared#^_</key>
<dict> <dict>
<key>orderHint</key> <key>orderHint</key>
<integer>14</integer> <integer>15</integer>
</dict> </dict>
<key>Mastodon - RTL.xcscheme_^#shared#^_</key> <key>Mastodon - RTL.xcscheme_^#shared#^_</key>
<dict> <dict>
@ -32,7 +32,7 @@
<key>NotificationService.xcscheme_^#shared#^_</key> <key>NotificationService.xcscheme_^#shared#^_</key>
<dict> <dict>
<key>orderHint</key> <key>orderHint</key>
<integer>15</integer> <integer>14</integer>
</dict> </dict>
</dict> </dict>
<key>SuppressBuildableAutocreation</key> <key>SuppressBuildableAutocreation</key>

View File

@ -138,11 +138,11 @@
}, },
{ {
"package": "TwitterTextEditor", "package": "TwitterTextEditor",
"repositoryURL": "https://github.com/MainasuK/TwitterTextEditor", "repositoryURL": "https://github.com/twitter/TwitterTextEditor",
"state": { "state": {
"branch": "feature/input-view", "branch": null,
"revision": "1e565d13e3c26fc2bedeb418890df42f80d6e3d5", "revision": "dfe0edc3bcb6703ee2fd0e627f95e726b63e732a",
"version": null "version": "1.1.0"
} }
}, },
{ {

View File

@ -300,24 +300,9 @@ extension ComposeViewController {
} }
} }
.store(in: &disposeBag) .store(in: &disposeBag)
// bind text editor for custom emojis update event
viewModel.customEmojiViewModel
.compactMap { $0?.emojis }
.switchToLatest()
.sink(receiveValue: { [weak self] emojis in
guard let self = self else { return }
for emoji in emojis {
UITextChecker.learnWord(emoji.shortcode)
UITextChecker.learnWord(":" + emoji.shortcode + ":")
}
self.textEditorView()?.setNeedsUpdateTextAttributes()
})
.store(in: &disposeBag)
// bind custom emoji picker UI // bind custom emoji picker UI
viewModel.customEmojiViewModel viewModel.customEmojiViewModel
.receive(on: DispatchQueue.main)
.map { viewModel -> AnyPublisher<[Mastodon.Entity.Emoji], Never> in .map { viewModel -> AnyPublisher<[Mastodon.Entity.Emoji], Never> in
guard let viewModel = viewModel else { guard let viewModel = viewModel else {
return Just([]).eraseToAnyPublisher() return Just([]).eraseToAnyPublisher()
@ -325,6 +310,7 @@ extension ComposeViewController {
return viewModel.emojis.eraseToAnyPublisher() return viewModel.emojis.eraseToAnyPublisher()
} }
.switchToLatest() .switchToLatest()
.receive(on: DispatchQueue.main)
.sink(receiveValue: { [weak self] emojis in .sink(receiveValue: { [weak self] emojis in
guard let self = self else { return } guard let self = self else { return }
if emojis.isEmpty { if emojis.isEmpty {
@ -581,6 +567,7 @@ extension ComposeViewController: TextEditorViewTextAttributesDelegate {
updateAttributedString attributedString: NSAttributedString, updateAttributedString attributedString: NSAttributedString,
completion: @escaping (NSAttributedString?) -> Void completion: @escaping (NSAttributedString?) -> Void
) { ) {
// FIXME: needs O(1) update completion to fix profermance issue
DispatchQueue.global().async { DispatchQueue.global().async {
let string = attributedString.string let string = attributedString.string
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: update: %s", ((#file as NSString).lastPathComponent), #line, #function, string) os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: update: %s", ((#file as NSString).lastPathComponent), #line, #function, string)
@ -631,11 +618,10 @@ extension ComposeViewController: TextEditorViewTextAttributesDelegate {
} }
// emoji // emoji
let emojis = customEmojiViewModel?.emojis.value ?? [] if let customEmojiViewModel = customEmojiViewModel, !customEmojiViewModel.emojiDict.value.isEmpty {
if !emojis.isEmpty {
for match in emojiMatches { for match in emojiMatches {
guard let name = string.substring(with: match, at: 2) else { continue } guard let name = string.substring(with: match, at: 2) else { continue }
guard let emoji = emojis.first(where: { $0.shortcode == name }) else { continue } guard let emoji = customEmojiViewModel.emoji(shortcode: name) else { continue }
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: handle emoji: %s", ((#file as NSString).lastPathComponent), #line, #function, name) os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: handle emoji: %s", ((#file as NSString).lastPathComponent), #line, #function, name)
// set emoji token invisiable (without upper bounce space) // set emoji token invisiable (without upper bounce space)

View File

@ -415,6 +415,6 @@ extension ComposeViewModel: MastodonAttachmentServiceDelegate {
extension ComposeViewModel: ComposePollAttributeDelegate { extension ComposeViewModel: ComposePollAttributeDelegate {
func composePollAttribute(_ attribute: ComposeStatusItem.ComposePollOptionAttribute, pollOptionDidChange: String?) { func composePollAttribute(_ attribute: ComposeStatusItem.ComposePollOptionAttribute, pollOptionDidChange: String?) {
// trigger update // trigger update
// pollOptionAttributes.value = pollOptionAttributes.value pollOptionAttributes.value = pollOptionAttributes.value
} }
} }

View File

@ -82,7 +82,7 @@ final class PollOptionView: UIView {
extension PollOptionView { extension PollOptionView {
private func _init() { private func _init() {
// default color in the timeline // default color in the timeline
roundedBackgroundView.backgroundColor = Asset.Colors.Background.systemGroupedBackground.color roundedBackgroundView.backgroundColor = Asset.Colors.Background.secondarySystemBackground.color
roundedBackgroundView.translatesAutoresizingMaskIntoConstraints = false roundedBackgroundView.translatesAutoresizingMaskIntoConstraints = false
addSubview(roundedBackgroundView) addSubview(roundedBackgroundView)
@ -193,6 +193,11 @@ struct PollOptionView_Previews: PreviewProvider {
PollOptionView() PollOptionView()
} }
.previewLayout(.fixed(width: 375, height: 100)) .previewLayout(.fixed(width: 375, height: 100))
UIViewPreview(width: 375) {
PollOptionView()
}
.preferredColorScheme(.dark)
.previewLayout(.fixed(width: 375, height: 100))
} }
} }

View File

@ -340,9 +340,10 @@ extension StatusView {
contentWarningOverlayView.translatesAutoresizingMaskIntoConstraints = false contentWarningOverlayView.translatesAutoresizingMaskIntoConstraints = false
containerStackView.addSubview(contentWarningOverlayView) containerStackView.addSubview(contentWarningOverlayView)
NSLayoutConstraint.activate([ NSLayoutConstraint.activate([
statusContainerStackView.topAnchor.constraint(equalTo: contentWarningOverlayView.topAnchor, constant: StatusView.contentWarningBlurRadius).priority(.defaultLow), statusContainerStackView.topAnchor.constraint(equalTo: contentWarningOverlayView.topAnchor, constant: StatusView.contentWarningBlurRadius).priority(.defaultHigh),
statusContainerStackView.leftAnchor.constraint(equalTo: contentWarningOverlayView.leftAnchor, constant: StatusView.contentWarningBlurRadius).priority(.defaultLow), statusContainerStackView.leftAnchor.constraint(equalTo: contentWarningOverlayView.leftAnchor, constant: StatusView.contentWarningBlurRadius).priority(.defaultHigh),
// only layout to top-left corner and draw image to fit size contentWarningOverlayView.rightAnchor.constraint(equalTo: statusContainerStackView.rightAnchor, constant: StatusView.contentWarningBlurRadius).priority(.defaultHigh),
// only layout to top and left & right then draw image to fit size
]) ])
// avoid overlay clip author view // avoid overlay clip author view
containerStackView.bringSubviewToFront(authorContainerStackView) containerStackView.bringSubviewToFront(authorContainerStackView)

View File

@ -129,14 +129,16 @@ struct PollTableViewCell_Previews: PreviewProvider {
} }
.previewLayout(.fixed(width: 375, height: 44 + 10)) .previewLayout(.fixed(width: 375, height: 44 + 10))
} }
.background(Color(.systemBackground))
} }
static var previews: some View { static var previews: some View {
Group { Group {
controls.colorScheme(.light) controls
controls.colorScheme(.dark) .colorScheme(.light)
controls
.colorScheme(.dark)
} }
.background(Color.gray)
} }
} }

View File

@ -41,7 +41,7 @@ extension EmojiService.CustomEmojiViewModel.LoadState {
guard let viewModel = viewModel, let apiService = viewModel.service?.apiService, let stateMachine = stateMachine else { return } guard let viewModel = viewModel, let apiService = viewModel.service?.apiService, let stateMachine = stateMachine else { return }
apiService.customEmoji(domain: viewModel.domain) apiService.customEmoji(domain: viewModel.domain)
.receive(on: DispatchQueue.main) // .receive(on: DispatchQueue.main)
.sink { completion in .sink { completion in
switch completion { switch completion {
case .failure(let error): case .failure(let error):

View File

@ -32,10 +32,31 @@ extension EmojiService {
return stateMachine return stateMachine
}() }()
let emojis = CurrentValueSubject<[Mastodon.Entity.Emoji], Never>([]) let emojis = CurrentValueSubject<[Mastodon.Entity.Emoji], Never>([])
let emojiDict = CurrentValueSubject<[String: [Mastodon.Entity.Emoji]], Never>([:])
private var learnedEmoji: Set<String> = Set()
init(domain: String, service: EmojiService) { init(domain: String, service: EmojiService) {
self.domain = domain self.domain = domain
self.service = service self.service = service
emojis
.map { Dictionary(grouping: $0, by: { $0.shortcode }) }
.assign(to: \.value, on: emojiDict)
.store(in: &disposeBag)
}
func emoji(shortcode: String) -> Mastodon.Entity.Emoji? {
if !learnedEmoji.contains(shortcode) {
learnedEmoji.insert(shortcode)
DispatchQueue.global().async {
UITextChecker.learnWord(shortcode)
UITextChecker.learnWord(":" + shortcode + ":")
}
}
return emojiDict.value[shortcode]?.first
} }
} }