Integrate emojibase (#1449)

* Integrate emojibase

* pin emojibase to version rather than revision

* Log error in case of failed loading of emojis from emojibase.

* Update Package.resolved

* Fix tests and bindings version
This commit is contained in:
David Langley
2023-08-10 19:14:18 +01:00
committed by GitHub
parent 975db4deb3
commit 8512d4c857
14 changed files with 86 additions and 30105 deletions
+17 -32
View File
@@ -159,7 +159,6 @@
383055C6ABE5BE058CEE1DDB /* WelcomeScreenScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57FE5EF0AFFE360C66420AAE /* WelcomeScreenScreenCoordinator.swift */; };
38546A6010A2CF240EC9AF73 /* BindableState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EA1D2CBAEA5D0BD00B90D1B /* BindableState.swift */; };
38896D54D6D675534E606195 /* RoomTimelineControllerFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6FCC416A3BFE73DF7B3E6BF /* RoomTimelineControllerFactory.swift */; };
3910D3A2EF98587C0E7B9CCB /* EmojiMartEmoji.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11F7F3CF7E70518BD7D25E04 /* EmojiMartEmoji.swift */; };
39929D29B265C3F6606047DE /* AlignedScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8872E9C5E91E9F2BFC4EBCCA /* AlignedScrollView.swift */; };
3A08584ECDD4A4541DBF21F8 /* EmojiLoaderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 201305507D7DFD16E544563A /* EmojiLoaderProtocol.swift */; };
3A64A93A651A3CB8774ADE8E /* Collections in Frameworks */ = {isa = PBXBuildFile; productRef = BA93CD75CCE486660C9040BD /* Collections */; };
@@ -217,7 +216,6 @@
4FF90E2242DBD596E1ED2E27 /* AppCoordinatorStateMachine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077D7C3BE199B6E5DDEC07EC /* AppCoordinatorStateMachine.swift */; };
4FFDC274824F7CC0BBDF581E /* BugReportScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C2BCE0BC1FC69C1B36E688 /* BugReportScreenModels.swift */; };
500CB65ED116B81DA52FDAEE /* TimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 874A1842477895F199567BD7 /* TimelineView.swift */; };
501304F26B52DF7024011B6C /* EmojiMartJSONLoaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BF9E3E6A23180EC05F06460 /* EmojiMartJSONLoaderTests.swift */; };
50C90117FE25390BFBD40173 /* RustTracing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 542D4F49FABA056DEEEB3400 /* RustTracing.swift */; };
5100F53E6884A15F9BA07CC3 /* AttributedStringTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CA26F55123E36B50DB0B3A /* AttributedStringTests.swift */; };
516534FC5C893D57F169D5A8 /* MapTilerGeocoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33720F7AD25E85E4A84669E8 /* MapTilerGeocoding.swift */; };
@@ -346,7 +344,6 @@
7C384A8E54A4B60A14CDE8E5 /* WaitlistScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12F1E7F9C2BE8BB751037826 /* WaitlistScreenCoordinator.swift */; };
7C6376192F578E0BA801BFEC /* AnalyticsSettingsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42C64A14EE89928207E3B42B /* AnalyticsSettingsScreenModels.swift */; };
7CD16990BA843BE9ED639129 /* ImageRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DFE4453AB0B34C203447162 /* ImageRoomTimelineItem.swift */; };
7E3C34BC10936AD4F77975F4 /* EmojiMartJSONLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39001365B76B89983FDB7AD8 /* EmojiMartJSONLoader.swift */; };
7E91BAC17963ED41208F489B /* UserSessionStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E8BDC092D817B68CD9040C5 /* UserSessionStore.swift */; };
7ECF12D5DCD69F67BD3E3842 /* RoomTimelineControllerFactoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18FE0CDF1FFA92EA7EE17B0B /* RoomTimelineControllerFactoryProtocol.swift */; };
7F02063FB3D1C3E5601471A1 /* WelcomeScreenScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 851EF6258DF8B7EF129DC3AC /* WelcomeScreenScreenViewModelTests.swift */; };
@@ -415,7 +412,6 @@
90EB25D13AE6EEF034BDE9D2 /* Assets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71D52BAA5BADB06E5E8C295D /* Assets.swift */; };
91ABC91758A6E4A5FAA2E9C4 /* ReadReceipt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 314F1C79850BE46E8ABEAFCB /* ReadReceipt.swift */; };
9219640F4D980CFC5FE855AD /* target.yml in Resources */ = {isa = PBXBuildFile; fileRef = 536E72DCBEEC4A1FE66CFDCE /* target.yml */; };
92B95779840CD749117B3615 /* EmojiMartStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = C38AE3617D7619EF30CDD229 /* EmojiMartStore.swift */; };
92D9088B901CEBB1A99ECA4E /* RoomMemberProxyMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36FD673E24FBFCFDF398716A /* RoomMemberProxyMock.swift */; };
93875ADD456142D20823ED24 /* ServerSelectionViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDAA4472821985BF868CC21C /* ServerSelectionViewModelTests.swift */; };
93BA4A81B6D893271101F9F0 /* Collections in Frameworks */ = {isa = PBXBuildFile; productRef = 9C73F37731C9FDED1BB24C1C /* Collections */; };
@@ -467,6 +463,7 @@
A009BDFB0A6816D4C392ADCB /* SettingsScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AF715D4FD4710EBB637D661 /* SettingsScreenViewModelProtocol.swift */; };
A021827B528F1EDC9101CA58 /* AppCoordinatorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBC776F301D374A3298C69DA /* AppCoordinatorProtocol.swift */; };
A0A0D2A9564BDA3FDE2E360F /* FormattedBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = F73FF1A33198F5FAE9D34B1F /* FormattedBodyText.swift */; };
A0D7E5BD0298A97DCBDCE40B /* Emojibase in Frameworks */ = {isa = PBXBuildFile; productRef = C05729B1684C331F5FFE9232 /* Emojibase */; };
A10D6CCDE2010C09EEA1A593 /* HomeScreenRoomList.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7661EFFCAA307A97D71132A /* HomeScreenRoomList.swift */; };
A14A9419105A1CD42F0511C4 /* UserIndicatorModalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E43005941B3A2C9671E23C85 /* UserIndicatorModalView.swift */; };
A17FAD2EBC53E17B5FD384DB /* InviteUsersScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22730A30C50AC2E3D5BA8642 /* InviteUsersScreenViewModelProtocol.swift */; };
@@ -612,7 +609,6 @@
CBD2ABE4C1A47ECD99E1488E /* NotificationSettingsScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 421FA93BCC2840E66E4F306F /* NotificationSettingsScreenViewModelProtocol.swift */; };
CC0D088F505F33A20DC5590F /* RoomStateEventStringBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEEAFB646E583655652C3D04 /* RoomStateEventStringBuilderTests.swift */; };
CC961529F9F1854BEC3272C9 /* LayoutMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC8AA23D4F37CC26564F63C5 /* LayoutMocks.swift */; };
CCAA0671B46EAFD0BB528E2C /* apple_emojis_data.json in Resources */ = {isa = PBXBuildFile; fileRef = 8FC26871038FB0E4AAE22605 /* apple_emojis_data.json */; };
CCBEC2100CAF2EEBE9DB4156 /* TemplateScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA40B98B098B6F0371B750B3 /* TemplateScreenModels.swift */; };
CCC3802A3C019A6FFAAA547A /* NotificationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07E65E613F057697A1A0BC03 /* NotificationViewController.swift */; };
CD0088B763CD970CF1CBF8CB /* DateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B5E97E9615A158C76B2AB77 /* DateTests.swift */; };
@@ -709,7 +705,6 @@
EDC1031A7CFB3406A9DA3175 /* AnalyticsLocationType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AD6299F4516797E9BBE14C3 /* AnalyticsLocationType.swift */; };
EDF8919F15DE0FF00EF99E70 /* DocumentPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F5567A7EF6F2AB9473236F6 /* DocumentPicker.swift */; };
EE4F5601356228FF72FC56B6 /* MockClientProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F40F48279322E504153AB0D /* MockClientProxy.swift */; };
EE6933C935080B4E0348A58B /* EmojiMartCategory.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5C3AACCAA82392D08924496 /* EmojiMartCategory.swift */; };
EE8491AD81F47DF3C192497B /* DecorationTimelineItemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 184CF8C196BE143AE226628D /* DecorationTimelineItemProtocol.swift */; };
EE8A37E2A1A77DE5CF941632 /* StateRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED983D4DCA5AFA6E1ED96099 /* StateRoomTimelineView.swift */; };
EEAE954289DE813A61656AE0 /* LayoutDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14D83B2B7CD5501A0089EFC /* LayoutDirection.swift */; };
@@ -865,7 +860,6 @@
10F32E0B4B83D2A11EE8D011 /* InviteUsersScreenSelectedItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InviteUsersScreenSelectedItem.swift; sourceTree = "<group>"; };
11151E78D6BB2B04A8FBD389 /* EmojiPickerScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiPickerScreenViewModelProtocol.swift; sourceTree = "<group>"; };
111B698739E3410E2CDB7144 /* MXLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MXLog.swift; sourceTree = "<group>"; };
11F7F3CF7E70518BD7D25E04 /* EmojiMartEmoji.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiMartEmoji.swift; sourceTree = "<group>"; };
1215A4FC53D2319E81AE8970 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
122186B7CD1BC46A9C629DD9 /* RoomDetailsEditScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsEditScreenUITests.swift; sourceTree = "<group>"; };
1222DB76B917EB8A55365BA5 /* target.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = target.yml; sourceTree = "<group>"; };
@@ -972,7 +966,6 @@
37CA26F55123E36B50DB0B3A /* AttributedStringTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributedStringTests.swift; sourceTree = "<group>"; };
382B50F7E379B3DBBD174364 /* NotificationSettingsProxyMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsProxyMock.swift; sourceTree = "<group>"; };
38E521D6C2BF8DF0DFB35146 /* DeveloperOptionsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperOptionsScreen.swift; sourceTree = "<group>"; };
39001365B76B89983FDB7AD8 /* EmojiMartJSONLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiMartJSONLoader.swift; sourceTree = "<group>"; };
3948D16F021DFDB2CD26EAA8 /* MockBackgroundTaskService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockBackgroundTaskService.swift; sourceTree = "<group>"; };
398817652FA8ABAE0A31AC6D /* ReadableFrameModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadableFrameModifier.swift; sourceTree = "<group>"; };
39B6C8690AEA1E49FF1BAF95 /* MediaUploadPreviewScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaUploadPreviewScreenUITests.swift; sourceTree = "<group>"; };
@@ -1205,7 +1198,6 @@
8F21ED7205048668BEB44A38 /* AppActivityView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppActivityView.swift; sourceTree = "<group>"; };
8F61A0DD8243B395499C99A2 /* InvitesScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvitesScreenUITests.swift; sourceTree = "<group>"; };
8F7D42E66E939B709C1EC390 /* MockRoomSummaryProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockRoomSummaryProvider.swift; sourceTree = "<group>"; };
8FC26871038FB0E4AAE22605 /* apple_emojis_data.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = apple_emojis_data.json; sourceTree = "<group>"; };
8FC803282F9268D49F4ABF14 /* AppCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCoordinator.swift; sourceTree = "<group>"; };
90A55430639712CFACA34F43 /* TextRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextRoomTimelineItem.swift; sourceTree = "<group>"; };
90F2F8998E5632668B0AD848 /* RoomTimelineItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineItemView.swift; sourceTree = "<group>"; };
@@ -1236,7 +1228,6 @@
9B06663F7858E45882E63471 /* StaticLocationScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StaticLocationScreen.swift; sourceTree = "<group>"; };
9B65A314DF40B6BBF775C2BC /* AnalyticsPromptScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsPromptScreenCoordinator.swift; sourceTree = "<group>"; };
9B663BE498BB39EADC24025D /* SettingsScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsScreenModels.swift; sourceTree = "<group>"; };
9BF9E3E6A23180EC05F06460 /* EmojiMartJSONLoaderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiMartJSONLoaderTests.swift; sourceTree = "<group>"; };
9C4048041C1A6B20CB97FD18 /* TestMeasurementParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestMeasurementParser.swift; sourceTree = "<group>"; };
9C5E81214D27A6B898FC397D /* ElementX.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ElementX.entitlements; sourceTree = "<group>"; };
9C698E30698EC59302A8EEBD /* NavigationStackCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationStackCoordinatorTests.swift; sourceTree = "<group>"; };
@@ -1353,7 +1344,6 @@
C2E9B841EE4878283ECDB554 /* InviteUsersScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InviteUsersScreen.swift; sourceTree = "<group>"; };
C2F079B5DBD0D85FEA687AAE /* SDKGeneratedMocks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SDKGeneratedMocks.swift; sourceTree = "<group>"; };
C352359663A0E52BA20761EE /* LoadableImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadableImage.swift; sourceTree = "<group>"; };
C38AE3617D7619EF30CDD229 /* EmojiMartStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiMartStore.swift; sourceTree = "<group>"; };
C4C89820BB2B88D4EA28131C /* BugReportScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportScreenViewModelProtocol.swift; sourceTree = "<group>"; };
C54464351F170D570110AFCA /* WelcomeScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeScreen.swift; sourceTree = "<group>"; };
C55D7E514F9DE4E3D72FDCAD /* SessionVerificationControllerProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationControllerProxy.swift; sourceTree = "<group>"; };
@@ -1447,7 +1437,6 @@
E51E3D86A84341C3A0CB8A40 /* FileRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileRoomTimelineView.swift; sourceTree = "<group>"; };
E5272BC4A60B6AD7553BACA1 /* BlurHashDecode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlurHashDecode.swift; sourceTree = "<group>"; };
E55B5EA766E89FF1F87C3ACB /* RoomNotificationSettingsProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomNotificationSettingsProxyProtocol.swift; sourceTree = "<group>"; };
E5C3AACCAA82392D08924496 /* EmojiMartCategory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiMartCategory.swift; sourceTree = "<group>"; };
E5E94DCFEE803E5ABAE8ACCE /* KeychainControllerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainControllerProtocol.swift; sourceTree = "<group>"; };
E5F2B6443D1ED8602F328539 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ru; path = ru.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
E6281B199D8A8F0892490C2E /* OnboardingCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingCoordinator.swift; sourceTree = "<group>"; };
@@ -1600,6 +1589,7 @@
B0CB16349B96262AA65A04AF /* Sentry in Frameworks */,
36AD4DD4C798E22584ED3200 /* URLRouting in Frameworks */,
36CD6E11B37396E14F032CB6 /* Version in Frameworks */,
A0D7E5BD0298A97DCBDCE40B /* Emojibase in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2037,7 +2027,6 @@
37A243E04B58DC6E41FDCD82 /* EmojiItem.swift */,
201305507D7DFD16E544563A /* EmojiLoaderProtocol.swift */,
6C113E0CB7E15E9765B1817A /* EmojiProvider.swift */,
5BACB442D02C878293C04837 /* EmojiMart */,
);
path = Emojis;
sourceTree = "<group>";
@@ -2340,18 +2329,6 @@
path = SoftLogoutScreen;
sourceTree = "<group>";
};
5BACB442D02C878293C04837 /* EmojiMart */ = {
isa = PBXGroup;
children = (
8FC26871038FB0E4AAE22605 /* apple_emojis_data.json */,
E5C3AACCAA82392D08924496 /* EmojiMartCategory.swift */,
11F7F3CF7E70518BD7D25E04 /* EmojiMartEmoji.swift */,
39001365B76B89983FDB7AD8 /* EmojiMartJSONLoader.swift */,
C38AE3617D7619EF30CDD229 /* EmojiMartStore.swift */,
);
path = EmojiMart;
sourceTree = "<group>";
};
5DC032EC5F19009AA7CADB41 /* View */ = {
isa = PBXGroup;
children = (
@@ -2525,7 +2502,6 @@
6D0A27607AB09784C8501B5C /* DeveloperOptionsScreenViewModelTests.swift */,
DBFEAC3AC691CBB84983E275 /* ElementXTests.swift */,
A58E93D91DE3288010390DEE /* EmojiDetectionTests.swift */,
9BF9E3E6A23180EC05F06460 /* EmojiMartJSONLoaderTests.swift */,
099F2D36C141D845A445B1E6 /* EmojiProviderTests.swift */,
84B7A28A6606D58D1E38C55A /* ExpiringTaskRunnerTests.swift */,
1A7ED2EF5BDBAD2A7DBC4636 /* GeoURITests.swift */,
@@ -3820,6 +3796,7 @@
7731767AE437BA3BD2CC14A8 /* Sentry */,
E9BAB8A793FE3B54CDD47102 /* URLRouting */,
A05AF81DDD14AD58CB0E1B9B /* Version */,
C05729B1684C331F5FFE9232 /* Emojibase */,
);
productName = ElementX;
productReference = 4CD6AC7546E8D7E5C73CEA48 /* ElementX.app */;
@@ -3934,6 +3911,7 @@
9754C4B03F6255F67FC15E52 /* XCRemoteSwiftPackageReference "compound-ios" */,
C13F55E4518415CB4C278E73 /* XCRemoteSwiftPackageReference "DTCoreText" */,
D5F7D47BBAAE0CF1DDEB3034 /* XCRemoteSwiftPackageReference "DeviceKit" */,
821C67C9A7F8CC3FD41B28B4 /* XCRemoteSwiftPackageReference "emojibase-bindings" */,
701C7BEF8F70F7A83E852DCC /* XCRemoteSwiftPackageReference "GZIP" */,
395DE6AE429B7ACC7C7FE31D /* XCRemoteSwiftPackageReference "KZFileWatchers" */,
61916C63E3F5BD900F08DA0C /* XCRemoteSwiftPackageReference "KeychainAccess" */,
@@ -3976,7 +3954,6 @@
6860721DB3091BE08164C132 /* MapAssets.xcassets in Resources */,
CE1694C7BB93C3311524EF28 /* Untranslated.strings in Resources */,
2797C9D9BA642370F1C85D78 /* Untranslated.stringsdict in Resources */,
CCAA0671B46EAFD0BB528E2C /* apple_emojis_data.json in Resources */,
E67418DACEDBC29E988E6ACD /* message.caf in Resources */,
DFF7D6A6C26DDD40D00AE579 /* target.yml in Resources */,
);
@@ -4177,7 +4154,6 @@
864C69CF951BF36D25BE0C03 /* DeveloperOptionsScreenViewModelTests.swift in Sources */,
9C45CE85325CD591DADBC4CA /* ElementXTests.swift in Sources */,
F697284B9B5F2C00CFEA3B12 /* EmojiDetectionTests.swift in Sources */,
501304F26B52DF7024011B6C /* EmojiMartJSONLoaderTests.swift in Sources */,
25618589E0DE0F1E95FC7B5C /* EmojiProviderTests.swift in Sources */,
71B62C48B8079D49F3FBC845 /* ExpiringTaskRunnerTests.swift in Sources */,
07756D532EFE33DD1FA258E5 /* GeoURITests.swift in Sources */,
@@ -4364,10 +4340,6 @@
E45C9FA22BC13B477FD3B4AC /* EmojiDetection.swift in Sources */,
D5C805F49B2C75DC3793E780 /* EmojiItem.swift in Sources */,
3A08584ECDD4A4541DBF21F8 /* EmojiLoaderProtocol.swift in Sources */,
EE6933C935080B4E0348A58B /* EmojiMartCategory.swift in Sources */,
3910D3A2EF98587C0E7B9CCB /* EmojiMartEmoji.swift in Sources */,
7E3C34BC10936AD4F77975F4 /* EmojiMartJSONLoader.swift in Sources */,
92B95779840CD749117B3615 /* EmojiMartStore.swift in Sources */,
340D39DB87F3800D53A6A621 /* EmojiPickerScreen.swift in Sources */,
C1910A16BDF131FECA77BE22 /* EmojiPickerScreenCoordinator.swift in Sources */,
EEB9C1555C63B93CA9C372C2 /* EmojiPickerScreenHeaderView.swift in Sources */,
@@ -5433,6 +5405,14 @@
version = "1.0.105-alpha";
};
};
821C67C9A7F8CC3FD41B28B4 /* XCRemoteSwiftPackageReference "emojibase-bindings" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/matrix-org/emojibase-bindings";
requirement = {
kind = upToNextMinorVersion;
minimumVersion = 1.0.0;
};
};
96495DD8554E2F39D3954354 /* XCRemoteSwiftPackageReference "posthog-ios" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/PostHog/posthog-ios";
@@ -5743,6 +5723,11 @@
package = D5F7D47BBAAE0CF1DDEB3034 /* XCRemoteSwiftPackageReference "DeviceKit" */;
productName = DeviceKit;
};
C05729B1684C331F5FFE9232 /* Emojibase */ = {
isa = XCSwiftPackageProductDependency;
package = 821C67C9A7F8CC3FD41B28B4 /* XCRemoteSwiftPackageReference "emojibase-bindings" */;
productName = Emojibase;
};
C1BF15833233CD3BDB7E2B1D /* Mapbox */ = {
isa = XCSwiftPackageProductDependency;
package = 0CBF57301AA172C21F76CE86 /* XCRemoteSwiftPackageReference "maplibre-gl-native-distribution" */;
@@ -52,6 +52,15 @@
"version" : "0.0.3"
}
},
{
"identity" : "emojibase-bindings",
"kind" : "remoteSourceControl",
"location" : "https://github.com/matrix-org/emojibase-bindings",
"state" : {
"revision" : "603693b5909e98e9a616420cbdf7a357828ab030",
"version" : "1.0.0"
}
},
{
"identity" : "gzip",
"kind" : "remoteSourceControl",
@@ -60,11 +60,7 @@ class EmojiPickerScreenViewModel: EmojiPickerScreenViewModelType, EmojiPickerScr
emojiCategories.compactMap { emojiCategory in
let emojisViewData: [EmojiPickerEmojiViewData] = emojiCategory.emojis.compactMap { emojiItem in
guard let firstSkin = emojiItem.skins.first else {
return nil
}
return EmojiPickerEmojiViewData(id: emojiItem.id, value: firstSkin)
EmojiPickerEmojiViewData(id: emojiItem.id, value: emojiItem.unicode)
}
return EmojiPickerEmojiCategoryViewData(id: emojiCategory.id, emojis: emojisViewData)
@@ -17,19 +17,13 @@
import Foundation
struct EmojiItem: Equatable, Identifiable {
var id: String
let name: String
var id: String {
label
}
let label: String
let unicode: String
let keywords: [String]
let shortcodes: [String]
let skins: [String]
}
extension EmojiItem {
init?(from emojiMart: EmojiMartEmoji) {
id = emojiMart.id
name = emojiMart.name
keywords = emojiMart.keywords
skins = emojiMart.skins.map { emojiMartEmojiSkin in
emojiMartEmojiSkin.native
}
}
}
@@ -1,22 +0,0 @@
//
// Copyright 2022 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import Foundation
struct EmojiMartCategory: Decodable {
let id: String
let emojis: [String]
}
@@ -1,29 +0,0 @@
//
// Copyright 2022 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import Foundation
struct EmojiMartEmoji: Decodable {
let id: String
let name: String
let keywords: [String]
let skins: [EmojiMartEmojiSkin]
}
struct EmojiMartEmojiSkin: Decodable {
let unified: String
let native: String
}
@@ -1,60 +0,0 @@
//
// Copyright 2022 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import Foundation
private enum EmojiMartJSONLoaderError: Error {
case fileNotFound
}
class EmojiMartJSONLoader: EmojiLoaderProtocol {
/// Emoji data coming from https://github.com/missive/emoji-mart/blob/main/packages/emoji-mart-data/sets/14/apple.json
private let jsonFilename = "apple_emojis_data"
func load() async -> [EmojiCategory] {
do {
let data = try await loadJSONData()
let store = try await decodeJSONData(data: data)
return emojiCategories(from: store)
} catch {
MXLog.error("Couldn't parse emoji json")
return []
}
}
private func loadJSONData() async throws -> Data {
guard let jsonDataURL = Bundle.main.url(forResource: jsonFilename, withExtension: "json") else {
throw EmojiMartJSONLoaderError.fileNotFound
}
return try Data(contentsOf: jsonDataURL)
}
private func decodeJSONData(data: Data) async throws -> EmojiMartStore {
try JSONDecoder().decode(EmojiMartStore.self, from: data)
}
private func emojiCategories(from emojiMartStore: EmojiMartStore) -> [EmojiCategory] {
emojiMartStore.categories.map { emojiMartCategory -> EmojiCategory in
let emojiItems = emojiMartCategory.emojis.compactMap { emoji -> EmojiItem? in
guard let emojiMartEmoji = emojiMartStore.emojis.first(where: { $0.id == emoji }) else {
return nil
}
return EmojiItem(from: emojiMartEmoji)
}
return EmojiCategory(id: emojiMartCategory.id, emojis: emojiItems)
}
}
}
@@ -1,35 +0,0 @@
//
// Copyright 2022 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import Foundation
struct EmojiMartStore: Decodable {
let categories: [EmojiMartCategory]
let emojis: [EmojiMartEmoji]
enum CodingKeys: CodingKey {
case categories
case emojis
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
categories = try container.decode([EmojiMartCategory].self, forKey: .categories)
let emojisDictionary = try container.decode([String: EmojiMartEmoji].self, forKey: .emojis)
emojis = emojisDictionary.map(\.value)
}
}
File diff suppressed because one or more lines are too long
@@ -14,6 +14,7 @@
// limitations under the License.
//
import Emojibase
import Foundation
@MainActor
@@ -31,7 +32,7 @@ class EmojiProvider: EmojiProviderProtocol {
private let loader: EmojiLoaderProtocol
private var state: EmojiProviderState = .notLoaded
init(loader: EmojiLoaderProtocol = EmojiMartJSONLoader()) {
init(loader: EmojiLoaderProtocol = EmojibaseDatasource()) {
self.loader = loader
Task {
await loadIfNeeded()
@@ -50,7 +51,7 @@ class EmojiProvider: EmojiProviderProtocol {
private func search(searchString: String, emojiCategories: [EmojiCategory]) -> [EmojiCategory] {
emojiCategories.compactMap { category in
let emojis = category.emojis.filter { emoji in
let searchArray = [emoji.id, emoji.name] + emoji.keywords
let searchArray = [emoji.label + emoji.unicode] + emoji.shortcodes + emoji.keywords
return searchArray.description.range(of: searchString, options: .caseInsensitive) != nil
}
return emojis.isEmpty ? nil : EmojiCategory(id: category.id, emojis: emojis)
@@ -74,3 +75,28 @@ class EmojiProvider: EmojiProviderProtocol {
}
}
}
extension EmojibaseDatasource: EmojiLoaderProtocol {
func load() async -> [EmojiCategory] {
do {
let store: EmojibaseStore = try await load()
return EmojibaseCategory.allCases.map { category in
let emojis = store.categories[category.rawValue] ?? []
return EmojiCategory(id: category.rawValue, emojis: emojis.compactMap(EmojiItem.init(from:)))
}
} catch {
MXLog.error("Failed retrieving emojis from the emojibase datasource: \(error)")
}
return []
}
}
extension EmojiItem {
init?(from emojibase: Emoji) {
unicode = emojibase.unicode
label = emojibase.label
shortcodes = emojibase.shortcodes
keywords = emojibase.tags ?? []
skins = emojibase.skins?.map(\.unicode) ?? []
}
}
+1
View File
@@ -163,6 +163,7 @@ targets:
- package: Sentry
- package: URLRouting
- package: Version
- package: Emojibase
sources:
- path: ../Sources
@@ -1,32 +0,0 @@
//
// Copyright 2022 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import XCTest
@testable import ElementX
final class EmojiMartJSONLoaderTests: XCTestCase {
var sut: EmojiMartJSONLoader!
override func setUp() {
sut = EmojiMartJSONLoader()
}
func test_whenEmojisLoaded_CorrectCategoryCountReturned() async {
let categories = await sut.load()
XCTAssertEqual(categories.count, 8)
}
}
+19 -25
View File
@@ -28,7 +28,7 @@ final class EmojiProviderTests: XCTestCase {
}
func test_whenEmojisLoaded_categoriesAreLoadedFromLoader() async throws {
let item = EmojiItem(id: "test", name: "test", keywords: ["1", "2"], skins: ["🙂"])
let item = EmojiItem(label: "test", unicode: "test", keywords: ["1", "2"], shortcodes: ["1", "2"], skins: ["🙂"])
let category = EmojiCategory(id: "test", emojis: [item])
emojiLoaderMock.categories = [category]
let categories = await sut.getCategories()
@@ -36,7 +36,7 @@ final class EmojiProviderTests: XCTestCase {
}
func test_whenEmojisLoadedAndSearchStringEmpty_allCategoriesReturned() async throws {
let item = EmojiItem(id: "test", name: "test", keywords: ["1", "2"], skins: ["🙂"])
let item = EmojiItem(label: "test", unicode: "test", keywords: ["1", "2"], shortcodes: ["1", "2"], skins: ["🙂"])
let category = EmojiCategory(id: "test", emojis: [item])
emojiLoaderMock.categories = [category]
let categories = await sut.getCategories(searchString: "")
@@ -44,10 +44,12 @@ final class EmojiProviderTests: XCTestCase {
}
func test_whenEmojisLoadedSecondTime_cachedValuesAreUsed() async throws {
let item = EmojiItem(label: "test", unicode: "test", keywords: ["1", "2"], shortcodes: ["1", "2"], skins: ["🙂"])
let item2 = EmojiItem(label: "test2", unicode: "test2", keywords: ["3", "4"], shortcodes: ["3", "4"], skins: ["🙂"])
let categoriesForFirstLoad = [EmojiCategory(id: "test",
emojis: [EmojiItem(id: "test", name: "test", keywords: ["1", "2"], skins: ["🙂"])])]
emojis: [item])]
let categoriesForSecondLoad = [EmojiCategory(id: "test2",
emojis: [EmojiItem(id: "test2", name: "test2", keywords: ["3", "4"], skins: ["🫠"])])]
emojis: [item2])]
emojiLoaderMock.categories = categoriesForFirstLoad
_ = await sut.getCategories()
emojiLoaderMock.categories = categoriesForSecondLoad
@@ -58,33 +60,25 @@ final class EmojiProviderTests: XCTestCase {
func test_whenEmojisSearched_correctNumberOfCategoriesReturned() async throws {
let searchString = "smile"
var categories = [EmojiCategory]()
let item0WithSearchString = EmojiItem(label: "emoji0", unicode: "\(searchString)_123", keywords: ["key1", "key1"], shortcodes: ["key1", "key1"], skins: ["🙂"])
let item1WithSearchString = EmojiItem(label: searchString, unicode: "emoji1", keywords: ["key1", "key1"], shortcodes: ["key1", "key1"], skins: ["🙂"])
let item2WithSearchString = EmojiItem(label: "emoji_2", unicode: "emoji_2", keywords: ["key1", "\(searchString)_123"], shortcodes: ["key1", "key2"], skins: ["🙂"])
let item3WithSearchString = EmojiItem(label: "emoji_2", unicode: "emoji_2", keywords: ["key1", "key1"], shortcodes: ["key1", "\(searchString)_123"], skins: ["🙂"])
let item4WithoutSearchString = EmojiItem(label: "emoji_3", unicode: "emoji_3", keywords: ["key1", "key1"], shortcodes: ["key1", "key1"], skins: ["🙂"])
let item5WithSearchString = EmojiItem(label: "emoji0", unicode: "\(searchString)_123", keywords: ["key1", "key1"], shortcodes: ["key1", "key1"], skins: ["🙂"])
categories.append(EmojiCategory(id: "test",
emojis: [EmojiItem(id: "\(searchString)_123",
name: "emoji0",
keywords: ["key1", "key1"],
skins: ["🙂"]),
EmojiItem(id: "emoji_1",
name: searchString,
keywords: ["key1", "key1"],
skins: ["🙂"]),
EmojiItem(id: "emoji_2",
name: "emoji2",
keywords: ["key1", "\(searchString)_123"],
skins: ["🙂"]),
EmojiItem(id: "emoji_3",
name: "emoji_3",
keywords: ["key1", "key1"],
skins: ["🙂"])]))
emojis: [item0WithSearchString,
item1WithSearchString,
item2WithSearchString,
item3WithSearchString,
item4WithoutSearchString]))
categories.append(EmojiCategory(id: "test",
emojis: [EmojiItem(id: "\(searchString)_123",
name: "emoji0",
keywords: ["key1", "key1"],
skins: ["🙂"])]))
emojis: [item5WithSearchString]))
emojiLoaderMock.categories = categories
_ = await sut.getCategories()
let result = await sut.getCategories(searchString: searchString)
XCTAssertEqual(result.count, 2)
XCTAssertEqual(result.first?.emojis.count, 3)
XCTAssertEqual(result.first?.emojis.count, 4)
}
}
+4
View File
@@ -106,3 +106,7 @@ packages:
Version:
url: https://github.com/mxcl/Version
minorVersion: 2.0.0
Emojibase:
url: https://github.com/matrix-org/emojibase-bindings
minorVersion: 1.0.0