diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index 920db583e..e352de917 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -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 = ""; }; 11151E78D6BB2B04A8FBD389 /* EmojiPickerScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiPickerScreenViewModelProtocol.swift; sourceTree = ""; }; 111B698739E3410E2CDB7144 /* MXLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MXLog.swift; sourceTree = ""; }; - 11F7F3CF7E70518BD7D25E04 /* EmojiMartEmoji.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiMartEmoji.swift; sourceTree = ""; }; 1215A4FC53D2319E81AE8970 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 122186B7CD1BC46A9C629DD9 /* RoomDetailsEditScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsEditScreenUITests.swift; sourceTree = ""; }; 1222DB76B917EB8A55365BA5 /* target.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = target.yml; sourceTree = ""; }; @@ -972,7 +966,6 @@ 37CA26F55123E36B50DB0B3A /* AttributedStringTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributedStringTests.swift; sourceTree = ""; }; 382B50F7E379B3DBBD174364 /* NotificationSettingsProxyMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsProxyMock.swift; sourceTree = ""; }; 38E521D6C2BF8DF0DFB35146 /* DeveloperOptionsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperOptionsScreen.swift; sourceTree = ""; }; - 39001365B76B89983FDB7AD8 /* EmojiMartJSONLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiMartJSONLoader.swift; sourceTree = ""; }; 3948D16F021DFDB2CD26EAA8 /* MockBackgroundTaskService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockBackgroundTaskService.swift; sourceTree = ""; }; 398817652FA8ABAE0A31AC6D /* ReadableFrameModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadableFrameModifier.swift; sourceTree = ""; }; 39B6C8690AEA1E49FF1BAF95 /* MediaUploadPreviewScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaUploadPreviewScreenUITests.swift; sourceTree = ""; }; @@ -1205,7 +1198,6 @@ 8F21ED7205048668BEB44A38 /* AppActivityView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppActivityView.swift; sourceTree = ""; }; 8F61A0DD8243B395499C99A2 /* InvitesScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvitesScreenUITests.swift; sourceTree = ""; }; 8F7D42E66E939B709C1EC390 /* MockRoomSummaryProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockRoomSummaryProvider.swift; sourceTree = ""; }; - 8FC26871038FB0E4AAE22605 /* apple_emojis_data.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = apple_emojis_data.json; sourceTree = ""; }; 8FC803282F9268D49F4ABF14 /* AppCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCoordinator.swift; sourceTree = ""; }; 90A55430639712CFACA34F43 /* TextRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextRoomTimelineItem.swift; sourceTree = ""; }; 90F2F8998E5632668B0AD848 /* RoomTimelineItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineItemView.swift; sourceTree = ""; }; @@ -1236,7 +1228,6 @@ 9B06663F7858E45882E63471 /* StaticLocationScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StaticLocationScreen.swift; sourceTree = ""; }; 9B65A314DF40B6BBF775C2BC /* AnalyticsPromptScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsPromptScreenCoordinator.swift; sourceTree = ""; }; 9B663BE498BB39EADC24025D /* SettingsScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsScreenModels.swift; sourceTree = ""; }; - 9BF9E3E6A23180EC05F06460 /* EmojiMartJSONLoaderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiMartJSONLoaderTests.swift; sourceTree = ""; }; 9C4048041C1A6B20CB97FD18 /* TestMeasurementParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestMeasurementParser.swift; sourceTree = ""; }; 9C5E81214D27A6B898FC397D /* ElementX.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ElementX.entitlements; sourceTree = ""; }; 9C698E30698EC59302A8EEBD /* NavigationStackCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationStackCoordinatorTests.swift; sourceTree = ""; }; @@ -1353,7 +1344,6 @@ C2E9B841EE4878283ECDB554 /* InviteUsersScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InviteUsersScreen.swift; sourceTree = ""; }; C2F079B5DBD0D85FEA687AAE /* SDKGeneratedMocks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SDKGeneratedMocks.swift; sourceTree = ""; }; C352359663A0E52BA20761EE /* LoadableImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadableImage.swift; sourceTree = ""; }; - C38AE3617D7619EF30CDD229 /* EmojiMartStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiMartStore.swift; sourceTree = ""; }; C4C89820BB2B88D4EA28131C /* BugReportScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportScreenViewModelProtocol.swift; sourceTree = ""; }; C54464351F170D570110AFCA /* WelcomeScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeScreen.swift; sourceTree = ""; }; C55D7E514F9DE4E3D72FDCAD /* SessionVerificationControllerProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationControllerProxy.swift; sourceTree = ""; }; @@ -1447,7 +1437,6 @@ E51E3D86A84341C3A0CB8A40 /* FileRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileRoomTimelineView.swift; sourceTree = ""; }; E5272BC4A60B6AD7553BACA1 /* BlurHashDecode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlurHashDecode.swift; sourceTree = ""; }; E55B5EA766E89FF1F87C3ACB /* RoomNotificationSettingsProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomNotificationSettingsProxyProtocol.swift; sourceTree = ""; }; - E5C3AACCAA82392D08924496 /* EmojiMartCategory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiMartCategory.swift; sourceTree = ""; }; E5E94DCFEE803E5ABAE8ACCE /* KeychainControllerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainControllerProtocol.swift; sourceTree = ""; }; E5F2B6443D1ED8602F328539 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ru; path = ru.lproj/Localizable.stringsdict; sourceTree = ""; }; E6281B199D8A8F0892490C2E /* OnboardingCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingCoordinator.swift; sourceTree = ""; }; @@ -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 = ""; @@ -2340,18 +2329,6 @@ path = SoftLogoutScreen; sourceTree = ""; }; - 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 = ""; - }; 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" */; diff --git a/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index f6ebc3bd8..1d9a87e6c 100644 --- a/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -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", diff --git a/ElementX/Sources/Screens/EmojiPickerScreen/EmojiPickerScreenViewModel.swift b/ElementX/Sources/Screens/EmojiPickerScreen/EmojiPickerScreenViewModel.swift index c1aa99d63..ee027604d 100644 --- a/ElementX/Sources/Screens/EmojiPickerScreen/EmojiPickerScreenViewModel.swift +++ b/ElementX/Sources/Screens/EmojiPickerScreen/EmojiPickerScreenViewModel.swift @@ -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) diff --git a/ElementX/Sources/Services/Emojis/EmojiItem.swift b/ElementX/Sources/Services/Emojis/EmojiItem.swift index a6e1e6a60..e3d2cb900 100644 --- a/ElementX/Sources/Services/Emojis/EmojiItem.swift +++ b/ElementX/Sources/Services/Emojis/EmojiItem.swift @@ -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 - } - } -} diff --git a/ElementX/Sources/Services/Emojis/EmojiMart/EmojiMartCategory.swift b/ElementX/Sources/Services/Emojis/EmojiMart/EmojiMartCategory.swift deleted file mode 100644 index 87dbb767b..000000000 --- a/ElementX/Sources/Services/Emojis/EmojiMart/EmojiMartCategory.swift +++ /dev/null @@ -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] -} diff --git a/ElementX/Sources/Services/Emojis/EmojiMart/EmojiMartEmoji.swift b/ElementX/Sources/Services/Emojis/EmojiMart/EmojiMartEmoji.swift deleted file mode 100644 index a08e5d228..000000000 --- a/ElementX/Sources/Services/Emojis/EmojiMart/EmojiMartEmoji.swift +++ /dev/null @@ -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 -} diff --git a/ElementX/Sources/Services/Emojis/EmojiMart/EmojiMartJSONLoader.swift b/ElementX/Sources/Services/Emojis/EmojiMart/EmojiMartJSONLoader.swift deleted file mode 100644 index 15eb1bfa8..000000000 --- a/ElementX/Sources/Services/Emojis/EmojiMart/EmojiMartJSONLoader.swift +++ /dev/null @@ -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) - } - } -} diff --git a/ElementX/Sources/Services/Emojis/EmojiMart/EmojiMartStore.swift b/ElementX/Sources/Services/Emojis/EmojiMart/EmojiMartStore.swift deleted file mode 100644 index 39639ee82..000000000 --- a/ElementX/Sources/Services/Emojis/EmojiMart/EmojiMartStore.swift +++ /dev/null @@ -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) - } -} diff --git a/ElementX/Sources/Services/Emojis/EmojiMart/apple_emojis_data.json b/ElementX/Sources/Services/Emojis/EmojiMart/apple_emojis_data.json deleted file mode 100644 index 403fbc9a7..000000000 --- a/ElementX/Sources/Services/Emojis/EmojiMart/apple_emojis_data.json +++ /dev/null @@ -1,29850 +0,0 @@ -{ - "categories": [{ - "id": "people", - "emojis": ["grinning", "smiley", "smile", "grin", "laughing", "sweat_smile", "rolling_on_the_floor_laughing", "joy", "slightly_smiling_face", "upside_down_face", "melting_face", "wink", "blush", "innocent", "smiling_face_with_3_hearts", "heart_eyes", "star-struck", "kissing_heart", "kissing", "relaxed", "kissing_closed_eyes", "kissing_smiling_eyes", "smiling_face_with_tear", "yum", "stuck_out_tongue", "stuck_out_tongue_winking_eye", "zany_face", "stuck_out_tongue_closed_eyes", "money_mouth_face", "hugging_face", "face_with_hand_over_mouth", "face_with_open_eyes_and_hand_over_mouth", "face_with_peeking_eye", "shushing_face", "thinking_face", "saluting_face", "zipper_mouth_face", "face_with_raised_eyebrow", "neutral_face", "expressionless", "no_mouth", "dotted_line_face", "face_in_clouds", "smirk", "unamused", "face_with_rolling_eyes", "grimacing", "face_exhaling", "lying_face", "relieved", "pensive", "sleepy", "drooling_face", "sleeping", "mask", "face_with_thermometer", "face_with_head_bandage", "nauseated_face", "face_vomiting", "sneezing_face", "hot_face", "cold_face", "woozy_face", "dizzy_face", "face_with_spiral_eyes", "exploding_head", "face_with_cowboy_hat", "partying_face", "disguised_face", "sunglasses", "nerd_face", "face_with_monocle", "confused", "face_with_diagonal_mouth", "worried", "slightly_frowning_face", "white_frowning_face", "open_mouth", "hushed", "astonished", "flushed", "pleading_face", "face_holding_back_tears", "frowning", "anguished", "fearful", "cold_sweat", "disappointed_relieved", "cry", "sob", "scream", "confounded", "persevere", "disappointed", "sweat", "weary", "tired_face", "yawning_face", "triumph", "rage", "angry", "face_with_symbols_on_mouth", "smiling_imp", "imp", "skull", "skull_and_crossbones", "hankey", "clown_face", "japanese_ogre", "japanese_goblin", "ghost", "alien", "space_invader", "robot_face", "wave", "raised_back_of_hand", "raised_hand_with_fingers_splayed", "hand", "spock-hand", "rightwards_hand", "leftwards_hand", "palm_down_hand", "palm_up_hand", "ok_hand", "pinched_fingers", "pinching_hand", "v", "crossed_fingers", "hand_with_index_finger_and_thumb_crossed", "i_love_you_hand_sign", "the_horns", "call_me_hand", "point_left", "point_right", "point_up_2", "middle_finger", "point_down", "point_up", "index_pointing_at_the_viewer", "+1", "-1", "fist", "facepunch", "left-facing_fist", "right-facing_fist", "clap", "raised_hands", "heart_hands", "open_hands", "palms_up_together", "handshake", "pray", "writing_hand", "nail_care", "selfie", "muscle", "mechanical_arm", "mechanical_leg", "leg", "foot", "ear", "ear_with_hearing_aid", "nose", "brain", "anatomical_heart", "lungs", "tooth", "bone", "eyes", "eye", "tongue", "lips", "biting_lip", "baby", "child", "boy", "girl", "adult", "person_with_blond_hair", "man", "bearded_person", "man_with_beard", "woman_with_beard", "red_haired_man", "curly_haired_man", "white_haired_man", "bald_man", "woman", "red_haired_woman", "red_haired_person", "curly_haired_woman", "curly_haired_person", "white_haired_woman", "white_haired_person", "bald_woman", "bald_person", "blond-haired-woman", "blond-haired-man", "older_adult", "older_man", "older_woman", "person_frowning", "man-frowning", "woman-frowning", "person_with_pouting_face", "man-pouting", "woman-pouting", "no_good", "man-gesturing-no", "woman-gesturing-no", "ok_woman", "man-gesturing-ok", "woman-gesturing-ok", "information_desk_person", "man-tipping-hand", "woman-tipping-hand", "raising_hand", "man-raising-hand", "woman-raising-hand", "deaf_person", "deaf_man", "deaf_woman", "bow", "man-bowing", "woman-bowing", "face_palm", "man-facepalming", "woman-facepalming", "shrug", "man-shrugging", "woman-shrugging", "health_worker", "male-doctor", "female-doctor", "student", "male-student", "female-student", "teacher", "male-teacher", "female-teacher", "judge", "male-judge", "female-judge", "farmer", "male-farmer", "female-farmer", "cook", "male-cook", "female-cook", "mechanic", "male-mechanic", "female-mechanic", "factory_worker", "male-factory-worker", "female-factory-worker", "office_worker", "male-office-worker", "female-office-worker", "scientist", "male-scientist", "female-scientist", "technologist", "male-technologist", "female-technologist", "singer", "male-singer", "female-singer", "artist", "male-artist", "female-artist", "pilot", "male-pilot", "female-pilot", "astronaut", "male-astronaut", "female-astronaut", "firefighter", "male-firefighter", "female-firefighter", "cop", "male-police-officer", "female-police-officer", "sleuth_or_spy", "male-detective", "female-detective", "guardsman", "male-guard", "female-guard", "ninja", "construction_worker", "male-construction-worker", "female-construction-worker", "person_with_crown", "prince", "princess", "man_with_turban", "man-wearing-turban", "woman-wearing-turban", "man_with_gua_pi_mao", "person_with_headscarf", "person_in_tuxedo", "man_in_tuxedo", "woman_in_tuxedo", "bride_with_veil", "man_with_veil", "woman_with_veil", "pregnant_woman", "pregnant_man", "pregnant_person", "breast-feeding", "woman_feeding_baby", "man_feeding_baby", "person_feeding_baby", "angel", "santa", "mrs_claus", "mx_claus", "superhero", "male_superhero", "female_superhero", "supervillain", "male_supervillain", "female_supervillain", "mage", "male_mage", "female_mage", "fairy", "male_fairy", "female_fairy", "vampire", "male_vampire", "female_vampire", "merperson", "merman", "mermaid", "elf", "male_elf", "female_elf", "genie", "male_genie", "female_genie", "zombie", "male_zombie", "female_zombie", "troll", "massage", "man-getting-massage", "woman-getting-massage", "haircut", "man-getting-haircut", "woman-getting-haircut", "walking", "man-walking", "woman-walking", "standing_person", "man_standing", "woman_standing", "kneeling_person", "man_kneeling", "woman_kneeling", "person_with_probing_cane", "man_with_probing_cane", "woman_with_probing_cane", "person_in_motorized_wheelchair", "man_in_motorized_wheelchair", "woman_in_motorized_wheelchair", "person_in_manual_wheelchair", "man_in_manual_wheelchair", "woman_in_manual_wheelchair", "runner", "man-running", "woman-running", "dancer", "man_dancing", "man_in_business_suit_levitating", "dancers", "men-with-bunny-ears-partying", "women-with-bunny-ears-partying", "person_in_steamy_room", "man_in_steamy_room", "woman_in_steamy_room", "person_climbing", "man_climbing", "woman_climbing", "fencer", "horse_racing", "skier", "snowboarder", "golfer", "man-golfing", "woman-golfing", "surfer", "man-surfing", "woman-surfing", "rowboat", "man-rowing-boat", "woman-rowing-boat", "swimmer", "man-swimming", "woman-swimming", "person_with_ball", "man-bouncing-ball", "woman-bouncing-ball", "weight_lifter", "man-lifting-weights", "woman-lifting-weights", "bicyclist", "man-biking", "woman-biking", "mountain_bicyclist", "man-mountain-biking", "woman-mountain-biking", "person_doing_cartwheel", "man-cartwheeling", "woman-cartwheeling", "wrestlers", "man-wrestling", "woman-wrestling", "water_polo", "man-playing-water-polo", "woman-playing-water-polo", "handball", "man-playing-handball", "woman-playing-handball", "juggling", "man-juggling", "woman-juggling", "person_in_lotus_position", "man_in_lotus_position", "woman_in_lotus_position", "bath", "sleeping_accommodation", "people_holding_hands", "two_women_holding_hands", "man_and_woman_holding_hands", "two_men_holding_hands", "couplekiss", "woman-kiss-man", "man-kiss-man", "woman-kiss-woman", "couple_with_heart", "woman-heart-man", "man-heart-man", "woman-heart-woman", "family", "man-woman-boy", "man-woman-girl", "man-woman-girl-boy", "man-woman-boy-boy", "man-woman-girl-girl", "man-man-boy", "man-man-girl", "man-man-girl-boy", "man-man-boy-boy", "man-man-girl-girl", "woman-woman-boy", "woman-woman-girl", "woman-woman-girl-boy", "woman-woman-boy-boy", "woman-woman-girl-girl", "man-boy", "man-boy-boy", "man-girl", "man-girl-boy", "man-girl-girl", "woman-boy", "woman-boy-boy", "woman-girl", "woman-girl-boy", "woman-girl-girl", "speaking_head_in_silhouette", "bust_in_silhouette", "busts_in_silhouette", "people_hugging", "footprints", "smiley_cat", "smile_cat", "joy_cat", "heart_eyes_cat", "smirk_cat", "kissing_cat", "scream_cat", "crying_cat_face", "pouting_cat", "see_no_evil", "hear_no_evil", "speak_no_evil", "kiss", "love_letter", "cupid", "gift_heart", "sparkling_heart", "heartpulse", "heartbeat", "revolving_hearts", "two_hearts", "heart_decoration", "heavy_heart_exclamation_mark_ornament", "broken_heart", "heart_on_fire", "mending_heart", "heart", "orange_heart", "yellow_heart", "green_heart", "blue_heart", "purple_heart", "brown_heart", "black_heart", "white_heart", "100", "anger", "boom", "dizzy", "sweat_drops", "dash", "hole", "bomb", "speech_balloon", "eye-in-speech-bubble", "left_speech_bubble", "right_anger_bubble", "thought_balloon", "zzz"] - }, { - "id": "nature", - "emojis": ["monkey_face", "monkey", "gorilla", "orangutan", "dog", "dog2", "guide_dog", "service_dog", "poodle", "wolf", "fox_face", "raccoon", "cat", "cat2", "black_cat", "lion_face", "tiger", "tiger2", "leopard", "horse", "racehorse", "unicorn_face", "zebra_face", "deer", "bison", "cow", "ox", "water_buffalo", "cow2", "pig", "pig2", "boar", "pig_nose", "ram", "sheep", "goat", "dromedary_camel", "camel", "llama", "giraffe_face", "elephant", "mammoth", "rhinoceros", "hippopotamus", "mouse", "mouse2", "rat", "hamster", "rabbit", "rabbit2", "chipmunk", "beaver", "hedgehog", "bat", "bear", "polar_bear", "koala", "panda_face", "sloth", "otter", "skunk", "kangaroo", "badger", "feet", "turkey", "chicken", "rooster", "hatching_chick", "baby_chick", "hatched_chick", "bird", "penguin", "dove_of_peace", "eagle", "duck", "swan", "owl", "dodo", "feather", "flamingo", "peacock", "parrot", "frog", "crocodile", "turtle", "lizard", "snake", "dragon_face", "dragon", "sauropod", "t-rex", "whale", "whale2", "dolphin", "seal", "fish", "tropical_fish", "blowfish", "shark", "octopus", "shell", "coral", "snail", "butterfly", "bug", "ant", "bee", "beetle", "ladybug", "cricket", "cockroach", "spider", "spider_web", "scorpion", "mosquito", "fly", "worm", "microbe", "bouquet", "cherry_blossom", "white_flower", "lotus", "rosette", "rose", "wilted_flower", "hibiscus", "sunflower", "blossom", "tulip", "seedling", "potted_plant", "evergreen_tree", "deciduous_tree", "palm_tree", "cactus", "ear_of_rice", "herb", "shamrock", "four_leaf_clover", "maple_leaf", "fallen_leaf", "leaves", "empty_nest", "nest_with_eggs"] - }, { - "id": "foods", - "emojis": ["grapes", "melon", "watermelon", "tangerine", "lemon", "banana", "pineapple", "mango", "apple", "green_apple", "pear", "peach", "cherries", "strawberry", "blueberries", "kiwifruit", "tomato", "olive", "coconut", "avocado", "eggplant", "potato", "carrot", "corn", "hot_pepper", "bell_pepper", "cucumber", "leafy_green", "broccoli", "garlic", "onion", "mushroom", "peanuts", "beans", "chestnut", "bread", "croissant", "baguette_bread", "flatbread", "pretzel", "bagel", "pancakes", "waffle", "cheese_wedge", "meat_on_bone", "poultry_leg", "cut_of_meat", "bacon", "hamburger", "fries", "pizza", "hotdog", "sandwich", "taco", "burrito", "tamale", "stuffed_flatbread", "falafel", "egg", "fried_egg", "shallow_pan_of_food", "stew", "fondue", "bowl_with_spoon", "green_salad", "popcorn", "butter", "salt", "canned_food", "bento", "rice_cracker", "rice_ball", "rice", "curry", "ramen", "spaghetti", "sweet_potato", "oden", "sushi", "fried_shrimp", "fish_cake", "moon_cake", "dango", "dumpling", "fortune_cookie", "takeout_box", "crab", "lobster", "shrimp", "squid", "oyster", "icecream", "shaved_ice", "ice_cream", "doughnut", "cookie", "birthday", "cake", "cupcake", "pie", "chocolate_bar", "candy", "lollipop", "custard", "honey_pot", "baby_bottle", "glass_of_milk", "coffee", "teapot", "tea", "sake", "champagne", "wine_glass", "cocktail", "tropical_drink", "beer", "beers", "clinking_glasses", "tumbler_glass", "pouring_liquid", "cup_with_straw", "bubble_tea", "beverage_box", "mate_drink", "ice_cube", "chopsticks", "knife_fork_plate", "fork_and_knife", "spoon", "hocho", "jar", "amphora"] - }, { - "id": "activity", - "emojis": ["jack_o_lantern", "christmas_tree", "fireworks", "sparkler", "firecracker", "sparkles", "balloon", "tada", "confetti_ball", "tanabata_tree", "bamboo", "dolls", "flags", "wind_chime", "rice_scene", "red_envelope", "ribbon", "gift", "reminder_ribbon", "admission_tickets", "ticket", "medal", "trophy", "sports_medal", "first_place_medal", "second_place_medal", "third_place_medal", "soccer", "baseball", "softball", "basketball", "volleyball", "football", "rugby_football", "tennis", "flying_disc", "bowling", "cricket_bat_and_ball", "field_hockey_stick_and_ball", "ice_hockey_stick_and_puck", "lacrosse", "table_tennis_paddle_and_ball", "badminton_racquet_and_shuttlecock", "boxing_glove", "martial_arts_uniform", "goal_net", "golf", "ice_skate", "fishing_pole_and_fish", "diving_mask", "running_shirt_with_sash", "ski", "sled", "curling_stone", "dart", "yo-yo", "kite", "8ball", "crystal_ball", "magic_wand", "nazar_amulet", "hamsa", "video_game", "joystick", "slot_machine", "game_die", "jigsaw", "teddy_bear", "pinata", "mirror_ball", "nesting_dolls", "spades", "hearts", "diamonds", "clubs", "chess_pawn", "black_joker", "mahjong", "flower_playing_cards", "performing_arts", "frame_with_picture", "art", "thread", "sewing_needle", "yarn", "knot"] - }, { - "id": "places", - "emojis": ["earth_africa", "earth_americas", "earth_asia", "globe_with_meridians", "world_map", "japan", "compass", "snow_capped_mountain", "mountain", "volcano", "mount_fuji", "camping", "beach_with_umbrella", "desert", "desert_island", "national_park", "stadium", "classical_building", "building_construction", "bricks", "rock", "wood", "hut", "house_buildings", "derelict_house_building", "house", "house_with_garden", "office", "post_office", "european_post_office", "hospital", "bank", "hotel", "love_hotel", "convenience_store", "school", "department_store", "factory", "japanese_castle", "european_castle", "wedding", "tokyo_tower", "statue_of_liberty", "church", "mosque", "hindu_temple", "synagogue", "shinto_shrine", "kaaba", "fountain", "tent", "foggy", "night_with_stars", "cityscape", "sunrise_over_mountains", "sunrise", "city_sunset", "city_sunrise", "bridge_at_night", "hotsprings", "carousel_horse", "playground_slide", "ferris_wheel", "roller_coaster", "barber", "circus_tent", "steam_locomotive", "railway_car", "bullettrain_side", "bullettrain_front", "train2", "metro", "light_rail", "station", "tram", "monorail", "mountain_railway", "train", "bus", "oncoming_bus", "trolleybus", "minibus", "ambulance", "fire_engine", "police_car", "oncoming_police_car", "taxi", "oncoming_taxi", "car", "oncoming_automobile", "blue_car", "pickup_truck", "truck", "articulated_lorry", "tractor", "racing_car", "racing_motorcycle", "motor_scooter", "manual_wheelchair", "motorized_wheelchair", "auto_rickshaw", "bike", "scooter", "skateboard", "roller_skate", "busstop", "motorway", "railway_track", "oil_drum", "fuelpump", "wheel", "rotating_light", "traffic_light", "vertical_traffic_light", "octagonal_sign", "construction", "anchor", "ring_buoy", "boat", "canoe", "speedboat", "passenger_ship", "ferry", "motor_boat", "ship", "airplane", "small_airplane", "airplane_departure", "airplane_arriving", "parachute", "seat", "helicopter", "suspension_railway", "mountain_cableway", "aerial_tramway", "satellite", "rocket", "flying_saucer", "bellhop_bell", "luggage", "hourglass", "hourglass_flowing_sand", "watch", "alarm_clock", "stopwatch", "timer_clock", "mantelpiece_clock", "clock12", "clock1230", "clock1", "clock130", "clock2", "clock230", "clock3", "clock330", "clock4", "clock430", "clock5", "clock530", "clock6", "clock630", "clock7", "clock730", "clock8", "clock830", "clock9", "clock930", "clock10", "clock1030", "clock11", "clock1130", "new_moon", "waxing_crescent_moon", "first_quarter_moon", "moon", "full_moon", "waning_gibbous_moon", "last_quarter_moon", "waning_crescent_moon", "crescent_moon", "new_moon_with_face", "first_quarter_moon_with_face", "last_quarter_moon_with_face", "thermometer", "sunny", "full_moon_with_face", "sun_with_face", "ringed_planet", "star", "star2", "stars", "milky_way", "cloud", "partly_sunny", "thunder_cloud_and_rain", "mostly_sunny", "barely_sunny", "partly_sunny_rain", "rain_cloud", "snow_cloud", "lightning", "tornado", "fog", "wind_blowing_face", "cyclone", "rainbow", "closed_umbrella", "umbrella", "umbrella_with_rain_drops", "umbrella_on_ground", "zap", "snowflake", "snowman", "snowman_without_snow", "comet", "fire", "droplet", "ocean"] - }, { - "id": "objects", - "emojis": ["eyeglasses", "dark_sunglasses", "goggles", "lab_coat", "safety_vest", "necktie", "shirt", "jeans", "scarf", "gloves", "coat", "socks", "dress", "kimono", "sari", "one-piece_swimsuit", "briefs", "shorts", "bikini", "womans_clothes", "purse", "handbag", "pouch", "shopping_bags", "school_satchel", "thong_sandal", "mans_shoe", "athletic_shoe", "hiking_boot", "womans_flat_shoe", "high_heel", "sandal", "ballet_shoes", "boot", "crown", "womans_hat", "tophat", "mortar_board", "billed_cap", "military_helmet", "helmet_with_white_cross", "prayer_beads", "lipstick", "ring", "gem", "mute", "speaker", "sound", "loud_sound", "loudspeaker", "mega", "postal_horn", "bell", "no_bell", "musical_score", "musical_note", "notes", "studio_microphone", "level_slider", "control_knobs", "microphone", "headphones", "radio", "saxophone", "accordion", "guitar", "musical_keyboard", "trumpet", "violin", "banjo", "drum_with_drumsticks", "long_drum", "iphone", "calling", "phone", "telephone_receiver", "pager", "fax", "battery", "low_battery", "electric_plug", "computer", "desktop_computer", "printer", "keyboard", "three_button_mouse", "trackball", "minidisc", "floppy_disk", "cd", "dvd", "abacus", "movie_camera", "film_frames", "film_projector", "clapper", "tv", "camera", "camera_with_flash", "video_camera", "vhs", "mag", "mag_right", "candle", "bulb", "flashlight", "izakaya_lantern", "diya_lamp", "notebook_with_decorative_cover", "closed_book", "book", "green_book", "blue_book", "orange_book", "books", "notebook", "ledger", "page_with_curl", "scroll", "page_facing_up", "newspaper", "rolled_up_newspaper", "bookmark_tabs", "bookmark", "label", "moneybag", "coin", "yen", "dollar", "euro", "pound", "money_with_wings", "credit_card", "receipt", "chart", "email", "e-mail", "incoming_envelope", "envelope_with_arrow", "outbox_tray", "inbox_tray", "package", "mailbox", "mailbox_closed", "mailbox_with_mail", "mailbox_with_no_mail", "postbox", "ballot_box_with_ballot", "pencil2", "black_nib", "lower_left_fountain_pen", "lower_left_ballpoint_pen", "lower_left_paintbrush", "lower_left_crayon", "memo", "briefcase", "file_folder", "open_file_folder", "card_index_dividers", "date", "calendar", "spiral_note_pad", "spiral_calendar_pad", "card_index", "chart_with_upwards_trend", "chart_with_downwards_trend", "bar_chart", "clipboard", "pushpin", "round_pushpin", "paperclip", "linked_paperclips", "straight_ruler", "triangular_ruler", "scissors", "card_file_box", "file_cabinet", "wastebasket", "lock", "unlock", "lock_with_ink_pen", "closed_lock_with_key", "key", "old_key", "hammer", "axe", "pick", "hammer_and_pick", "hammer_and_wrench", "dagger_knife", "crossed_swords", "gun", "boomerang", "bow_and_arrow", "shield", "carpentry_saw", "wrench", "screwdriver", "nut_and_bolt", "gear", "compression", "scales", "probing_cane", "link", "chains", "hook", "toolbox", "magnet", "ladder", "alembic", "test_tube", "petri_dish", "dna", "microscope", "telescope", "satellite_antenna", "syringe", "drop_of_blood", "pill", "adhesive_bandage", "crutch", "stethoscope", "x-ray", "door", "elevator", "mirror", "window", "bed", "couch_and_lamp", "chair", "toilet", "plunger", "shower", "bathtub", "mouse_trap", "razor", "lotion_bottle", "safety_pin", "broom", "basket", "roll_of_paper", "bucket", "soap", "bubbles", "toothbrush", "sponge", "fire_extinguisher", "shopping_trolley", "smoking", "coffin", "headstone", "funeral_urn", "moyai", "placard", "identification_card"] - }, { - "id": "symbols", - "emojis": ["atm", "put_litter_in_its_place", "potable_water", "wheelchair", "mens", "womens", "restroom", "baby_symbol", "wc", "passport_control", "customs", "baggage_claim", "left_luggage", "warning", "children_crossing", "no_entry", "no_entry_sign", "no_bicycles", "no_smoking", "do_not_litter", "non-potable_water", "no_pedestrians", "no_mobile_phones", "underage", "radioactive_sign", "biohazard_sign", "arrow_up", "arrow_upper_right", "arrow_right", "arrow_lower_right", "arrow_down", "arrow_lower_left", "arrow_left", "arrow_upper_left", "arrow_up_down", "left_right_arrow", "leftwards_arrow_with_hook", "arrow_right_hook", "arrow_heading_up", "arrow_heading_down", "arrows_clockwise", "arrows_counterclockwise", "back", "end", "on", "soon", "top", "place_of_worship", "atom_symbol", "om_symbol", "star_of_david", "wheel_of_dharma", "yin_yang", "latin_cross", "orthodox_cross", "star_and_crescent", "peace_symbol", "menorah_with_nine_branches", "six_pointed_star", "aries", "taurus", "gemini", "cancer", "leo", "virgo", "libra", "scorpius", "sagittarius", "capricorn", "aquarius", "pisces", "ophiuchus", "twisted_rightwards_arrows", "repeat", "repeat_one", "arrow_forward", "fast_forward", "black_right_pointing_double_triangle_with_vertical_bar", "black_right_pointing_triangle_with_double_vertical_bar", "arrow_backward", "rewind", "black_left_pointing_double_triangle_with_vertical_bar", "arrow_up_small", "arrow_double_up", "arrow_down_small", "arrow_double_down", "double_vertical_bar", "black_square_for_stop", "black_circle_for_record", "eject", "cinema", "low_brightness", "high_brightness", "signal_strength", "vibration_mode", "mobile_phone_off", "transgender_symbol", "heavy_multiplication_x", "heavy_plus_sign", "heavy_minus_sign", "heavy_division_sign", "heavy_equals_sign", "infinity", "bangbang", "interrobang", "question", "grey_question", "grey_exclamation", "exclamation", "wavy_dash", "currency_exchange", "heavy_dollar_sign", "recycle", "fleur_de_lis", "trident", "name_badge", "beginner", "o", "white_check_mark", "ballot_box_with_check", "heavy_check_mark", "x", "negative_squared_cross_mark", "curly_loop", "loop", "part_alternation_mark", "eight_spoked_asterisk", "eight_pointed_black_star", "sparkle", "copyright", "registered", "tm", "hash", "keycap_star", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "keycap_ten", "capital_abcd", "abcd", "1234", "symbols", "abc", "a", "ab", "b", "cl", "cool", "free", "information_source", "id", "m", "new", "ng", "o2", "ok", "parking", "sos", "up", "vs", "koko", "sa", "u6708", "u6709", "u6307", "ideograph_advantage", "u5272", "u7121", "u7981", "accept", "u7533", "u5408", "u7a7a", "congratulations", "secret", "u55b6", "u6e80", "red_circle", "large_orange_circle", "large_yellow_circle", "large_green_circle", "large_blue_circle", "large_purple_circle", "large_brown_circle", "black_circle", "white_circle", "large_red_square", "large_orange_square", "large_yellow_square", "large_green_square", "large_blue_square", "large_purple_square", "large_brown_square", "black_large_square", "white_large_square", "black_medium_square", "white_medium_square", "black_medium_small_square", "white_medium_small_square", "black_small_square", "white_small_square", "large_orange_diamond", "large_blue_diamond", "small_orange_diamond", "small_blue_diamond", "small_red_triangle", "small_red_triangle_down", "diamond_shape_with_a_dot_inside", "radio_button", "white_square_button", "black_square_button"] - }, { - "id": "flags", - "emojis": ["checkered_flag", "cn", "crossed_flags", "de", "es", "flag-ac", "flag-ad", "flag-ae", "flag-af", "flag-ag", "flag-ai", "flag-al", "flag-am", "flag-ao", "flag-aq", "flag-ar", "flag-as", "flag-at", "flag-au", "flag-aw", "flag-ax", "flag-az", "flag-ba", "flag-bb", "flag-bd", "flag-be", "flag-bf", "flag-bg", "flag-bh", "flag-bi", "flag-bj", "flag-bl", "flag-bm", "flag-bn", "flag-bo", "flag-bq", "flag-br", "flag-bs", "flag-bt", "flag-bv", "flag-bw", "flag-by", "flag-bz", "flag-ca", "flag-cc", "flag-cd", "flag-cf", "flag-cg", "flag-ch", "flag-ci", "flag-ck", "flag-cl", "flag-cm", "flag-co", "flag-cp", "flag-cr", "flag-cu", "flag-cv", "flag-cw", "flag-cx", "flag-cy", "flag-cz", "flag-dg", "flag-dj", "flag-dk", "flag-dm", "flag-do", "flag-dz", "flag-ea", "flag-ec", "flag-ee", "flag-eg", "flag-eh", "flag-england", "flag-er", "flag-et", "flag-eu", "flag-fi", "flag-fj", "flag-fk", "flag-fm", "flag-fo", "flag-ga", "flag-gd", "flag-ge", "flag-gf", "flag-gg", "flag-gh", "flag-gi", "flag-gl", "flag-gm", "flag-gn", "flag-gp", "flag-gq", "flag-gr", "flag-gs", "flag-gt", "flag-gu", "flag-gw", "flag-gy", "flag-hk", "flag-hm", "flag-hn", "flag-hr", "flag-ht", "flag-hu", "flag-ic", "flag-id", "flag-ie", "flag-il", "flag-im", "flag-in", "flag-io", "flag-iq", "flag-ir", "flag-is", "flag-je", "flag-jm", "flag-jo", "flag-ke", "flag-kg", "flag-kh", "flag-ki", "flag-km", "flag-kn", "flag-kp", "flag-kw", "flag-ky", "flag-kz", "flag-la", "flag-lb", "flag-lc", "flag-li", "flag-lk", "flag-lr", "flag-ls", "flag-lt", "flag-lu", "flag-lv", "flag-ly", "flag-ma", "flag-mc", "flag-md", "flag-me", "flag-mf", "flag-mg", "flag-mh", "flag-mk", "flag-ml", "flag-mm", "flag-mn", "flag-mo", "flag-mp", "flag-mq", "flag-mr", "flag-ms", "flag-mt", "flag-mu", "flag-mv", "flag-mw", "flag-mx", "flag-my", "flag-mz", "flag-na", "flag-nc", "flag-ne", "flag-nf", "flag-ng", "flag-ni", "flag-nl", "flag-no", "flag-np", "flag-nr", "flag-nu", "flag-nz", "flag-om", "flag-pa", "flag-pe", "flag-pf", "flag-pg", "flag-ph", "flag-pk", "flag-pl", "flag-pm", "flag-pn", "flag-pr", "flag-ps", "flag-pt", "flag-pw", "flag-py", "flag-qa", "flag-re", "flag-ro", "flag-rs", "flag-rw", "flag-sa", "flag-sb", "flag-sc", "flag-scotland", "flag-sd", "flag-se", "flag-sg", "flag-sh", "flag-si", "flag-sj", "flag-sk", "flag-sl", "flag-sm", "flag-sn", "flag-so", "flag-sr", "flag-ss", "flag-st", "flag-sv", "flag-sx", "flag-sy", "flag-sz", "flag-ta", "flag-tc", "flag-td", "flag-tf", "flag-tg", "flag-th", "flag-tj", "flag-tk", "flag-tl", "flag-tm", "flag-tn", "flag-to", "flag-tr", "flag-tt", "flag-tv", "flag-tw", "flag-tz", "flag-ua", "flag-ug", "flag-um", "flag-un", "flag-uy", "flag-uz", "flag-va", "flag-vc", "flag-ve", "flag-vg", "flag-vi", "flag-vn", "flag-vu", "flag-wales", "flag-wf", "flag-ws", "flag-xk", "flag-ye", "flag-yt", "flag-za", "flag-zm", "flag-zw", "fr", "gb", "it", "jp", "kr", "pirate_flag", "rainbow-flag", "ru", "transgender_flag", "triangular_flag_on_post", "us", "waving_black_flag", "waving_white_flag"] - }], - "emojis": { - "100": { - "id": "100", - "name": "Hundred Points", - "keywords": ["100", "score", "perfect", "numbers", "century", "exam", "quiz", "test", "pass"], - "skins": [{ - "unified": "1f4af", - "native": "๐Ÿ’ฏ", - "x": 28, - "y": 6 - }], - "version": 1 - }, - "1234": { - "id": "1234", - "name": "Input Numbers", - "keywords": ["1234", "blue", "square"], - "skins": [{ - "unified": "1f522", - "native": "๐Ÿ”ข", - "x": 29, - "y": 59 - }], - "version": 1 - }, - "grinning": { - "id": "grinning", - "name": "Grinning Face", - "emoticons": [":D"], - "keywords": ["smile", "happy", "joy", ":D", "grin"], - "skins": [{ - "unified": "1f600", - "native": "๐Ÿ˜€", - "x": 32, - "y": 20 - }], - "version": 1 - }, - "smiley": { - "id": "smiley", - "name": "Grinning Face with Big Eyes", - "emoticons": [":)", "=)", "=-)"], - "keywords": ["smiley", "happy", "joy", "haha", ":D", ":)", "smile", "funny"], - "skins": [{ - "unified": "1f603", - "native": "๐Ÿ˜ƒ", - "x": 32, - "y": 23 - }], - "version": 1 - }, - "smile": { - "id": "smile", - "name": "Grinning Face with Smiling Eyes", - "emoticons": [":)", "C:", "c:", ":D", ":-D"], - "keywords": ["smile", "happy", "joy", "funny", "haha", "laugh", "like", ":D", ":)"], - "skins": [{ - "unified": "1f604", - "native": "๐Ÿ˜„", - "x": 32, - "y": 24 - }], - "version": 1 - }, - "grin": { - "id": "grin", - "name": "Beaming Face with Smiling Eyes", - "keywords": ["grin", "happy", "smile", "joy", "kawaii"], - "skins": [{ - "unified": "1f601", - "native": "๐Ÿ˜", - "x": 32, - "y": 21 - }], - "version": 1 - }, - "laughing": { - "id": "laughing", - "name": "Grinning Squinting Face", - "emoticons": [":>", ":->"], - "keywords": ["laughing", "satisfied", "happy", "joy", "lol", "haha", "glad", "XD", "laugh"], - "skins": [{ - "unified": "1f606", - "native": "๐Ÿ˜†", - "x": 32, - "y": 26 - }], - "version": 1 - }, - "sweat_smile": { - "id": "sweat_smile", - "name": "Grinning Face with Sweat", - "keywords": ["smile", "hot", "happy", "laugh", "relief"], - "skins": [{ - "unified": "1f605", - "native": "๐Ÿ˜…", - "x": 32, - "y": 25 - }], - "version": 1 - }, - "rolling_on_the_floor_laughing": { - "id": "rolling_on_the_floor_laughing", - "name": "Rolling on the Floor Laughing", - "keywords": ["face", "lol", "haha", "rofl"], - "skins": [{ - "unified": "1f923", - "native": "๐Ÿคฃ", - "x": 40, - "y": 15 - }], - "version": 3 - }, - "joy": { - "id": "joy", - "name": "Face with Tears of Joy", - "keywords": ["cry", "weep", "happy", "happytears", "haha"], - "skins": [{ - "unified": "1f602", - "native": "๐Ÿ˜‚", - "x": 32, - "y": 22 - }], - "version": 1 - }, - "slightly_smiling_face": { - "id": "slightly_smiling_face", - "name": "Slightly Smiling Face", - "emoticons": [":)", "(:", ":-)"], - "keywords": ["smile"], - "skins": [{ - "unified": "1f642", - "native": "๐Ÿ™‚", - "x": 33, - "y": 28 - }], - "version": 1 - }, - "upside_down_face": { - "id": "upside_down_face", - "name": "Upside-Down Face", - "keywords": ["upside", "down", "flipped", "silly", "smile"], - "skins": [{ - "unified": "1f643", - "native": "๐Ÿ™ƒ", - "x": 33, - "y": 29 - }], - "version": 1 - }, - "melting_face": { - "id": "melting_face", - "name": "Melting Face", - "keywords": ["hot", "heat"], - "skins": [{ - "unified": "1fae0", - "native": "๐Ÿซ ", - "x": 55, - "y": 12 - }], - "version": 14 - }, - "wink": { - "id": "wink", - "name": "Winking Face", - "emoticons": [";)", ";-)"], - "keywords": ["wink", "happy", "mischievous", "secret", ";)", "smile", "eye"], - "skins": [{ - "unified": "1f609", - "native": "๐Ÿ˜‰", - "x": 32, - "y": 29 - }], - "version": 1 - }, - "blush": { - "id": "blush", - "name": "Smiling Face with Smiling Eyes", - "emoticons": [":)"], - "keywords": ["blush", "smile", "happy", "flushed", "crush", "embarrassed", "shy", "joy"], - "skins": [{ - "unified": "1f60a", - "native": "๐Ÿ˜Š", - "x": 32, - "y": 30 - }], - "version": 1 - }, - "innocent": { - "id": "innocent", - "name": "Smiling Face with Halo", - "keywords": ["innocent", "angel", "heaven"], - "skins": [{ - "unified": "1f607", - "native": "๐Ÿ˜‡", - "x": 32, - "y": 27 - }], - "version": 1 - }, - "smiling_face_with_3_hearts": { - "id": "smiling_face_with_3_hearts", - "name": "Smiling Face with Hearts", - "keywords": ["3", "love", "like", "affection", "valentines", "infatuation", "crush", "adore"], - "skins": [{ - "unified": "1f970", - "native": "๐Ÿฅฐ", - "x": 43, - "y": 58 - }], - "version": 11 - }, - "heart_eyes": { - "id": "heart_eyes", - "name": "Smiling Face with Heart-Eyes", - "keywords": ["heart", "eyes", "love", "like", "affection", "valentines", "infatuation", "crush"], - "skins": [{ - "unified": "1f60d", - "native": "๐Ÿ˜", - "x": 32, - "y": 33 - }], - "version": 1 - }, - "star-struck": { - "id": "star-struck", - "name": "Star-Struck", - "keywords": ["star", "struck", "grinning", "face", "with", "eyes", "smile", "starry"], - "skins": [{ - "unified": "1f929", - "native": "๐Ÿคฉ", - "x": 40, - "y": 38 - }], - "version": 5 - }, - "kissing_heart": { - "id": "kissing_heart", - "name": "Face Blowing a Kiss", - "emoticons": [":*", ":-*"], - "keywords": ["kissing", "heart", "love", "like", "affection", "valentines", "infatuation"], - "skins": [{ - "unified": "1f618", - "native": "๐Ÿ˜˜", - "x": 32, - "y": 44 - }], - "version": 1 - }, - "kissing": { - "id": "kissing", - "name": "Kissing Face", - "keywords": ["love", "like", "3", "valentines", "infatuation", "kiss"], - "skins": [{ - "unified": "1f617", - "native": "๐Ÿ˜—", - "x": 32, - "y": 43 - }], - "version": 1 - }, - "relaxed": { - "id": "relaxed", - "name": "Smiling Face", - "keywords": ["relaxed", "blush", "massage", "happiness"], - "skins": [{ - "unified": "263a-fe0f", - "native": "โ˜บ๏ธ", - "x": 57, - "y": 4 - }], - "version": 1 - }, - "kissing_closed_eyes": { - "id": "kissing_closed_eyes", - "name": "Kissing Face with Closed Eyes", - "keywords": ["love", "like", "affection", "valentines", "infatuation", "kiss"], - "skins": [{ - "unified": "1f61a", - "native": "๐Ÿ˜š", - "x": 32, - "y": 46 - }], - "version": 1 - }, - "kissing_smiling_eyes": { - "id": "kissing_smiling_eyes", - "name": "Kissing Face with Smiling Eyes", - "keywords": ["affection", "valentines", "infatuation", "kiss"], - "skins": [{ - "unified": "1f619", - "native": "๐Ÿ˜™", - "x": 32, - "y": 45 - }], - "version": 1 - }, - "smiling_face_with_tear": { - "id": "smiling_face_with_tear", - "name": "Smiling Face with Tear", - "keywords": ["sad", "cry", "pretend"], - "skins": [{ - "unified": "1f972", - "native": "๐Ÿฅฒ", - "x": 43, - "y": 60 - }], - "version": 13 - }, - "yum": { - "id": "yum", - "name": "Face Savoring Food", - "keywords": ["yum", "happy", "joy", "tongue", "smile", "silly", "yummy", "nom", "delicious", "savouring"], - "skins": [{ - "unified": "1f60b", - "native": "๐Ÿ˜‹", - "x": 32, - "y": 31 - }], - "version": 1 - }, - "stuck_out_tongue": { - "id": "stuck_out_tongue", - "name": "Face with Tongue", - "emoticons": [":p", ":-p", ":P", ":-P", ":b", ":-b"], - "keywords": ["stuck", "out", "prank", "childish", "playful", "mischievous", "smile"], - "skins": [{ - "unified": "1f61b", - "native": "๐Ÿ˜›", - "x": 32, - "y": 47 - }], - "version": 1 - }, - "stuck_out_tongue_winking_eye": { - "id": "stuck_out_tongue_winking_eye", - "name": "Winking Face with Tongue", - "emoticons": [";p", ";-p", ";b", ";-b", ";P", ";-P"], - "keywords": ["stuck", "out", "eye", "prank", "childish", "playful", "mischievous", "smile", "wink"], - "skins": [{ - "unified": "1f61c", - "native": "๐Ÿ˜œ", - "x": 32, - "y": 48 - }], - "version": 1 - }, - "zany_face": { - "id": "zany_face", - "name": "Zany Face", - "keywords": ["grinning", "with", "one", "large", "and", "small", "eye", "goofy", "crazy"], - "skins": [{ - "unified": "1f92a", - "native": "๐Ÿคช", - "x": 40, - "y": 39 - }], - "version": 5 - }, - "stuck_out_tongue_closed_eyes": { - "id": "stuck_out_tongue_closed_eyes", - "name": "Squinting Face with Tongue", - "keywords": ["stuck", "out", "closed", "eyes", "prank", "playful", "mischievous", "smile"], - "skins": [{ - "unified": "1f61d", - "native": "๐Ÿ˜", - "x": 32, - "y": 49 - }], - "version": 1 - }, - "money_mouth_face": { - "id": "money_mouth_face", - "name": "Money-Mouth Face", - "keywords": ["money", "mouth", "rich", "dollar"], - "skins": [{ - "unified": "1f911", - "native": "๐Ÿค‘", - "x": 38, - "y": 59 - }], - "version": 1 - }, - "hugging_face": { - "id": "hugging_face", - "name": "Hugging Face", - "keywords": ["smile", "hug"], - "skins": [{ - "unified": "1f917", - "native": "๐Ÿค—", - "x": 39, - "y": 4 - }], - "version": 1 - }, - "face_with_hand_over_mouth": { - "id": "face_with_hand_over_mouth", - "name": "Face with Hand over Mouth", - "keywords": ["smiling", "eyes", "and", "covering", "whoops", "shock", "surprise"], - "skins": [{ - "unified": "1f92d", - "native": "๐Ÿคญ", - "x": 40, - "y": 42 - }], - "version": 5 - }, - "face_with_open_eyes_and_hand_over_mouth": { - "id": "face_with_open_eyes_and_hand_over_mouth", - "name": "Face with Open Eyes and Hand over Mouth", - "keywords": ["silence", "secret", "shock", "surprise"], - "skins": [{ - "unified": "1fae2", - "native": "๐Ÿซข", - "x": 55, - "y": 14 - }], - "version": 14 - }, - "face_with_peeking_eye": { - "id": "face_with_peeking_eye", - "name": "Face with Peeking Eye", - "keywords": ["scared", "frightening", "embarrassing"], - "skins": [{ - "unified": "1fae3", - "native": "๐Ÿซฃ", - "x": 55, - "y": 15 - }], - "version": 14 - }, - "shushing_face": { - "id": "shushing_face", - "name": "Shushing Face", - "keywords": ["with", "finger", "covering", "closed", "lips", "quiet", "shhh"], - "skins": [{ - "unified": "1f92b", - "native": "๐Ÿคซ", - "x": 40, - "y": 40 - }], - "version": 5 - }, - "thinking_face": { - "id": "thinking_face", - "name": "Thinking Face", - "keywords": ["hmmm", "think", "consider"], - "skins": [{ - "unified": "1f914", - "native": "๐Ÿค”", - "x": 39, - "y": 1 - }], - "version": 1 - }, - "saluting_face": { - "id": "saluting_face", - "name": "Saluting Face", - "keywords": ["respect", "salute"], - "skins": [{ - "unified": "1fae1", - "native": "๐Ÿซก", - "x": 55, - "y": 13 - }], - "version": 14 - }, - "zipper_mouth_face": { - "id": "zipper_mouth_face", - "name": "Zipper-Mouth Face", - "keywords": ["zipper", "mouth", "sealed", "secret"], - "skins": [{ - "unified": "1f910", - "native": "๐Ÿค", - "x": 38, - "y": 58 - }], - "version": 1 - }, - "face_with_raised_eyebrow": { - "id": "face_with_raised_eyebrow", - "name": "Face with Raised Eyebrow", - "keywords": ["one", "distrust", "scepticism", "disapproval", "disbelief", "surprise"], - "skins": [{ - "unified": "1f928", - "native": "๐Ÿคจ", - "x": 40, - "y": 37 - }], - "version": 5 - }, - "neutral_face": { - "id": "neutral_face", - "name": "Neutral Face", - "emoticons": [":|", ":-|"], - "keywords": ["indifference", "meh", ":", ""], - "skins": [{ - "unified": "1f610", - "native": "๐Ÿ˜", - "x": 32, - "y": 36 - }], - "version": 1 - }, - "expressionless": { - "id": "expressionless", - "name": "Expressionless Face", - "emoticons": ["-_-"], - "keywords": ["indifferent", "-", "", "meh", "deadpan"], - "skins": [{ - "unified": "1f611", - "native": "๐Ÿ˜‘", - "x": 32, - "y": 37 - }], - "version": 1 - }, - "no_mouth": { - "id": "no_mouth", - "name": "Face Without Mouth", - "keywords": ["no", "hellokitty"], - "skins": [{ - "unified": "1f636", - "native": "๐Ÿ˜ถ", - "x": 33, - "y": 16 - }], - "version": 1 - }, - "dotted_line_face": { - "id": "dotted_line_face", - "name": "Dotted Line Face", - "keywords": ["invisible", "lonely", "isolation", "depression"], - "skins": [{ - "unified": "1fae5", - "native": "๐Ÿซฅ", - "x": 55, - "y": 17 - }], - "version": 14 - }, - "face_in_clouds": { - "id": "face_in_clouds", - "name": "Face in Clouds", - "keywords": ["shower", "steam", "dream"], - "skins": [{ - "unified": "1f636-200d-1f32b-fe0f", - "native": "๐Ÿ˜ถโ€๐ŸŒซ๏ธ", - "x": 33, - "y": 15 - }], - "version": 13.1 - }, - "smirk": { - "id": "smirk", - "name": "Smirking Face", - "keywords": ["smirk", "smile", "mean", "prank", "smug", "sarcasm"], - "skins": [{ - "unified": "1f60f", - "native": "๐Ÿ˜", - "x": 32, - "y": 35 - }], - "version": 1 - }, - "unamused": { - "id": "unamused", - "name": "Unamused Face", - "emoticons": [":("], - "keywords": ["indifference", "bored", "straight", "serious", "sarcasm", "unimpressed", "skeptical", "dubious", "side", "eye"], - "skins": [{ - "unified": "1f612", - "native": "๐Ÿ˜’", - "x": 32, - "y": 38 - }], - "version": 1 - }, - "face_with_rolling_eyes": { - "id": "face_with_rolling_eyes", - "name": "Face with Rolling Eyes", - "keywords": ["eyeroll", "frustrated"], - "skins": [{ - "unified": "1f644", - "native": "๐Ÿ™„", - "x": 33, - "y": 30 - }], - "version": 1 - }, - "grimacing": { - "id": "grimacing", - "name": "Grimacing Face", - "keywords": ["grimace", "teeth"], - "skins": [{ - "unified": "1f62c", - "native": "๐Ÿ˜ฌ", - "x": 33, - "y": 3 - }], - "version": 1 - }, - "face_exhaling": { - "id": "face_exhaling", - "name": "Face Exhaling", - "keywords": ["relieve", "relief", "tired", "sigh"], - "skins": [{ - "unified": "1f62e-200d-1f4a8", - "native": "๐Ÿ˜ฎโ€๐Ÿ’จ", - "x": 33, - "y": 5 - }], - "version": 13.1 - }, - "lying_face": { - "id": "lying_face", - "name": "Lying Face", - "keywords": ["lie", "pinocchio"], - "skins": [{ - "unified": "1f925", - "native": "๐Ÿคฅ", - "x": 40, - "y": 17 - }], - "version": 3 - }, - "relieved": { - "id": "relieved", - "name": "Relieved Face", - "keywords": ["relaxed", "phew", "massage", "happiness"], - "skins": [{ - "unified": "1f60c", - "native": "๐Ÿ˜Œ", - "x": 32, - "y": 32 - }], - "version": 1 - }, - "pensive": { - "id": "pensive", - "name": "Pensive Face", - "keywords": ["sad", "depressed", "upset"], - "skins": [{ - "unified": "1f614", - "native": "๐Ÿ˜”", - "x": 32, - "y": 40 - }], - "version": 1 - }, - "sleepy": { - "id": "sleepy", - "name": "Sleepy Face", - "keywords": ["tired", "rest", "nap"], - "skins": [{ - "unified": "1f62a", - "native": "๐Ÿ˜ช", - "x": 33, - "y": 1 - }], - "version": 1 - }, - "drooling_face": { - "id": "drooling_face", - "name": "Drooling Face", - "keywords": [], - "skins": [{ - "unified": "1f924", - "native": "๐Ÿคค", - "x": 40, - "y": 16 - }], - "version": 3 - }, - "sleeping": { - "id": "sleeping", - "name": "Sleeping Face", - "keywords": ["tired", "sleepy", "night", "zzz"], - "skins": [{ - "unified": "1f634", - "native": "๐Ÿ˜ด", - "x": 33, - "y": 12 - }], - "version": 1 - }, - "mask": { - "id": "mask", - "name": "Face with Medical Mask", - "keywords": ["sick", "ill", "disease"], - "skins": [{ - "unified": "1f637", - "native": "๐Ÿ˜ท", - "x": 33, - "y": 17 - }], - "version": 1 - }, - "face_with_thermometer": { - "id": "face_with_thermometer", - "name": "Face with Thermometer", - "keywords": ["sick", "temperature", "cold", "fever"], - "skins": [{ - "unified": "1f912", - "native": "๐Ÿค’", - "x": 38, - "y": 60 - }], - "version": 1 - }, - "face_with_head_bandage": { - "id": "face_with_head_bandage", - "name": "Face with Head-Bandage", - "keywords": ["head", "bandage", "injured", "clumsy", "hurt"], - "skins": [{ - "unified": "1f915", - "native": "๐Ÿค•", - "x": 39, - "y": 2 - }], - "version": 1 - }, - "nauseated_face": { - "id": "nauseated_face", - "name": "Nauseated Face", - "keywords": ["vomit", "gross", "green", "sick", "throw", "up", "ill"], - "skins": [{ - "unified": "1f922", - "native": "๐Ÿคข", - "x": 40, - "y": 14 - }], - "version": 3 - }, - "face_vomiting": { - "id": "face_vomiting", - "name": "Face Vomiting", - "keywords": ["with", "open", "mouth", "sick"], - "skins": [{ - "unified": "1f92e", - "native": "๐Ÿคฎ", - "x": 40, - "y": 43 - }], - "version": 5 - }, - "sneezing_face": { - "id": "sneezing_face", - "name": "Sneezing Face", - "keywords": ["gesundheit", "sneeze", "sick", "allergy"], - "skins": [{ - "unified": "1f927", - "native": "๐Ÿคง", - "x": 40, - "y": 36 - }], - "version": 3 - }, - "hot_face": { - "id": "hot_face", - "name": "Hot Face", - "keywords": ["feverish", "heat", "red", "sweating"], - "skins": [{ - "unified": "1f975", - "native": "๐Ÿฅต", - "x": 44, - "y": 2 - }], - "version": 11 - }, - "cold_face": { - "id": "cold_face", - "name": "Cold Face", - "keywords": ["blue", "freezing", "frozen", "frostbite", "icicles"], - "skins": [{ - "unified": "1f976", - "native": "๐Ÿฅถ", - "x": 44, - "y": 3 - }], - "version": 11 - }, - "woozy_face": { - "id": "woozy_face", - "name": "Woozy Face", - "keywords": ["dizzy", "intoxicated", "tipsy", "wavy"], - "skins": [{ - "unified": "1f974", - "native": "๐Ÿฅด", - "x": 44, - "y": 1 - }], - "version": 11 - }, - "dizzy_face": { - "id": "dizzy_face", - "name": "Dizzy Face", - "keywords": ["spent", "unconscious", "xox"], - "skins": [{ - "unified": "1f635", - "native": "๐Ÿ˜ต", - "x": 33, - "y": 14 - }], - "version": 1 - }, - "face_with_spiral_eyes": { - "id": "face_with_spiral_eyes", - "name": "Face with Spiral Eyes", - "keywords": ["sick", "ill", "confused", "nauseous", "nausea"], - "skins": [{ - "unified": "1f635-200d-1f4ab", - "native": "๐Ÿ˜ตโ€๐Ÿ’ซ", - "x": 33, - "y": 13 - }], - "version": 13.1 - }, - "exploding_head": { - "id": "exploding_head", - "name": "Exploding Head", - "keywords": ["shocked", "face", "with", "mind", "blown"], - "skins": [{ - "unified": "1f92f", - "native": "๐Ÿคฏ", - "x": 40, - "y": 44 - }], - "version": 5 - }, - "face_with_cowboy_hat": { - "id": "face_with_cowboy_hat", - "name": "Cowboy Hat Face", - "keywords": ["with", "cowgirl"], - "skins": [{ - "unified": "1f920", - "native": "๐Ÿค ", - "x": 40, - "y": 12 - }], - "version": 3 - }, - "partying_face": { - "id": "partying_face", - "name": "Partying Face", - "keywords": ["celebration", "woohoo"], - "skins": [{ - "unified": "1f973", - "native": "๐Ÿฅณ", - "x": 44, - "y": 0 - }], - "version": 11 - }, - "disguised_face": { - "id": "disguised_face", - "name": "Disguised Face", - "keywords": ["pretent", "brows", "glasses", "moustache"], - "skins": [{ - "unified": "1f978", - "native": "๐Ÿฅธ", - "x": 44, - "y": 10 - }], - "version": 13 - }, - "sunglasses": { - "id": "sunglasses", - "name": "Smiling Face with Sunglasses", - "emoticons": ["8)"], - "keywords": ["cool", "smile", "summer", "beach", "sunglass"], - "skins": [{ - "unified": "1f60e", - "native": "๐Ÿ˜Ž", - "x": 32, - "y": 34 - }], - "version": 1 - }, - "nerd_face": { - "id": "nerd_face", - "name": "Nerd Face", - "keywords": ["nerdy", "geek", "dork"], - "skins": [{ - "unified": "1f913", - "native": "๐Ÿค“", - "x": 39, - "y": 0 - }], - "version": 1 - }, - "face_with_monocle": { - "id": "face_with_monocle", - "name": "Face with Monocle", - "keywords": ["stuffy", "wealthy"], - "skins": [{ - "unified": "1f9d0", - "native": "๐Ÿง", - "x": 47, - "y": 11 - }], - "version": 5 - }, - "confused": { - "id": "confused", - "name": "Confused Face", - "emoticons": [":\\", ":-\\", ":/", ":-/"], - "keywords": ["indifference", "huh", "weird", "hmmm", ":/"], - "skins": [{ - "unified": "1f615", - "native": "๐Ÿ˜•", - "x": 32, - "y": 41 - }], - "version": 1 - }, - "face_with_diagonal_mouth": { - "id": "face_with_diagonal_mouth", - "name": "Face with Diagonal Mouth", - "keywords": ["skeptic", "confuse", "frustrated", "indifferent"], - "skins": [{ - "unified": "1fae4", - "native": "๐Ÿซค", - "x": 55, - "y": 16 - }], - "version": 14 - }, - "worried": { - "id": "worried", - "name": "Worried Face", - "keywords": ["concern", "nervous", ":("], - "skins": [{ - "unified": "1f61f", - "native": "๐Ÿ˜Ÿ", - "x": 32, - "y": 51 - }], - "version": 1 - }, - "slightly_frowning_face": { - "id": "slightly_frowning_face", - "name": "Slightly Frowning Face", - "keywords": ["disappointed", "sad", "upset"], - "skins": [{ - "unified": "1f641", - "native": "๐Ÿ™", - "x": 33, - "y": 27 - }], - "version": 1 - }, - "white_frowning_face": { - "id": "white_frowning_face", - "name": "Frowning Face", - "keywords": ["white", "sad", "upset", "frown"], - "skins": [{ - "unified": "2639-fe0f", - "native": "โ˜น๏ธ", - "x": 57, - "y": 3 - }], - "version": 1 - }, - "open_mouth": { - "id": "open_mouth", - "name": "Face with Open Mouth", - "emoticons": [":o", ":-o", ":O", ":-O"], - "keywords": ["surprise", "impressed", "wow", "whoa", ":O"], - "skins": [{ - "unified": "1f62e", - "native": "๐Ÿ˜ฎ", - "x": 33, - "y": 6 - }], - "version": 1 - }, - "hushed": { - "id": "hushed", - "name": "Hushed Face", - "keywords": ["woo", "shh"], - "skins": [{ - "unified": "1f62f", - "native": "๐Ÿ˜ฏ", - "x": 33, - "y": 7 - }], - "version": 1 - }, - "astonished": { - "id": "astonished", - "name": "Astonished Face", - "keywords": ["xox", "surprised", "poisoned"], - "skins": [{ - "unified": "1f632", - "native": "๐Ÿ˜ฒ", - "x": 33, - "y": 10 - }], - "version": 1 - }, - "flushed": { - "id": "flushed", - "name": "Flushed Face", - "keywords": ["blush", "shy", "flattered"], - "skins": [{ - "unified": "1f633", - "native": "๐Ÿ˜ณ", - "x": 33, - "y": 11 - }], - "version": 1 - }, - "pleading_face": { - "id": "pleading_face", - "name": "Pleading Face", - "keywords": ["begging", "mercy"], - "skins": [{ - "unified": "1f97a", - "native": "๐Ÿฅบ", - "x": 44, - "y": 12 - }], - "version": 11 - }, - "face_holding_back_tears": { - "id": "face_holding_back_tears", - "name": "Face Holding Back Tears", - "keywords": ["touched", "gratitude"], - "skins": [{ - "unified": "1f979", - "native": "๐Ÿฅน", - "x": 44, - "y": 11 - }], - "version": 14 - }, - "frowning": { - "id": "frowning", - "name": "Frowning Face with Open Mouth", - "keywords": ["aw", "what"], - "skins": [{ - "unified": "1f626", - "native": "๐Ÿ˜ฆ", - "x": 32, - "y": 58 - }], - "version": 1 - }, - "anguished": { - "id": "anguished", - "name": "Anguished Face", - "emoticons": ["D:"], - "keywords": ["stunned", "nervous"], - "skins": [{ - "unified": "1f627", - "native": "๐Ÿ˜ง", - "x": 32, - "y": 59 - }], - "version": 1 - }, - "fearful": { - "id": "fearful", - "name": "Fearful Face", - "keywords": ["scared", "terrified", "nervous", "oops", "huh"], - "skins": [{ - "unified": "1f628", - "native": "๐Ÿ˜จ", - "x": 32, - "y": 60 - }], - "version": 1 - }, - "cold_sweat": { - "id": "cold_sweat", - "name": "Anxious Face with Sweat", - "keywords": ["cold", "nervous"], - "skins": [{ - "unified": "1f630", - "native": "๐Ÿ˜ฐ", - "x": 33, - "y": 8 - }], - "version": 1 - }, - "disappointed_relieved": { - "id": "disappointed_relieved", - "name": "Sad but Relieved Face", - "keywords": ["disappointed", "phew", "sweat", "nervous"], - "skins": [{ - "unified": "1f625", - "native": "๐Ÿ˜ฅ", - "x": 32, - "y": 57 - }], - "version": 1 - }, - "cry": { - "id": "cry", - "name": "Crying Face", - "emoticons": [":'("], - "keywords": ["cry", "tears", "sad", "depressed", "upset", ":'("], - "skins": [{ - "unified": "1f622", - "native": "๐Ÿ˜ข", - "x": 32, - "y": 54 - }], - "version": 1 - }, - "sob": { - "id": "sob", - "name": "Loudly Crying Face", - "emoticons": [":'("], - "keywords": ["sob", "cry", "tears", "sad", "upset", "depressed"], - "skins": [{ - "unified": "1f62d", - "native": "๐Ÿ˜ญ", - "x": 33, - "y": 4 - }], - "version": 1 - }, - "scream": { - "id": "scream", - "name": "Face Screaming in Fear", - "keywords": ["scream", "munch", "scared", "omg"], - "skins": [{ - "unified": "1f631", - "native": "๐Ÿ˜ฑ", - "x": 33, - "y": 9 - }], - "version": 1 - }, - "confounded": { - "id": "confounded", - "name": "Confounded Face", - "keywords": ["confused", "sick", "unwell", "oops", ":S"], - "skins": [{ - "unified": "1f616", - "native": "๐Ÿ˜–", - "x": 32, - "y": 42 - }], - "version": 1 - }, - "persevere": { - "id": "persevere", - "name": "Persevering Face", - "keywords": ["persevere", "sick", "no", "upset", "oops"], - "skins": [{ - "unified": "1f623", - "native": "๐Ÿ˜ฃ", - "x": 32, - "y": 55 - }], - "version": 1 - }, - "disappointed": { - "id": "disappointed", - "name": "Disappointed Face", - "emoticons": ["):", ":(", ":-("], - "keywords": ["sad", "upset", "depressed", ":("], - "skins": [{ - "unified": "1f61e", - "native": "๐Ÿ˜ž", - "x": 32, - "y": 50 - }], - "version": 1 - }, - "sweat": { - "id": "sweat", - "name": "Face with Cold Sweat", - "keywords": ["downcast", "hot", "sad", "tired", "exercise"], - "skins": [{ - "unified": "1f613", - "native": "๐Ÿ˜“", - "x": 32, - "y": 39 - }], - "version": 1 - }, - "weary": { - "id": "weary", - "name": "Weary Face", - "keywords": ["tired", "sleepy", "sad", "frustrated", "upset"], - "skins": [{ - "unified": "1f629", - "native": "๐Ÿ˜ฉ", - "x": 33, - "y": 0 - }], - "version": 1 - }, - "tired_face": { - "id": "tired_face", - "name": "Tired Face", - "keywords": ["sick", "whine", "upset", "frustrated"], - "skins": [{ - "unified": "1f62b", - "native": "๐Ÿ˜ซ", - "x": 33, - "y": 2 - }], - "version": 1 - }, - "yawning_face": { - "id": "yawning_face", - "name": "Yawning Face", - "keywords": ["tired", "sleepy"], - "skins": [{ - "unified": "1f971", - "native": "๐Ÿฅฑ", - "x": 43, - "y": 59 - }], - "version": 12 - }, - "triumph": { - "id": "triumph", - "name": "Face with Look of Triumph", - "keywords": ["steam", "from", "nose", "gas", "phew", "proud", "pride"], - "skins": [{ - "unified": "1f624", - "native": "๐Ÿ˜ค", - "x": 32, - "y": 56 - }], - "version": 1 - }, - "rage": { - "id": "rage", - "name": "Pouting Face", - "keywords": ["rage", "angry", "mad", "hate", "despise"], - "skins": [{ - "unified": "1f621", - "native": "๐Ÿ˜ก", - "x": 32, - "y": 53 - }], - "version": 1 - }, - "angry": { - "id": "angry", - "name": "Angry Face", - "emoticons": [">:(", ">:-("], - "keywords": ["mad", "annoyed", "frustrated"], - "skins": [{ - "unified": "1f620", - "native": "๐Ÿ˜ ", - "x": 32, - "y": 52 - }], - "version": 1 - }, - "face_with_symbols_on_mouth": { - "id": "face_with_symbols_on_mouth", - "name": "Face with Symbols on Mouth", - "keywords": ["serious", "covering", "swearing", "cursing", "cussing", "profanity", "expletive"], - "skins": [{ - "unified": "1f92c", - "native": "๐Ÿคฌ", - "x": 40, - "y": 41 - }], - "version": 5 - }, - "smiling_imp": { - "id": "smiling_imp", - "name": "Smiling Face with Horns", - "keywords": ["imp", "devil"], - "skins": [{ - "unified": "1f608", - "native": "๐Ÿ˜ˆ", - "x": 32, - "y": 28 - }], - "version": 1 - }, - "imp": { - "id": "imp", - "name": "Imp", - "keywords": ["angry", "face", "with", "horns", "devil"], - "skins": [{ - "unified": "1f47f", - "native": "๐Ÿ‘ฟ", - "x": 25, - "y": 8 - }], - "version": 1 - }, - "skull": { - "id": "skull", - "name": "Skull", - "keywords": ["dead", "skeleton", "creepy", "death"], - "skins": [{ - "unified": "1f480", - "native": "๐Ÿ’€", - "x": 25, - "y": 9 - }], - "version": 1 - }, - "skull_and_crossbones": { - "id": "skull_and_crossbones", - "name": "Skull and Crossbones", - "keywords": ["poison", "danger", "deadly", "scary", "death", "pirate", "evil"], - "skins": [{ - "unified": "2620-fe0f", - "native": "โ˜ ๏ธ", - "x": 56, - "y": 56 - }], - "version": 1 - }, - "hankey": { - "id": "hankey", - "name": "Pile of Poo", - "keywords": ["hankey", "poop", "shit", "shitface", "fail", "turd"], - "skins": [{ - "unified": "1f4a9", - "native": "๐Ÿ’ฉ", - "x": 27, - "y": 56 - }], - "version": 1 - }, - "clown_face": { - "id": "clown_face", - "name": "Clown Face", - "keywords": [], - "skins": [{ - "unified": "1f921", - "native": "๐Ÿคก", - "x": 40, - "y": 13 - }], - "version": 3 - }, - "japanese_ogre": { - "id": "japanese_ogre", - "name": "Ogre", - "keywords": ["japanese", "monster", "red", "mask", "halloween", "scary", "creepy", "devil", "demon"], - "skins": [{ - "unified": "1f479", - "native": "๐Ÿ‘น", - "x": 24, - "y": 58 - }], - "version": 1 - }, - "japanese_goblin": { - "id": "japanese_goblin", - "name": "Goblin", - "keywords": ["japanese", "red", "evil", "mask", "monster", "scary", "creepy"], - "skins": [{ - "unified": "1f47a", - "native": "๐Ÿ‘บ", - "x": 24, - "y": 59 - }], - "version": 1 - }, - "ghost": { - "id": "ghost", - "name": "Ghost", - "keywords": ["halloween", "spooky", "scary"], - "skins": [{ - "unified": "1f47b", - "native": "๐Ÿ‘ป", - "x": 24, - "y": 60 - }], - "version": 1 - }, - "alien": { - "id": "alien", - "name": "Alien", - "keywords": ["UFO", "paul", "weird", "outer", "space"], - "skins": [{ - "unified": "1f47d", - "native": "๐Ÿ‘ฝ", - "x": 25, - "y": 6 - }], - "version": 1 - }, - "space_invader": { - "id": "space_invader", - "name": "Alien Monster", - "keywords": ["space", "invader", "game", "arcade", "play"], - "skins": [{ - "unified": "1f47e", - "native": "๐Ÿ‘พ", - "x": 25, - "y": 7 - }], - "version": 1 - }, - "robot_face": { - "id": "robot_face", - "name": "Robot", - "keywords": ["face", "computer", "machine", "bot"], - "skins": [{ - "unified": "1f916", - "native": "๐Ÿค–", - "x": 39, - "y": 3 - }], - "version": 1 - }, - "smiley_cat": { - "id": "smiley_cat", - "name": "Grinning Cat", - "keywords": ["smiley", "animal", "cats", "happy", "smile"], - "skins": [{ - "unified": "1f63a", - "native": "๐Ÿ˜บ", - "x": 33, - "y": 20 - }], - "version": 1 - }, - "smile_cat": { - "id": "smile_cat", - "name": "Grinning Cat with Smiling Eyes", - "keywords": ["smile", "animal", "cats"], - "skins": [{ - "unified": "1f638", - "native": "๐Ÿ˜ธ", - "x": 33, - "y": 18 - }], - "version": 1 - }, - "joy_cat": { - "id": "joy_cat", - "name": "Cat with Tears of Joy", - "keywords": ["animal", "cats", "haha", "happy"], - "skins": [{ - "unified": "1f639", - "native": "๐Ÿ˜น", - "x": 33, - "y": 19 - }], - "version": 1 - }, - "heart_eyes_cat": { - "id": "heart_eyes_cat", - "name": "Smiling Cat with Heart-Eyes", - "keywords": ["heart", "eyes", "animal", "love", "like", "affection", "cats", "valentines"], - "skins": [{ - "unified": "1f63b", - "native": "๐Ÿ˜ป", - "x": 33, - "y": 21 - }], - "version": 1 - }, - "smirk_cat": { - "id": "smirk_cat", - "name": "Cat with Wry Smile", - "keywords": ["smirk", "animal", "cats"], - "skins": [{ - "unified": "1f63c", - "native": "๐Ÿ˜ผ", - "x": 33, - "y": 22 - }], - "version": 1 - }, - "kissing_cat": { - "id": "kissing_cat", - "name": "Kissing Cat", - "keywords": ["animal", "cats", "kiss"], - "skins": [{ - "unified": "1f63d", - "native": "๐Ÿ˜ฝ", - "x": 33, - "y": 23 - }], - "version": 1 - }, - "scream_cat": { - "id": "scream_cat", - "name": "Weary Cat", - "keywords": ["scream", "animal", "cats", "munch", "scared"], - "skins": [{ - "unified": "1f640", - "native": "๐Ÿ™€", - "x": 33, - "y": 26 - }], - "version": 1 - }, - "crying_cat_face": { - "id": "crying_cat_face", - "name": "Crying Cat", - "keywords": ["face", "animal", "tears", "weep", "sad", "cats", "upset", "cry"], - "skins": [{ - "unified": "1f63f", - "native": "๐Ÿ˜ฟ", - "x": 33, - "y": 25 - }], - "version": 1 - }, - "pouting_cat": { - "id": "pouting_cat", - "name": "Pouting Cat", - "keywords": ["animal", "cats"], - "skins": [{ - "unified": "1f63e", - "native": "๐Ÿ˜พ", - "x": 33, - "y": 24 - }], - "version": 1 - }, - "see_no_evil": { - "id": "see_no_evil", - "name": "See-No-Evil Monkey", - "keywords": ["see", "no", "evil", "animal", "nature", "haha"], - "skins": [{ - "unified": "1f648", - "native": "๐Ÿ™ˆ", - "x": 34, - "y": 24 - }], - "version": 1 - }, - "hear_no_evil": { - "id": "hear_no_evil", - "name": "Hear-No-Evil Monkey", - "keywords": ["hear", "no", "evil", "animal", "nature"], - "skins": [{ - "unified": "1f649", - "native": "๐Ÿ™‰", - "x": 34, - "y": 25 - }], - "version": 1 - }, - "speak_no_evil": { - "id": "speak_no_evil", - "name": "Speak-No-Evil Monkey", - "keywords": ["speak", "no", "evil", "animal", "nature", "omg"], - "skins": [{ - "unified": "1f64a", - "native": "๐Ÿ™Š", - "x": 34, - "y": 26 - }], - "version": 1 - }, - "kiss": { - "id": "kiss", - "name": "Kiss Mark", - "keywords": ["face", "lips", "love", "like", "affection", "valentines"], - "skins": [{ - "unified": "1f48b", - "native": "๐Ÿ’‹", - "x": 26, - "y": 37 - }], - "version": 1 - }, - "love_letter": { - "id": "love_letter", - "name": "Love Letter", - "keywords": ["email", "like", "affection", "envelope", "valentines"], - "skins": [{ - "unified": "1f48c", - "native": "๐Ÿ’Œ", - "x": 26, - "y": 38 - }], - "version": 1 - }, - "cupid": { - "id": "cupid", - "name": "Heart with Arrow", - "keywords": ["cupid", "love", "like", "affection", "valentines"], - "skins": [{ - "unified": "1f498", - "native": "๐Ÿ’˜", - "x": 27, - "y": 39 - }], - "version": 1 - }, - "gift_heart": { - "id": "gift_heart", - "name": "Heart with Ribbon", - "keywords": ["gift", "love", "valentines"], - "skins": [{ - "unified": "1f49d", - "native": "๐Ÿ’", - "x": 27, - "y": 44 - }], - "version": 1 - }, - "sparkling_heart": { - "id": "sparkling_heart", - "name": "Sparkling Heart", - "keywords": ["love", "like", "affection", "valentines"], - "skins": [{ - "unified": "1f496", - "native": "๐Ÿ’–", - "x": 27, - "y": 37 - }], - "version": 1 - }, - "heartpulse": { - "id": "heartpulse", - "name": "Growing Heart", - "keywords": ["heartpulse", "like", "love", "affection", "valentines", "pink"], - "skins": [{ - "unified": "1f497", - "native": "๐Ÿ’—", - "x": 27, - "y": 38 - }], - "version": 1 - }, - "heartbeat": { - "id": "heartbeat", - "name": "Beating Heart", - "keywords": ["heartbeat", "love", "like", "affection", "valentines", "pink"], - "skins": [{ - "unified": "1f493", - "native": "๐Ÿ’“", - "x": 27, - "y": 34 - }], - "version": 1 - }, - "revolving_hearts": { - "id": "revolving_hearts", - "name": "Revolving Hearts", - "keywords": ["love", "like", "affection", "valentines"], - "skins": [{ - "unified": "1f49e", - "native": "๐Ÿ’ž", - "x": 27, - "y": 45 - }], - "version": 1 - }, - "two_hearts": { - "id": "two_hearts", - "name": "Two Hearts", - "keywords": ["love", "like", "affection", "valentines", "heart"], - "skins": [{ - "unified": "1f495", - "native": "๐Ÿ’•", - "x": 27, - "y": 36 - }], - "version": 1 - }, - "heart_decoration": { - "id": "heart_decoration", - "name": "Heart Decoration", - "keywords": ["purple", "square", "love", "like"], - "skins": [{ - "unified": "1f49f", - "native": "๐Ÿ’Ÿ", - "x": 27, - "y": 46 - }], - "version": 1 - }, - "heavy_heart_exclamation_mark_ornament": { - "id": "heavy_heart_exclamation_mark_ornament", - "name": "Heart Exclamation", - "keywords": ["heavy", "mark", "ornament", "decoration", "love"], - "skins": [{ - "unified": "2763-fe0f", - "native": "โฃ๏ธ", - "x": 59, - "y": 7 - }], - "version": 1 - }, - "broken_heart": { - "id": "broken_heart", - "name": "Broken Heart", - "emoticons": [" [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) ?? [] + } +} diff --git a/ElementX/SupportingFiles/target.yml b/ElementX/SupportingFiles/target.yml index c4a25dd33..72da2237e 100644 --- a/ElementX/SupportingFiles/target.yml +++ b/ElementX/SupportingFiles/target.yml @@ -163,6 +163,7 @@ targets: - package: Sentry - package: URLRouting - package: Version + - package: Emojibase sources: - path: ../Sources diff --git a/UnitTests/Sources/EmojiMartJSONLoaderTests.swift b/UnitTests/Sources/EmojiMartJSONLoaderTests.swift deleted file mode 100644 index 112000e5e..000000000 --- a/UnitTests/Sources/EmojiMartJSONLoaderTests.swift +++ /dev/null @@ -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) - } -} diff --git a/UnitTests/Sources/EmojiProviderTests.swift b/UnitTests/Sources/EmojiProviderTests.swift index a67fb0857..fca074d0f 100644 --- a/UnitTests/Sources/EmojiProviderTests.swift +++ b/UnitTests/Sources/EmojiProviderTests.swift @@ -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) } } diff --git a/project.yml b/project.yml index dbe0f72c9..8fc6c7fa7 100644 --- a/project.yml +++ b/project.yml @@ -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 +