├── .gitignore ├── .swiftlint.yml ├── ExternalResources └── locales.json ├── LICENSE ├── Makefile ├── Podfile ├── Podfile.lock ├── README.md ├── WeChat-SwiftUI.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── swiftpm │ │ └── Package.resolved └── xcuserdata │ └── lebron.xcuserdatad │ └── xcschemes │ └── xcschememanagement.plist ├── WeChat-SwiftUI.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ ├── IDEWorkspaceChecks.plist │ └── swiftpm │ └── Package.resolved ├── WeChat-SwiftUI ├── API │ ├── Firesbase │ │ ├── FirebaseAuthService.swift │ │ ├── FirebaseAuthServiceMock.swift │ │ ├── FirebaseAuthServiceType.swift │ │ ├── FirestoreService.swift │ │ ├── FirestoreServiceMock.swift │ │ └── FirestoreServiceType.swift │ └── OurOwnBackend │ │ ├── Lib │ │ ├── APIError.swift │ │ ├── EnvironmentType.swift │ │ ├── Method.swift │ │ ├── NetworkingHelpers.swift │ │ ├── OauthToken.swift │ │ └── Route.swift │ │ ├── MockService.swift │ │ ├── ServerConfig.swift │ │ ├── ServerConfigTests.swift │ │ ├── Service+RequestHelpers.swift │ │ ├── Service.swift │ │ ├── ServiceTests.swift │ │ ├── ServiceType.swift │ │ └── ServiceTypeTests.swift ├── Configs │ └── Secrets.swift ├── DataModels │ ├── AccessTokenEnvelope.swift │ ├── ContactCategory.swift │ ├── ContactType.swift │ ├── Dialog+Setters.swift │ ├── Dialog.swift │ ├── DialogChange.swift │ ├── DialogChangeTests.swift │ ├── DialogMessages.swift │ ├── DialogMessagesTests.swift │ ├── DialogTests.swift │ ├── DiscoverItem.swift │ ├── DiscoverSectionTests.swift │ ├── ExpressionSticker.swift │ ├── ExpressionStickerTests.swift │ ├── MeItem.swift │ ├── Message+Setters.swift │ ├── Message.Image+Setters.swift │ ├── Message.Image.LocalImage+Setters.swift │ ├── Message.Image.LocalImage.swift │ ├── Message.Image.LocalImageTests.swift │ ├── Message.Image.URLImage.swift │ ├── Message.Image.swift │ ├── Message.ImageTests.swift │ ├── Message.swift │ ├── MessageChange.swift │ ├── MessageChangeTests.swift │ ├── MessageTests.swift │ ├── OfficialAccount.swift │ ├── OfficialAccountTests.swift │ ├── TabBarItem.swift │ ├── Templates │ │ ├── DialogMessagesTemplates.swift │ │ ├── DialogTemplates.swift │ │ ├── ExpressionStickerTemplates.swift │ │ ├── Message.ImageTemplates.swift │ │ ├── MessageTemplates.swift │ │ ├── OfficialAccountTemplates.swift │ │ └── UserTemplates.swift │ ├── User+Setters.swift │ ├── User.swift │ └── UserTests.swift ├── Info.plist ├── Library │ ├── AppEnvironment.swift │ ├── AppEnvironmentTests.swift │ ├── CancelBag.swift │ ├── Components │ │ ├── ActivityIndicator.swift │ │ ├── ErrorView.swift │ │ ├── ImagePicker.swift │ │ ├── ImageTitleRow.swift │ │ ├── MediaLoadingProgressView.swift │ │ ├── NavigationRow.swift │ │ ├── SearchBar.swift │ │ ├── SectionHeaderBackground.swift │ │ ├── SectionHeaderTitle.swift │ │ └── URLPlaceholderImage.swift │ ├── Constants.swift │ ├── Environment.swift │ ├── EnvironmentTests.swift │ ├── Errors.swift │ ├── Extensions │ │ ├── AnyPublisher+Initializers.swift │ │ ├── CGSize+AspectSize.swift │ │ ├── CGSize+AspectSizeTests.swift │ │ ├── Collection+Matching.swift │ │ ├── Collection+MatchingTests.swift │ │ ├── Color+Hex.swift │ │ ├── Color+HexTests.swift │ │ ├── Dictionary+Data.swift │ │ ├── EdgeInsets.swift │ │ ├── EdgeInsetsTests.swift │ │ ├── Encodable+Dictionary.swift │ │ ├── Encodable+DictionaryTests.swift │ │ ├── Image+Constants.swift │ │ ├── Image+Resize.swift │ │ ├── Publisher+Sink.swift │ │ ├── String+Height.swift │ │ ├── String+Identifiable.swift │ │ ├── UIApplication+EndEditing.swift │ │ ├── UIImage+InitWithColor.swift │ │ └── View+AsAnyView.swift │ ├── Firebase │ │ ├── FirebaseStorageService.swift │ │ ├── FirebaseStorageServiceMock.swift │ │ ├── FirebaseStorageServiceType.swift │ │ └── FirestoreReferenceFactory.swift │ ├── GenerateUUID.swift │ ├── Haptics.swift │ ├── ImageFormat.swift │ ├── KeyValueStoreKey.swift │ ├── KeyValueStoreType.swift │ ├── Language.swift │ ├── LanguageTests.swift │ ├── Loadable.swift │ ├── LoadableTests.swift │ ├── LocalizedString.swift │ ├── LocalizedStringTests.swift │ ├── Modifiers │ │ ├── DelayTouchesModifier.swift │ │ ├── LoadingModifier.swift │ │ ├── ResignKeyboardOnDragModifier.swift │ │ └── ResignKeyboardOnTapModifier.swift │ ├── NSBundleType.swift │ ├── ObjectBox.swift │ ├── PhotoPickerType.swift │ ├── PresentationStyle.swift │ ├── Strings.swift │ ├── Styles │ │ └── Colors.swift │ ├── TestHelpers │ │ ├── AppStateDataSource.swift │ │ ├── MessagesDataSource.swift │ │ ├── MockBundle.swift │ │ ├── TestObserver.swift │ │ ├── XCTestCase+AppEnvironment.swift │ │ └── XCTestCase+Wait.swift │ ├── TryDecodable.swift │ ├── ValueUpdateStatus.swift │ ├── ValueUpdateStatusTests.swift │ └── WaitAndExecute.swift ├── Locales │ ├── en.lproj │ │ └── Localizable.strings │ └── zh-Hans.lproj │ │ └── Localizable.strings ├── PreviewContent │ └── PreviewAssets.xcassets │ │ ├── Contents.json │ │ ├── IMG_0001.imageset │ │ ├── Contents.json │ │ └── IMG_0001.png │ │ ├── IMG_0002.imageset │ │ ├── Contents.json │ │ └── IMG_0002.png │ │ ├── IMG_0003.imageset │ │ ├── Contents.json │ │ └── IMG_0003.png │ │ ├── IMG_0004.imageset │ │ ├── Contents.json │ │ └── IMG_0004.png │ │ └── IMG_0005.imageset │ │ ├── Contents.json │ │ └── IMG_0005.png ├── Redux │ ├── Actions │ │ ├── AuthActions.swift │ │ ├── AuthActionsTests.swift │ │ ├── ChatsActions.swift │ │ ├── ChatsActionsTests.swift │ │ ├── ContactsActions.swift │ │ ├── ContactsActionsTests.swift │ │ ├── RootActions.swift │ │ └── SystemActions.swift │ ├── MockStore.swift │ ├── Reducers │ │ ├── AppReducer.swift │ │ ├── AuthReducer.swift │ │ ├── AuthReducerTests.swift │ │ ├── ChatsReducer.swift │ │ ├── ChatsReducerTests.swift │ │ ├── ContactsReducer.swift │ │ ├── ContactsReducerTests.swift │ │ ├── RootReducer.swift │ │ ├── RootReducerTests.swift │ │ ├── SystemReducer.swift │ │ └── SystemReducerTests.swift │ ├── State │ │ ├── AppState.swift │ │ ├── AppStateTests.swift │ │ ├── AuthState.swift │ │ ├── AuthStateTests.swift │ │ ├── ChatsState.swift │ │ ├── ChatsStateTests.swift │ │ ├── ContactsState.swift │ │ ├── ContactsStateTests.swift │ │ ├── DiscoverState.swift │ │ ├── DiscoverStateTests.swift │ │ ├── RootState.swift │ │ ├── RootStateTests.swift │ │ ├── SystemState.swift │ │ └── SystemStateTests.swift │ └── Store.swift ├── Resources │ ├── Assets.xcassets │ │ ├── AccentColor.colorset │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ ├── AppIcon_1024.png │ │ │ ├── AppIcon_120-1.png │ │ │ ├── AppIcon_120.png │ │ │ ├── AppIcon_180.png │ │ │ ├── AppIcon_40.png │ │ │ ├── AppIcon_58.png │ │ │ ├── AppIcon_60.png │ │ │ ├── AppIcon_80.png │ │ │ ├── AppIcon_87.png │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── colors │ │ │ ├── Contents.json │ │ │ ├── app_bg.colorset │ │ │ │ └── Contents.json │ │ │ ├── app_white.colorset │ │ │ │ └── Contents.json │ │ │ ├── bg_chat_incoming_msg.colorset │ │ │ │ └── Contents.json │ │ │ ├── bg_chat_outgoing_msg.colorset │ │ │ │ └── Contents.json │ │ │ ├── bg_expression_preview.colorset │ │ │ │ └── Contents.json │ │ │ ├── bg_info_100.colorset │ │ │ │ └── Contents.json │ │ │ ├── bg_info_150.colorset │ │ │ │ └── Contents.json │ │ │ ├── bg_info_170.colorset │ │ │ │ └── Contents.json │ │ │ ├── bg_info_200.colorset │ │ │ │ └── Contents.json │ │ │ ├── bg_info_300.colorset │ │ │ │ └── Contents.json │ │ │ ├── bg_text_input.colorset │ │ │ │ └── Contents.json │ │ │ ├── highlighted.colorset │ │ │ │ └── Contents.json │ │ │ ├── link.colorset │ │ │ │ └── Contents.json │ │ │ ├── text_chat_incoming_msg.colorset │ │ │ │ └── Contents.json │ │ │ ├── text_chat_outgoing_msg.colorset │ │ │ │ └── Contents.json │ │ │ ├── text_expression_preview.colorset │ │ │ │ └── Contents.json │ │ │ ├── text_info_100.colorset │ │ │ │ └── Contents.json │ │ │ ├── text_info_200.colorset │ │ │ │ └── Contents.json │ │ │ ├── text_info_50.colorset │ │ │ │ └── Contents.json │ │ │ ├── text_info_500.colorset │ │ │ │ └── Contents.json │ │ │ ├── text_info_80.colorset │ │ │ │ └── Contents.json │ │ │ └── text_primary.colorset │ │ │ │ └── Contents.json │ │ ├── expressions │ │ │ ├── Contents.json │ │ │ ├── aaagh!.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── aaagh!@2x.png │ │ │ ├── angry.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── angry@2x.png │ │ │ ├── awesome.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── awesome@2x.png │ │ │ ├── awkward.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── awkward@2x.png │ │ │ ├── bah!l.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── bah!l@2x.png │ │ │ ├── bah!r.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── bah!r@2x.png │ │ │ ├── beckon.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── beckon@2x.png │ │ │ ├── beer.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── beer@2x.png │ │ │ ├── blessing.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── blessing@2x.png │ │ │ ├── blush.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── blush@2x.png │ │ │ ├── bomb.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── bomb@2x.png │ │ │ ├── boring.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── boring@2x.png │ │ │ ├── broken.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── broken@2x.png │ │ │ ├── brokenheart.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── brokenheart@2x.png │ │ │ ├── bye.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── bye@2x.png │ │ │ ├── cake.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── cake@2x.png │ │ │ ├── chuckle.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── chuckle@2x.png │ │ │ ├── clap.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── clap@2x.png │ │ │ ├── cleaver.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── cleaver@2x.png │ │ │ ├── coffee.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── coffee@2x.png │ │ │ ├── commando.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── commando@2x.png │ │ │ ├── concerned.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── concerned@2x.png │ │ │ ├── coolguy.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── coolguy@2x.png │ │ │ ├── cry.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── cry0@2x.png │ │ │ ├── determined.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── determined@2x.png │ │ │ ├── dizzy.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── dizzy@2x.png │ │ │ ├── doge.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── doge@2x.png │ │ │ ├── drool.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── drool@2x.png │ │ │ ├── drowsy.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── drowsy@2x.png │ │ │ ├── emm.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── emm@2x.png │ │ │ ├── facepalm.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── facepalm@2x.png │ │ │ ├── fist.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── fist@2x.png │ │ │ ├── frown.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── frown@2x.png │ │ │ ├── goforit.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── goforit@2x.png │ │ │ ├── grimace.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── grimace@2x.png │ │ │ ├── grin.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── grin@2x.png │ │ │ ├── hammer.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── hammer@2x.png │ │ │ ├── heart.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── heart@2x.png │ │ │ ├── hey.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── hey@2x.png │ │ │ ├── hug.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── hug@2x.png │ │ │ ├── hurt.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── hurt@2x.png │ │ │ ├── joyful.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── joyful@2x.png │ │ │ ├── keepfighting.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── keepfighting@2x.png │ │ │ ├── kiss.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── kiss@2x.png │ │ │ ├── laugh.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── laugh@2x.png │ │ │ ├── letmesee.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── letmesee@2x.png │ │ │ ├── lips.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── lips@2x.png │ │ │ ├── moon.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── moon@2x.png │ │ │ ├── mybad.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── mybad@2x.png │ │ │ ├── noprob.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── noprob@2x.png │ │ │ ├── nosepick.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── nosepick@2x.png │ │ │ ├── ok.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── ok@2x.png │ │ │ ├── omg.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── omg@2x.png │ │ │ ├── onlooker.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── onlooker@2x.png │ │ │ ├── packet.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── packet@2x.png │ │ │ ├── panic.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── panic@2x.png │ │ │ ├── peace.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── peace@2x.png │ │ │ ├── pig.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── pig@2x.png │ │ │ ├── pooh-pooh.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── pooh-pooh@2x.png │ │ │ ├── poop.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── poop@2x.png │ │ │ ├── puke.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── puke@2x.png │ │ │ ├── respect.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── respect@2x.png │ │ │ ├── rich.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── rich@2x.png │ │ │ ├── rose.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── rose@2x.png │ │ │ ├── salute.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── salute@2x.png │ │ │ ├── scold.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── scold@2x.png │ │ │ ├── scowl.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── scowl@2x.png │ │ │ ├── scream.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── scream@2x.png │ │ │ ├── shake.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── shake@2x.png │ │ │ ├── shhh.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── shhh@2x.png │ │ │ ├── shocked.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── shocked@2x.png │ │ │ ├── shrunken.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── shrunken@2x.png │ │ │ ├── shy.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── shy@2x.png │ │ │ ├── sigh.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── sigh@2x.png │ │ │ ├── silent.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── silent@2x.png │ │ │ ├── skull.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── skull@2x.png │ │ │ ├── sleep.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── sleep@2x.png │ │ │ ├── slight.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── slight@2x.png │ │ │ ├── sly.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── sly@2x.png │ │ │ ├── smart.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── smart@2x.png │ │ │ ├── smile.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── smile@2x.png │ │ │ ├── smirk.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── smirk@2x.png │ │ │ ├── smug.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── smug@2x.png │ │ │ ├── sob.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── sob@2x.png │ │ │ ├── speechless.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── speechless@2x.png │ │ │ ├── sun.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── sun@2x.png │ │ │ ├── surprise.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── surprise@2x.png │ │ │ ├── sweat.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── sweat@2x.png │ │ │ ├── sweats.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── sweats@2x.png │ │ │ ├── tearingup.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── tearingup@2x.png │ │ │ ├── thumbsdown.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── thumbsdown@2x.png │ │ │ ├── thumbsup.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── thumbsup@2x.png │ │ │ ├── toasted.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── toasted@2x.png │ │ │ ├── tongue.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── tongue@2x.png │ │ │ ├── tremble.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── tremble@2x.png │ │ │ ├── trick.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── trick@2x.png │ │ │ ├── twirl.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── twirl@2x.png │ │ │ ├── waddle.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── waddle@2x.png │ │ │ ├── watermelon.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── watermelon@2x.png │ │ │ ├── whimper.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── whimper@2x.png │ │ │ ├── wilt.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── wilt@2x.png │ │ │ ├── wow.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── wow@2x.png │ │ │ └── yeah!.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── yeah!@2x.png │ │ └── icons │ │ │ ├── Contents.json │ │ │ ├── WeWork.imageset │ │ │ ├── Contents.json │ │ │ └── WeWork.svg │ │ │ ├── icons_filled_camera.imageset │ │ │ ├── Contents.json │ │ │ └── icons_filled_camera.svg │ │ │ ├── icons_filled_chats.imageset │ │ │ ├── Contents.json │ │ │ └── icons_filled_chats.svg │ │ │ ├── icons_filled_colorful_female.imageset │ │ │ ├── Contents.json │ │ │ └── icons_filled_colorful_female.svg │ │ │ ├── icons_filled_colorful_male.imageset │ │ │ ├── Contents.json │ │ │ └── icons_filled_colorful_man.svg │ │ │ ├── icons_filled_contacts.imageset │ │ │ ├── Contents.json │ │ │ └── icons_filled_contacts.svg │ │ │ ├── icons_filled_discover.imageset │ │ │ ├── Contents.json │ │ │ └── icons_filled_discover.svg │ │ │ ├── icons_filled_error.imageset │ │ │ ├── Contents.json │ │ │ └── icons_filled_error.svg │ │ │ ├── icons_filled_fts_default_headimage.imageset │ │ │ ├── Contents.json │ │ │ └── icons_filled_fts_default_headimage.svg │ │ │ ├── icons_filled_group_detail.imageset │ │ │ ├── Contents.json │ │ │ └── icons_filled_group_detail.svg │ │ │ ├── icons_filled_me.imageset │ │ │ ├── Contents.json │ │ │ └── icons_filled_me.svg │ │ │ ├── icons_filled_official_accounts.imageset │ │ │ ├── Contents.json │ │ │ └── icons_filled_official_accounts.svg │ │ │ ├── icons_filled_tag.imageset │ │ │ ├── Contents.json │ │ │ └── icons_filled_tag.svg │ │ │ ├── icons_outlined_add.imageset │ │ │ ├── Contents.json │ │ │ └── icons_outlined_add2.svg │ │ │ ├── icons_outlined_add2.imageset │ │ │ ├── Contents.json │ │ │ └── icons_outlined_add.svg │ │ │ ├── icons_outlined_add_friends.imageset │ │ │ ├── Contents.json │ │ │ └── icons_outlined_add_friends.svg │ │ │ ├── icons_outlined_back.imageset │ │ │ ├── Contents.json │ │ │ └── icons_outlined_back.svg │ │ │ ├── icons_outlined_channel.imageset │ │ │ ├── Contents.json │ │ │ └── icons_outlined_channel_2.svg │ │ │ ├── icons_outlined_chats.imageset │ │ │ ├── Contents.json │ │ │ └── icons_outlined_chats.svg │ │ │ ├── icons_outlined_colorful_favorites.imageset │ │ │ ├── Contents.json │ │ │ └── icons_outlined_colorful_favorites.svg │ │ │ ├── icons_outlined_colorful_game.imageset │ │ │ ├── Contents.json │ │ │ └── icons_outlined_colorful_game.svg │ │ │ ├── icons_outlined_colorful_moment.imageset │ │ │ ├── Contents.json │ │ │ └── icons_outlined_colorful_moment.svg │ │ │ ├── icons_outlined_contacts.imageset │ │ │ ├── Contents.json │ │ │ └── icons_outlined_contacts.svg │ │ │ ├── icons_outlined_discover.imageset │ │ │ ├── Contents.json │ │ │ └── icons_outlined_discover.svg │ │ │ ├── icons_outlined_keyboard.imageset │ │ │ ├── Contents.json │ │ │ └── icons_outlined_keyboard.svg │ │ │ ├── icons_outlined_live_nearby.imageset │ │ │ ├── Contents.json │ │ │ └── icons_outlined_live_nearby.svg │ │ │ ├── icons_outlined_me.imageset │ │ │ ├── Contents.json │ │ │ └── icons_outlined_me.svg │ │ │ ├── icons_outlined_news.imageset │ │ │ ├── Contents.json │ │ │ └── icons_outlined_news.svg │ │ │ ├── icons_outlined_qr_code.imageset │ │ │ ├── Contents.json │ │ │ └── icons_outlined_qr_code.svg │ │ │ ├── icons_outlined_scan.imageset │ │ │ ├── Contents.json │ │ │ └── icons_outlined_scan.svg │ │ │ ├── icons_outlined_searchlogo.imageset │ │ │ ├── Contents.json │ │ │ └── icons_outlined_searchlogo.svg │ │ │ ├── icons_outlined_setting.imageset │ │ │ ├── Contents.json │ │ │ └── icons_outlined_setting.svg │ │ │ ├── icons_outlined_shake.imageset │ │ │ ├── Contents.json │ │ │ └── icons_outlined_shake.svg │ │ │ ├── icons_outlined_shop.imageset │ │ │ ├── Contents.json │ │ │ └── icons_outlined_shop.svg │ │ │ ├── icons_outlined_sticker.imageset │ │ │ ├── Contents.json │ │ │ └── icons_outlined_sticker.svg │ │ │ ├── icons_outlined_videocall.imageset │ │ │ ├── Contents.json │ │ │ └── icons_outlined_videocall.svg │ │ │ ├── icons_outlined_voice.imageset │ │ │ ├── Contents.json │ │ │ └── icons_outlined_voice.svg │ │ │ └── icons_outlined_wechatpay.imageset │ │ │ ├── Contents.json │ │ │ └── icons_outlined_wechatpay.svg │ ├── GoogleService-Info.plist │ └── expressions.json ├── ViewModels │ ├── DialogViewModel.swift │ ├── DialogsListViewModel.swift │ ├── MyProfileFieldUpdateViewModel.swift │ ├── MyProfileFieldUpdateViewModelTests.swift │ ├── MyProfilePhotoPreviewViewModel.swift │ ├── MyProfilePhotoPreviewViewModelTests.swift │ ├── OnboardingViewModel.swift │ └── OnboardingViewModelTests.swift ├── Views │ ├── Chats │ │ ├── ChatsView.swift │ │ ├── Dialog │ │ │ ├── DialogRow.swift │ │ │ ├── DialogView.swift │ │ │ └── DialogsList.swift │ │ ├── InputPanel │ │ │ ├── ChatInputPanel.swift │ │ │ ├── ChatInputToolBar.swift │ │ │ ├── ExpressionKeyboard.swift │ │ │ ├── ExpressionPreview.Background.swift │ │ │ └── ExpressionPreview.swift │ │ └── Message │ │ │ ├── MessageContentImage.swift │ │ │ ├── MessageContentText.swift │ │ │ ├── MessageContentVideo.swift │ │ │ ├── MessageRow.swift │ │ │ └── MessagesList.swift │ ├── Contacts │ │ ├── ContactCategoriesList.swift │ │ ├── ContactCategoryRow.swift │ │ ├── ContactDetail.swift │ │ ├── ContactOfficialAccountsList.swift │ │ ├── ContactsList.SectionIndexTitles.swift │ │ ├── ContactsList.swift │ │ └── ContactsView.swift │ ├── ContentView.swift │ ├── Discover │ │ ├── DiscoverList.swift │ │ └── DiscoverView.swift │ ├── Me │ │ ├── MeView.swift │ │ ├── MyProfileFieldUpdateView.Field.swift │ │ ├── MyProfileFieldUpdateView.swift │ │ ├── MyProfilePhotoPreview.swift │ │ ├── MyProfileView.ProfileRow.swift │ │ ├── MyProfileView.Row.swift │ │ ├── MyProfileView.RowTests.swift │ │ └── MyProfileView.swift │ ├── Onboarding │ │ └── OnboardingView.swift │ └── RootView.swift └── WeChat_SwiftUIApp.swift ├── WeChat-SwiftUITests └── Info.plist ├── WeChat-SwiftUIUITests ├── Info.plist └── TestExamples.swift ├── bin ├── StringsScript │ ├── StringsScript.xcodeproj │ │ ├── project.pbxproj │ │ └── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── StringsScript │ │ ├── Source │ │ │ ├── Extensions.swift │ │ │ ├── StringsScript.swift │ │ │ ├── StringsScriptCore.swift │ │ │ └── StringsScriptCoreError.swift │ │ └── main.swift │ └── bin │ │ └── strings-script └── strings-script └── previews ├── 1.png ├── 2.png ├── 3.png ├── 4.png ├── 5.png ├── 6.png ├── 7.png └── 8.png /.swiftlint.yml: -------------------------------------------------------------------------------- 1 | cyclomatic_complexity: 2 | warning: 20 3 | error: 30 4 | 5 | disabled_rules: # rule identifiers to exclude from running 6 | - todo 7 | - type_name 8 | - large_tuple 9 | - identifier_name 10 | - function_parameter_count 11 | - multiple_closures_with_trailing_closure 12 | 13 | excluded: # paths to ignore during linting. Takes precedence over `included`. 14 | - Pods 15 | - Carthage 16 | 17 | function_body_length: 18 | warning: 75 19 | error: 100 20 | 21 | file_length: 22 | warning: 800 23 | error: 1000 24 | 25 | identifier_name: 26 | excluded: id # id is allowed 27 | 28 | included: 29 | - ./ 30 | 31 | nesting: 32 | type_level: 33 | warning: 4 34 | error: 5 35 | 36 | type_body_length: 37 | warning: 400 38 | error: 500 39 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | strings: 2 | ./bin/strings-script "./ExternalResources/locales.json" "./WeChat-SwiftUI/Library/Strings.swift" "./WeChat-SwiftUI/Locales" -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, "15.0" 2 | use_frameworks! 3 | inhibit_all_warnings! 4 | 5 | target 'WeChat-SwiftUI' do 6 | pod 'Firebase/Core' 7 | pod 'Firebase/Auth' 8 | pod 'Firebase/Storage' 9 | pod 'Firebase/Firestore' 10 | end 11 | 12 | target 'WeChat-SwiftUITests' do 13 | pod 'Firebase/Core' 14 | pod 'Firebase/Auth' 15 | pod 'Firebase/Storage' 16 | pod 'Firebase/Firestore' 17 | end -------------------------------------------------------------------------------- /WeChat-SwiftUI.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /WeChat-SwiftUI.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /WeChat-SwiftUI.xcodeproj/xcuserdata/lebron.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | WeChat-SwiftUI.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 22 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /WeChat-SwiftUI.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /WeChat-SwiftUI.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/API/Firesbase/FirebaseAuthServiceMock.swift: -------------------------------------------------------------------------------- 1 | import Combine 2 | import FirebaseAuth 3 | 4 | /// 返回值无法初始化,无法进行 Mock 5 | struct FirebaseAuthServiceMock: FirebaseAuthServiceType { 6 | 7 | func register(email: String, password: String) -> AnyPublisher { 8 | // AuthDataResult 无法手动初始化 9 | .publisher(failure: NSError.unknowError) 10 | } 11 | 12 | func signIn(email: String, password: String) -> AnyPublisher { 13 | // FirebaseAuth.User 无法手动初始化 14 | .publisher(failure: NSError.unknowError) 15 | } 16 | 17 | func updateUsername(authResult: AuthDataResult, username: String) -> AnyPublisher { 18 | // FirebaseAuth.User 无法手动初始化 19 | .publisher(failure: NSError.unknowError) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/API/Firesbase/FirebaseAuthServiceType.swift: -------------------------------------------------------------------------------- 1 | import Combine 2 | import FirebaseAuth 3 | 4 | protocol FirebaseAuthServiceType { 5 | func register(email: String, password: String) -> AnyPublisher 6 | func signIn(email: String, password: String) -> AnyPublisher 7 | func updateUsername(authResult: AuthDataResult, username: String) -> AnyPublisher 8 | } 9 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/API/Firesbase/FirestoreServiceType.swift: -------------------------------------------------------------------------------- 1 | import Combine 2 | 3 | protocol FirestoreServiceType { 4 | func insert(_ message: Message, to dialog: Dialog) -> AnyPublisher 5 | func loadContacts() -> AnyPublisher<[User], Error> 6 | func loadDialogs() -> AnyPublisher<[Dialog], Error> 7 | func loadMessages(for dialog: Dialog) -> AnyPublisher<[Message], Error> 8 | func loadOfficialAccounts() -> AnyPublisher<[OfficialAccount], Error> 9 | func loadUserSelf() -> AnyPublisher 10 | func overrideDialog(_ dialog: Dialog) -> AnyPublisher 11 | func overrideUser(_ user: User) -> AnyPublisher 12 | } 13 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/API/OurOwnBackend/Lib/APIError.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | enum APIError: Error { 4 | case internalServerError 5 | case invalidURL(String) 6 | case unexpectedResponse(HTTPURLResponse) 7 | } 8 | 9 | extension APIError: LocalizedError { 10 | var errorDescription: String? { 11 | switch self { 12 | case .internalServerError: 13 | return Strings.api_error_internal_server_error() 14 | case let .invalidURL(url): 15 | return Strings.api_error_invalid_url(url: url) 16 | case let .unexpectedResponse(response): 17 | return Strings.api_error_unexpected_response(response: "\(response)") 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/API/OurOwnBackend/Lib/EnvironmentType.swift: -------------------------------------------------------------------------------- 1 | enum EnvironmentType: String { 2 | case production = "Production" 3 | case staging = "Staging" 4 | } 5 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/API/OurOwnBackend/Lib/Method.swift: -------------------------------------------------------------------------------- 1 | enum Method: String { 2 | case GET 3 | case POST 4 | case PUT 5 | case DELETE 6 | } 7 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/API/OurOwnBackend/Lib/OauthToken.swift: -------------------------------------------------------------------------------- 1 | /// 提供 oauth token 身份验证的类型。 2 | protocol OauthTokenAuthType { 3 | var token: String { get } 4 | } 5 | 6 | func == (lhs: OauthTokenAuthType, rhs: OauthTokenAuthType) -> Bool { 7 | type(of: lhs) == type(of: rhs) && 8 | lhs.token == rhs.token 9 | } 10 | 11 | func == (lhs: OauthTokenAuthType?, rhs: OauthTokenAuthType?) -> Bool { 12 | type(of: lhs) == type(of: rhs) && 13 | lhs?.token == rhs?.token 14 | } 15 | 16 | struct OauthToken: OauthTokenAuthType { 17 | let token: String 18 | 19 | init(token: String) { 20 | self.token = token 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/API/OurOwnBackend/Lib/Route.swift: -------------------------------------------------------------------------------- 1 | /// 数据请求的列表 2 | enum Route { 3 | case loadContacts 4 | case loadOfficialAccounts 5 | case loadUserSelf 6 | 7 | var requestProperties: 8 | (method: Method, path: String, query: [String: Any]) { 9 | switch self { 10 | case .loadContacts: 11 | return (.GET, "/users/contacts.json", [:]) 12 | 13 | case .loadOfficialAccounts: 14 | return (.GET, "/official_accounts/accounts.json", [:]) 15 | 16 | case .loadUserSelf: 17 | return (.GET, "/users/me.json", [:]) 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/API/OurOwnBackend/Service+RequestHelpers.swift: -------------------------------------------------------------------------------- 1 | import Combine 2 | import Foundation 3 | 4 | extension Service { 5 | private static let session = URLSession(configuration: .default) 6 | 7 | func request(_ route: Route) -> AnyPublisher { 8 | let properties = route.requestProperties 9 | let urlString = serverConfig.apiBaseUrl.absoluteString + properties.path 10 | 11 | guard let url = URL(string: urlString) else { 12 | return Fail(error: APIError.invalidURL(urlString)) 13 | .eraseToAnyPublisher() 14 | } 15 | 16 | print("\(url): \(properties.method) \(properties.query)") 17 | 18 | let request = preparedRequest(forURL: url, method: properties.method, query: properties.query) 19 | return Service.session 20 | .dataTaskPublisher(for: request) 21 | .requestJSON() 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Configs/Secrets.swift: -------------------------------------------------------------------------------- 1 | enum Secrets { 2 | static let isMockService = false 3 | 4 | enum Api { 5 | enum Endpoint { 6 | static let production = "https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI-Database/main" 7 | static let staging = "https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI-Database/main" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/DataModels/AccessTokenEnvelope.swift: -------------------------------------------------------------------------------- 1 | struct AccessTokenEnvelope { 2 | let accessToken: String 3 | let user: User 4 | 5 | init(accessToken: String, user: User) { 6 | self.accessToken = accessToken 7 | self.user = user 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/DataModels/ContactType.swift: -------------------------------------------------------------------------------- 1 | protocol ContactType: Identifiable { 2 | var name: String { get } 3 | var avatar: String { get } 4 | 5 | /// 在列表中的索引 6 | var index: String { get } 7 | 8 | /// 是否匹配搜索关键字 9 | func match(_ query: String) -> Bool 10 | } 11 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/DataModels/Dialog+Setters.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | extension Dialog { 4 | func setLastMessage(_ lastMessage: Message) -> Dialog { 5 | Dialog( 6 | id: id, 7 | name: name, 8 | members: members, 9 | lastMessage: lastMessage, 10 | createTime: createTime 11 | ) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/DataModels/DialogChange.swift: -------------------------------------------------------------------------------- 1 | import FirebaseFirestore 2 | 3 | struct DialogChange: Equatable { 4 | let dialog: Dialog 5 | let changeType: DocumentChangeType 6 | } 7 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/DataModels/DialogChangeTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import WeChat_SwiftUI 3 | 4 | final class DialogChangeTests: XCTestCase { 5 | func test_equatable() { 6 | let dc1 = DialogChange(dialog: .template1, changeType: .added) 7 | let dc2 = DialogChange(dialog: .template1, changeType: .modified) 8 | let dc3 = DialogChange(dialog: .empty, changeType: .modified) 9 | XCTAssertEqual(dc1, dc1) 10 | XCTAssertEqual(dc2, dc2) 11 | XCTAssertEqual(dc3, dc3) 12 | XCTAssertNotEqual(dc1, dc2) 13 | XCTAssertNotEqual(dc2, dc3) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/DataModels/DiscoverSectionTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import WeChat_SwiftUI 3 | 4 | final class DiscoverSectionTests: XCTestCase { 5 | 6 | func test_isFirstSection() { 7 | DiscoverSection.allCases 8 | .forEach { section in 9 | switch section { 10 | case .moments: 11 | XCTAssertTrue(section.isFirstSection) 12 | default: 13 | XCTAssertFalse(section.isFirstSection) 14 | } 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/DataModels/ExpressionSticker.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | struct ExpressionSticker: Decodable { 4 | let image: String 5 | let desc: Description 6 | 7 | func desciptionForCurrentLanguage() -> String { 8 | switch AppEnvironment.current.language { 9 | case .en: 10 | return desc.en 11 | case .zh: 12 | return desc.zh 13 | } 14 | } 15 | } 16 | 17 | extension ExpressionSticker { 18 | struct Description: Decodable { 19 | let en: String 20 | let zh: String 21 | } 22 | } 23 | 24 | extension ExpressionSticker: Hashable { 25 | static func == (lhs: ExpressionSticker, rhs: ExpressionSticker) -> Bool { 26 | lhs.image == rhs.image 27 | } 28 | 29 | func hash(into hasher: inout Hasher) { 30 | hasher.combine(image) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/DataModels/ExpressionStickerTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import WeChat_SwiftUI 3 | 4 | final class ExpressionStickerTests: XCTestCase { 5 | 6 | func test_equals() { 7 | XCTAssertEqual(ExpressionSticker.awesome, ExpressionSticker.awesome) 8 | XCTAssertNotEqual(ExpressionSticker.awesome, ExpressionSticker.letmesee) 9 | } 10 | 11 | func test_desciptionForCurrentLanguage() { 12 | withEnvironment(language: .en) { 13 | XCTAssertEqual( 14 | ExpressionSticker.awesome.desciptionForCurrentLanguage(), 15 | ExpressionSticker.awesome.desc.en 16 | ) 17 | } 18 | 19 | withEnvironment(language: .zh) { 20 | XCTAssertEqual( 21 | ExpressionSticker.awesome.desciptionForCurrentLanguage(), 22 | ExpressionSticker.awesome.desc.zh 23 | ) 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/DataModels/Message.Image+Setters.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | extension Message.Image { 4 | func setStatus(_ status: Message.Image.LocalImage.Status) -> Message.Image { 5 | .init(localImage: localImage?.setSatus(status)) 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/DataModels/Message.Image.LocalImage+Setters.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | extension Message.Image.LocalImage { 4 | func setSatus(_ status: Status) -> Message.Image.LocalImage { 5 | .init(uiImage: uiImage, status: status) 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/DataModels/Message.Image.URLImage.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | extension Message.Image { 4 | struct URLImage { 5 | let url: String 6 | let width: CGFloat 7 | let height: CGFloat 8 | } 9 | } 10 | 11 | extension Message.Image.URLImage: Codable { } 12 | 13 | extension Message.Image.URLImage: Equatable { } 14 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/DataModels/MessageChange.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import FirebaseFirestore 3 | 4 | struct MessageChange: Equatable { 5 | let message: Message 6 | let changeType: DocumentChangeType 7 | } 8 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/DataModels/MessageChangeTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import WeChat_SwiftUI 3 | 4 | final class MessageChangeTests: XCTestCase { 5 | func test_equatable() { 6 | let mc1 = MessageChange(message: .textTemplate, changeType: .added) 7 | let mc2 = MessageChange(message: .textTemplate, changeType: .modified) 8 | let mc3 = MessageChange(message: .textTemplate2, changeType: .modified) 9 | XCTAssertEqual(mc1, mc1) 10 | XCTAssertEqual(mc2, mc2) 11 | XCTAssertEqual(mc3, mc3) 12 | XCTAssertNotEqual(mc1, mc2) 13 | XCTAssertNotEqual(mc2, mc3) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/DataModels/OfficialAccount.swift: -------------------------------------------------------------------------------- 1 | struct OfficialAccount: Decodable, Equatable { 2 | let id: String 3 | let avatar: String 4 | let name: String 5 | let pinyin: String 6 | 7 | enum CodingKeys: String, CodingKey { 8 | case id 9 | case avatar 10 | case name 11 | case pinyin 12 | } 13 | } 14 | 15 | extension OfficialAccount: CustomDebugStringConvertible { 16 | var debugDescription: String { 17 | "OfficialAccount(id: \(id), name: \"\(name)\")" 18 | } 19 | } 20 | 21 | extension OfficialAccount: ContactType { 22 | var index: String { 23 | String(pinyin.first ?? Character("")).uppercased() 24 | } 25 | 26 | func match(_ query: String) -> Bool { 27 | let q = query.lowercased() 28 | return name.lowercased().contains(q) || 29 | pinyin.lowercased().contains(q) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/DataModels/Templates/DialogMessagesTemplates.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | extension DialogMessages { 4 | static let template1 = DialogMessages(dialogId: generateUUID(), messages: [.textTemplate]) 5 | static let template2 = DialogMessages(dialogId: generateUUID(), messages: [.textTemplate2]) 6 | } 7 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/DataModels/Templates/ExpressionStickerTemplates.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | extension ExpressionSticker { 4 | static let awesome = ExpressionSticker( 5 | image: "awesome", 6 | desc: .init(en: "Awesome", zh: "666") 7 | ) 8 | 9 | static let letmesee = ExpressionSticker( 10 | image: "letmesee", 11 | desc: .init(en: "Letmesee", zh: "让我看看") 12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/DataModels/Templates/Message.ImageTemplates.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | extension Message.Image { 4 | static let urlTemplate = Message.Image( 5 | urlImage: .init( 6 | url: "https://example.com/test.png", 7 | width: 300, 8 | height: 200 9 | ) 10 | ) 11 | 12 | static let uiImageTemplateIdle = Message.Image( 13 | uiImage: Message.Image.LocalImage.testUIImage1, 14 | status: .idle 15 | ) 16 | 17 | static let uiImageTemplateUploaded = Message.Image( 18 | uiImage: Message.Image.LocalImage.testUIImage2, 19 | status: .uploaded 20 | ) 21 | 22 | static let uiImageTemplateError = Message.Image( 23 | uiImage: Message.Image.LocalImage.testUIImage2, 24 | status: .failed(NSError.unknowError) 25 | ) 26 | } 27 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/DataModels/Templates/OfficialAccountTemplates.swift: -------------------------------------------------------------------------------- 1 | extension OfficialAccount { 2 | static let template: OfficialAccount! = tryDecode( 3 | """ 4 | { 5 | "id": "cf73ed17-20b5-4254-b67c-c6539acb4d81", 6 | "avatar": "https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI-Database/main/images/guangdongdianxin.jpeg", 7 | "name": "广东电信", 8 | "pinyin": "guangdongdianxin" 9 | } 10 | """ 11 | ) 12 | 13 | static let template2: OfficialAccount! = tryDecode( 14 | """ 15 | { 16 | "id": "93209b2a-f4d2-43b9-b173-228c417b1a8e", 17 | "avatar": "https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI-Database/main/images/kejimeixue.jpeg", 18 | "name": "科技美学", 19 | "pinyin": "kejimeixue" 20 | } 21 | """ 22 | ) 23 | } 24 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/DataModels/Templates/UserTemplates.swift: -------------------------------------------------------------------------------- 1 | extension User { 2 | static let template: User! = tryDecode( 3 | """ 4 | { 5 | "id": "112ec2a2-68d3-4949-9ce9-82ec80db9c60", 6 | "avatar": "https://cdn.nba.com/headshots/nba/latest/260x190/1629630.png", 7 | "name": "Ja Morant", 8 | "wechat_id": "ja_morant", 9 | "gender": "male", 10 | "region": "USA", 11 | "whats_up": "Hello, I'm Ja Morant!" 12 | } 13 | """ 14 | ) 15 | 16 | static let template2: User! = tryDecode( 17 | """ 18 | { 19 | "id": "4d0914d5-b04c-43f1-b37f-b2bb8d177951", 20 | "avatar": "https://cdn.nba.com/headshots/nba/latest/260x190/2544.png", 21 | "name": "LeBron James", 22 | "wechat_id": "lebron_james", 23 | "gender": "male", 24 | "region": "USA", 25 | "whats_up": "Hello, I'm LeBron James!" 26 | } 27 | """ 28 | ) 29 | } 30 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/CancelBag.swift: -------------------------------------------------------------------------------- 1 | import Combine 2 | 3 | /// 存储订阅的工具类 4 | final class CancelBag { 5 | var subscriptions = Set() 6 | 7 | func cancel() { 8 | subscriptions.forEach { $0.cancel() } 9 | subscriptions.removeAll() 10 | } 11 | } 12 | 13 | extension AnyCancellable { 14 | 15 | func store(in cancelBag: CancelBag) { 16 | cancelBag.subscriptions.insert(self) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/Components/ActivityIndicator.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct ActivityIndicator: View { 4 | 5 | private let style: Style 6 | 7 | init(style: Style = .medium) { 8 | self.style = style 9 | } 10 | 11 | var body: some View { 12 | ProgressView() 13 | .progressViewStyle(.circular) 14 | .scaleEffect(style.scale) 15 | } 16 | } 17 | 18 | extension ActivityIndicator { 19 | enum Style { 20 | case large 21 | case medium 22 | 23 | var scale: Double { 24 | switch self { 25 | case .large: 26 | return 1.8 27 | case .medium: 28 | return 1 29 | } 30 | } 31 | } 32 | } 33 | 34 | struct ActivityIndicator_Previews: PreviewProvider { 35 | static var previews: some View { 36 | ActivityIndicator(style: .medium) 37 | ActivityIndicator(style: .large) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/Components/ErrorView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct ErrorView: View { 4 | let error: Error 5 | let retryAction: () -> Void 6 | 7 | var body: some View { 8 | VStack { 9 | Text(Strings.general_an_error_occured()) 10 | .font(.title) 11 | Text((error as? APIError)?.localizedDescription ?? error.localizedDescription) 12 | .font(.callout) 13 | .multilineTextAlignment(.center) 14 | .padding(.bottom, 40) 15 | .padding() 16 | Button(action: retryAction) { Text(Strings.general_retry()).bold() } 17 | } 18 | } 19 | } 20 | 21 | #if DEBUG 22 | struct ErrorView_Previews: PreviewProvider { 23 | static var previews: some View { 24 | ErrorView( 25 | error: NSError.commonError(description: Strings.general_something_went_wrong()), 26 | retryAction: { } 27 | ) 28 | } 29 | } 30 | #endif 31 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/Components/SectionHeaderBackground.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct SectionHeaderBackground: View { 4 | let color: Color 5 | 6 | init(_ color: Color = .app_bg) { 7 | self.color = color 8 | } 9 | 10 | var body: some View { 11 | color 12 | .listRowInsets(.zero) 13 | .listRowSeparator(.hidden) 14 | } 15 | } 16 | 17 | struct SectionHeaderBackground_Previews: PreviewProvider { 18 | static var previews: some View { 19 | SectionHeaderBackground() 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/Components/SectionHeaderTitle.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct SectionHeaderTitle: View { 4 | let title: String 5 | 6 | var body: some View { 7 | Text(title) 8 | .foregroundColor(.text_info_200) 9 | .font(.system(size: 14, weight: .medium)) 10 | .padding(EdgeInsets(top: 5, leading: 20, bottom: 5, trailing: 0)) 11 | .frame(width: UIScreen.main.bounds.width, alignment: .leading) 12 | .background(.app_bg) 13 | .padding(.vertical, -7) // remove the vertical margin 14 | } 15 | } 16 | 17 | struct SectionHeaderTitle_Previews: PreviewProvider { 18 | static var previews: some View { 19 | SectionHeaderTitle(title: "Hello") 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/Constants.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | enum Constant { 4 | static let jsonDecoder: JSONDecoder = { 5 | let decoder = JSONDecoder() 6 | decoder.dateDecodingStrategy = .iso8601 7 | return decoder 8 | }() 9 | 10 | static let jsonEncoder: JSONEncoder = { 11 | let encoder = JSONEncoder() 12 | encoder.dateEncodingStrategy = .iso8601 13 | return encoder 14 | }() 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/EnvironmentTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import WeChat_SwiftUI 3 | 4 | final class EnvironmentTests: XCTestCase { 5 | func test_defaults() { 6 | let env = Environment() 7 | 8 | XCTAssertTrue(env.apiService == Service()) 9 | XCTAssertNil(env.currentUser) 10 | XCTAssertEqual(env.language, Language(languageStrings: Locale.preferredLanguages)) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/Errors.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | extension NSError { 4 | static var unknowError: Error { 5 | NSError( 6 | domain: "", 7 | code: -1, 8 | userInfo: [NSLocalizedDescriptionKey: Strings.general_unknown_error()] 9 | ) 10 | } 11 | 12 | static func commonError(description: String) -> NSError { 13 | NSError( 14 | domain: "", 15 | code: -1, 16 | userInfo: [NSLocalizedDescriptionKey: description] 17 | ) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/Extensions/AnyPublisher+Initializers.swift: -------------------------------------------------------------------------------- 1 | import Combine 2 | import Foundation 3 | 4 | extension AnyPublisher { 5 | static func publisher(output: T) -> AnyPublisher { 6 | Just 7 | .withErrorType(Error.self) 8 | .map { output } 9 | .eraseToAnyPublisher() 10 | } 11 | 12 | static func publisher(failure: Error) -> AnyPublisher { 13 | Fail(error: failure) 14 | .eraseToAnyPublisher() 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/Extensions/CGSize+AspectSize.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | extension CGSize { 4 | /// 返回在给定的 size 内的等比例缩放的最大 size 5 | func aspectSize(fitsSize size: CGSize) -> CGSize { 6 | let heightFitsWidth = (size.width * height) / width 7 | 8 | if heightFitsWidth > size.height { 9 | let widthFitsHeight = (size.height * width) / height 10 | return .init(width: widthFitsHeight, height: size.height) 11 | } 12 | 13 | return .init(width: size.width, height: heightFitsWidth) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/Extensions/CGSize+AspectSizeTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import SwiftUI 3 | @testable import WeChat_SwiftUI 4 | 5 | final class CGSize_AspectSizeTests: XCTestCase { 6 | func test_aspectSizeFitsSize() { 7 | let containerSize = CGSize(width: 10, height: 20) 8 | 9 | var originalSize = CGSize(width: 20, height: 30) 10 | var expectedSize = CGSize(width: 10, height: 15) 11 | XCTAssertEqual(originalSize.aspectSize(fitsSize: containerSize), expectedSize) 12 | 13 | originalSize = CGSize(width: 20, height: 50) 14 | expectedSize = CGSize(width: 8, height: 20) 15 | XCTAssertEqual(originalSize.aspectSize(fitsSize: containerSize), expectedSize) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/Extensions/Collection+Matching.swift: -------------------------------------------------------------------------------- 1 | extension Collection where Element: Identifiable { 2 | func index(matching element: Element) -> Self.Index? { 3 | firstIndex(where: { $0.id == element.id }) 4 | } 5 | 6 | func element(matching element: Element) -> Element { 7 | first(where: { $0.id == element.id }) ?? element 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/Extensions/Dictionary+Data.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | extension Dictionary { 4 | var data: Data? { 5 | try? JSONSerialization.data(withJSONObject: self) 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/Extensions/EdgeInsets.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | extension EdgeInsets { 4 | static var zero: EdgeInsets { 5 | .init(top: 0, leading: 0, bottom: 0, trailing: 0) 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/Extensions/EdgeInsetsTests.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | import XCTest 3 | @testable import WeChat_SwiftUI 4 | 5 | final class EdgeInsetsTests: XCTestCase { 6 | 7 | func test_zero() { 8 | XCTAssertEqual(EdgeInsets.zero.top, 0) 9 | XCTAssertEqual(EdgeInsets.zero.leading, 0) 10 | XCTAssertEqual(EdgeInsets.zero.bottom, 0) 11 | XCTAssertEqual(EdgeInsets.zero.trailing, 0) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/Extensions/Encodable+Dictionary.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | extension Encodable { 4 | var dictionaryRepresentation: [String: Any]? { 5 | guard let data = try? Constant.jsonEncoder.encode(self) else { 6 | return nil 7 | } 8 | return (try? JSONSerialization.jsonObject(with: data, options: .allowFragments)) 9 | .flatMap { $0 as? [String: Any] } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/Extensions/Image+Constants.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | extension Image { 4 | static let avatarPlaceholder = Image("icons_filled_fts_default_headimage") 5 | } 6 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/Extensions/Image+Resize.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | extension Image { 4 | 5 | func resize( 6 | _ contentMode: ContentMode = .fill, 7 | _ size: CGSize? = nil 8 | ) -> some View { 9 | 10 | let content = resizable().aspectRatio(contentMode: contentMode) 11 | 12 | if let size = size { 13 | return content.frame(width: size.width, height: size.height).asAnyView() 14 | } 15 | 16 | return content.asAnyView() 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/Extensions/String+Height.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | extension String { 4 | func height(withConstrainedWidth width: CGFloat, font: UIFont) -> CGFloat { 5 | let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude) 6 | let boundingRect = self.boundingRect( 7 | with: constraintRect, 8 | options: [.usesLineFragmentOrigin, .usesFontLeading], 9 | attributes: [.font: font], 10 | context: nil 11 | ) 12 | return ceil(boundingRect.height) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/Extensions/String+Identifiable.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | extension String: Identifiable { 4 | public var id: String { self } 5 | } 6 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/Extensions/UIApplication+EndEditing.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | extension UIApplication { 4 | var keyWindow: UIWindow? { 5 | UIApplication.shared.connectedScenes 6 | .filter({ $0.activationState == .foregroundActive }) 7 | .compactMap({ $0 as? UIWindowScene }) 8 | .first?.windows 9 | .filter({ $0.isKeyWindow }).first 10 | } 11 | 12 | func endEditing(_ force: Bool) { 13 | keyWindow?.endEditing(force) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/Extensions/UIImage+InitWithColor.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | extension UIImage { 4 | convenience init?(color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) { 5 | let rect = CGRect(origin: .zero, size: size) 6 | UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0) 7 | 8 | color.setFill() 9 | UIRectFill(rect) 10 | 11 | let image = UIGraphicsGetImageFromCurrentImageContext() 12 | UIGraphicsEndImageContext() 13 | 14 | guard let cgImage = image?.cgImage else { 15 | return nil 16 | } 17 | 18 | self.init(cgImage: cgImage) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/Extensions/View+AsAnyView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | extension View { 4 | func asAnyView() -> AnyView { 5 | AnyView(self) 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/Firebase/FirebaseStorageServiceType.swift: -------------------------------------------------------------------------------- 1 | import Combine 2 | import Foundation 3 | 4 | protocol FirebaseStorageServiceType { 5 | func uploadAvatar(data: Data, format: ImageFormat) -> AnyPublisher 6 | 7 | func uploadImageData( 8 | _ data: Data, 9 | for message: Message, 10 | in format: ImageFormat, 11 | progress: @escaping ((Double) -> Void) 12 | ) -> AnyPublisher 13 | } 14 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/Firebase/FirestoreReferenceFactory.swift: -------------------------------------------------------------------------------- 1 | import FirebaseFirestore 2 | 3 | enum FirestoreReferenceFactory { 4 | static func reference(for type: FirestoreReferenceType) -> CollectionReference { 5 | Firestore.firestore().collection(type.pathComponents.joined(separator: "/")) 6 | } 7 | } 8 | 9 | enum FirestoreReferenceType { 10 | case dialogs 11 | case dialogMessages(dialogId: String) 12 | case officialAccounts 13 | case users 14 | 15 | var pathComponents: [String] { 16 | switch self { 17 | case .dialogs: 18 | return ["dialogs"] 19 | case .dialogMessages(let dialogId): 20 | return ["dialogs", dialogId, "messages"] 21 | case .officialAccounts: 22 | return ["official-accounts"] 23 | case .users: 24 | return ["users"] 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/GenerateUUID.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | func generateUUID() -> String { 4 | UUID().uuidString.lowercased() 5 | } 6 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/Haptics.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | enum Haptics { 4 | static func impact(_ style: UIImpactFeedbackGenerator.FeedbackStyle) { 5 | let generator = UIImpactFeedbackGenerator(style: style) 6 | generator.impactOccurred() 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/ImageFormat.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | enum ImageFormat { 4 | case png 5 | case jpg 6 | 7 | var fileExtension: String { 8 | switch self { 9 | case .png: return "png" 10 | case .jpg: return "jpg" 11 | } 12 | } 13 | 14 | var contentType: String { 15 | switch self { 16 | case .png: return "image/png" 17 | case .jpg: return "image/jpeg" 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/KeyValueStoreKey.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | enum KeyValueStoreKey: String { 4 | case appEnvironment 5 | case appState 6 | 7 | var key: String { 8 | "com.WeChat-SwiftUI.\(rawValue)" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/Language.swift: -------------------------------------------------------------------------------- 1 | /// 应用所支持的语言 2 | enum Language: String { 3 | case en 4 | case zh 5 | 6 | init?(languageString language: String) { 7 | switch language.lowercased() { 8 | case "en": self = .en 9 | case "zh": self = .zh 10 | default: return nil 11 | } 12 | } 13 | 14 | init?(languageStrings languages: [String]) { 15 | guard let language = languages 16 | .lazy 17 | .map({ String($0.prefix(2)) }) 18 | .compactMap(Language.init(languageString:)) 19 | .first else { 20 | return nil 21 | } 22 | 23 | self = language 24 | } 25 | 26 | var displayString: String { 27 | switch self { 28 | case .en: return "English" 29 | case .zh: return "简体中文" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/LanguageTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import WeChat_SwiftUI 3 | 4 | final class LanguageTests: XCTestCase { 5 | 6 | func test_initializer() { 7 | XCTAssertEqual(Language.en, Language(languageString: "En")) 8 | XCTAssertEqual(Language.zh, Language(languageString: "Zh")) 9 | XCTAssertEqual(nil, Language(languageString: "AB")) 10 | } 11 | 12 | func test_languageFromLanguageStrings() { 13 | XCTAssertEqual(Language.en, Language(languageStrings: ["AB", "EN", "FR"])) 14 | XCTAssertEqual(Language.zh, Language(languageStrings: ["AB", "BC", "ZH"])) 15 | XCTAssertEqual(nil, Language(languageStrings: ["AB", "BC", "CD"])) 16 | } 17 | 18 | func test_displayString() { 19 | XCTAssertEqual(Language.en.displayString, "English") 20 | XCTAssertEqual(Language.zh.displayString, "简体中文") 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/Modifiers/ResignKeyboardOnDragModifier.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | extension View { 4 | func resignKeyboardOnDrag(onResign: @escaping () -> Void = {}) -> some View { 5 | modifier(ResignKeyboardOnDrag(onResign: onResign)) 6 | } 7 | } 8 | 9 | private struct ResignKeyboardOnDrag: ViewModifier { 10 | 11 | let onResign: () -> Void 12 | 13 | func body(content: Content) -> some View { 14 | content 15 | .gesture( 16 | DragGesture() 17 | .onChanged { _ in 18 | UIApplication.shared.endEditing(true) 19 | onResign() 20 | } 21 | ) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/Modifiers/ResignKeyboardOnTapModifier.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | extension View { 4 | func resignKeyboardOnTap(onResign: @escaping () -> Void = {}) -> some View { 5 | modifier(ResignKeyboardOnTap(onResign: onResign)) 6 | } 7 | } 8 | 9 | private struct ResignKeyboardOnTap: ViewModifier { 10 | 11 | let onResign: () -> Void 12 | 13 | func body(content: Content) -> some View { 14 | content 15 | .gesture( 16 | TapGesture() 17 | .onEnded({ 18 | UIApplication.shared.endEditing(true) 19 | onResign() 20 | }) 21 | ) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/NSBundleType.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | protocol NSBundleType { 4 | static func create(path: String) -> NSBundleType? 5 | func path(forResource name: String?, ofType ext: String?) -> String? 6 | func localizedString(forKey key: String, value: String?, table tableName: String?) -> String 7 | } 8 | 9 | extension Bundle: NSBundleType { 10 | static func create(path: String) -> NSBundleType? { 11 | return Bundle(path: path) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/ObjectBox.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// 把一个对象包装在此类型中,用于把这个对象传递给 `view` 的子层级 4 | final class ObjectBox: ObservableObject { 5 | let value: T 6 | 7 | init(value: T) { 8 | self.value = value 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/PhotoPickerType.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | enum PhotoPickerType: Identifiable { 4 | case camera 5 | case library 6 | 7 | var id: PhotoPickerType { self } 8 | } 9 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/PresentationStyle.swift: -------------------------------------------------------------------------------- 1 | enum PresentationStyle { 2 | case modal 3 | case push 4 | } 5 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/TestHelpers/AppStateDataSource.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import XCTest 3 | @testable import WeChat_SwiftUI 4 | 5 | protocol AppStateDataSource { 6 | func preparedAppState(dialogs: [Dialog], dialogMessages: Set) -> AppState 7 | } 8 | 9 | extension AppStateDataSource where Self: XCTestCase { 10 | func preparedAppState(dialogs: [Dialog], dialogMessages: Set) -> AppState { 11 | var appState: AppState = .preview 12 | appState.chatsState.dialogs = dialogs 13 | appState.chatsState.dialogMessages = dialogMessages 14 | return appState 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/TestHelpers/MessagesDataSource.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import XCTest 3 | @testable import WeChat_SwiftUI 4 | 5 | protocol MessagesDataSource { 6 | func sortedMessages() -> (Message, Message, Message) 7 | } 8 | 9 | extension MessagesDataSource where Self: XCTestCase { 10 | func sortedMessages() -> (Message, Message, Message) { 11 | let now = Date() 12 | let m1 = Message(text: "1", createTime: now) 13 | let m2 = Message(text: "2", createTime: now.addingTimeInterval(10)) 14 | let m3 = Message(text: "3", createTime: now.addingTimeInterval(20)) 15 | return (m1, m2, m3) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/TestHelpers/XCTestCase+Wait.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | extension XCTestCase { 4 | func wait(interval: TimeInterval = 0.1, completion: @escaping (() -> Void)) { 5 | let exp = expectation(description: "") 6 | DispatchQueue.main.asyncAfter(deadline: .now() + interval) { 7 | completion() 8 | exp.fulfill() 9 | } 10 | waitForExpectations(timeout: interval + 0.2) // add 0.2 for sure async after called 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/TryDecodable.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | func tryDecode(_ primitive: Any) -> T? { 4 | guard 5 | let data = try? JSONSerialization.data(withJSONObject: primitive, options: []), 6 | let value = try? Constant.jsonDecoder.decode(T.self, from: data) 7 | else { return nil } 8 | 9 | return value 10 | } 11 | 12 | func tryDecode(_ jsonString: String) -> T? { 13 | guard 14 | let data = jsonString.data(using: .utf8), 15 | let value = try? Constant.jsonDecoder.decode(T.self, from: data) 16 | else { return nil } 17 | 18 | return value 19 | } 20 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Library/WaitAndExecute.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | func wait(interval: TimeInterval = 1, execute block: @escaping () -> Void) { 4 | DispatchQueue.main.asyncAfter(deadline: .now() + interval, execute: block) 5 | } 6 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/PreviewContent/PreviewAssets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/PreviewContent/PreviewAssets.xcassets/IMG_0001.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "IMG_0001.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/PreviewContent/PreviewAssets.xcassets/IMG_0001.imageset/IMG_0001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/PreviewContent/PreviewAssets.xcassets/IMG_0001.imageset/IMG_0001.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/PreviewContent/PreviewAssets.xcassets/IMG_0002.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "IMG_0002.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/PreviewContent/PreviewAssets.xcassets/IMG_0002.imageset/IMG_0002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/PreviewContent/PreviewAssets.xcassets/IMG_0002.imageset/IMG_0002.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/PreviewContent/PreviewAssets.xcassets/IMG_0003.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "IMG_0003.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/PreviewContent/PreviewAssets.xcassets/IMG_0003.imageset/IMG_0003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/PreviewContent/PreviewAssets.xcassets/IMG_0003.imageset/IMG_0003.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/PreviewContent/PreviewAssets.xcassets/IMG_0004.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "IMG_0004.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/PreviewContent/PreviewAssets.xcassets/IMG_0004.imageset/IMG_0004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/PreviewContent/PreviewAssets.xcassets/IMG_0004.imageset/IMG_0004.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/PreviewContent/PreviewAssets.xcassets/IMG_0005.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "IMG_0005.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/PreviewContent/PreviewAssets.xcassets/IMG_0005.imageset/IMG_0005.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/PreviewContent/PreviewAssets.xcassets/IMG_0005.imageset/IMG_0005.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Redux/Actions/AuthActions.swift: -------------------------------------------------------------------------------- 1 | import SwiftUIRedux 2 | 3 | enum AuthActions { 4 | private static let cancelBag = CancelBag() 5 | 6 | struct LoadUserSelf: AsyncAction, Equatable { 7 | func async(dispatch: @escaping Dispatch, state: ReduxState?) { 8 | AppEnvironment.current.firestoreService 9 | .loadUserSelf() 10 | .sinkToResultForUI { result in 11 | if case .success(let user) = result { 12 | dispatch(SetSignedInUser(user: user)) 13 | } 14 | } 15 | .store(in: cancelBag) 16 | } 17 | 18 | static func == (lhs: AuthActions.LoadUserSelf, rhs: AuthActions.LoadUserSelf) -> Bool { 19 | true 20 | } 21 | } 22 | 23 | struct SetSignedInUser: Action, Equatable { 24 | let user: User? 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Redux/Actions/RootActions.swift: -------------------------------------------------------------------------------- 1 | import SwiftUIRedux 2 | 3 | enum RootActions { 4 | struct SetSelectedTab: Action { 5 | let tab: TabBarItem 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Redux/Actions/SystemActions.swift: -------------------------------------------------------------------------------- 1 | import SwiftUIRedux 2 | 3 | enum SystemActions { 4 | struct SetErrorMessage: Action, Equatable { 5 | let message: String? 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Redux/MockStore.swift: -------------------------------------------------------------------------------- 1 | import SwiftUIRedux 2 | 3 | final class MockStore: Store { 4 | 5 | private(set) var actions: [Action] = [] 6 | 7 | override func dispatch(action: Action) { 8 | actions.append(action) 9 | super.dispatch(action: action) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Redux/Reducers/AppReducer.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import SwiftUIRedux 3 | 4 | func appStateReducer(state: AppState, action: Action) -> AppState { 5 | var newState = state 6 | newState.authState = authStateReducer(state: state.authState, action: action) 7 | newState.chatsState = chatsStateReducer(state: state.chatsState, action: action) 8 | newState.contactsState = contactsStateReducer(state: state.contactsState, action: action) 9 | newState.rootState = rootStateReducer(state: state.rootState, action: action) 10 | newState.systemState = systemStateReducer(state: state.systemState, action: action) 11 | return newState 12 | } 13 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Redux/Reducers/AuthReducer.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import SwiftUIRedux 3 | 4 | func authStateReducer(state: AuthState, action: Action) -> AuthState { 5 | var newState = state 6 | switch action { 7 | case let action as AuthActions.SetSignedInUser: 8 | newState.signedInUser = action.user 9 | 10 | if let user = action.user { 11 | // token is unnecessary for firestoreService, but we set it to make AppEnvironment works 12 | let tokenEnvelope = AccessTokenEnvelope(accessToken: "deadbeef", user: user) 13 | AppEnvironment.login(tokenEnvelope) 14 | } else { 15 | AppEnvironment.logout() 16 | } 17 | 18 | default: 19 | break 20 | } 21 | return newState 22 | } 23 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Redux/Reducers/AuthReducerTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import SwiftUIRedux 3 | @testable import WeChat_SwiftUI 4 | 5 | final class AuthReducerTests: XCTestCase { 6 | 7 | private var store: Store! 8 | 9 | override func setUp() { 10 | super.setUp() 11 | store = Store(initialState: AppState(), reducer: appStateReducer) 12 | } 13 | 14 | override func tearDown() { 15 | super.tearDown() 16 | store = nil 17 | } 18 | 19 | func test_handleSetSignedInUser() { 20 | store.dispatch(action: AuthActions.SetSignedInUser(user: .template)) 21 | XCTAssertEqual(store.state.authState.signedInUser, .template) 22 | 23 | store.dispatch(action: AuthActions.SetSignedInUser(user: nil)) 24 | XCTAssertEqual(store.state.authState.signedInUser, nil) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Redux/Reducers/ContactsReducer.swift: -------------------------------------------------------------------------------- 1 | import SwiftUIRedux 2 | 3 | func contactsStateReducer(state: ContactsState, action: Action) -> ContactsState { 4 | var newState = state 5 | switch action { 6 | case let action as ContactsActions.SetContacts: 7 | newState.contacts = action.contacts 8 | case let action as ContactsActions.SetOfficialAccounts: 9 | newState.officialAccounts = action.accounts 10 | default: 11 | break 12 | } 13 | return newState 14 | } 15 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Redux/Reducers/RootReducer.swift: -------------------------------------------------------------------------------- 1 | import SwiftUIRedux 2 | 3 | func rootStateReducer(state: RootState, action: Action) -> RootState { 4 | var newState = state 5 | switch action { 6 | case let action as RootActions.SetSelectedTab: 7 | newState.selectedTab = action.tab 8 | default: 9 | break 10 | } 11 | return newState 12 | } 13 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Redux/Reducers/RootReducerTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import SwiftUIRedux 3 | @testable import WeChat_SwiftUI 4 | 5 | final class RootReducerTests: XCTestCase { 6 | 7 | private var store: Store! 8 | 9 | override func setUp() { 10 | super.setUp() 11 | store = Store(initialState: AppState(), reducer: appStateReducer) 12 | } 13 | 14 | override func tearDown() { 15 | super.tearDown() 16 | store = nil 17 | } 18 | 19 | func test_handleSetSelectedTab() { 20 | store.dispatch(action: RootActions.SetSelectedTab(tab: .chats)) 21 | XCTAssertEqual(store.state.rootState.selectedTab, .chats) 22 | 23 | store.dispatch(action: RootActions.SetSelectedTab(tab: .contacts)) 24 | XCTAssertEqual(store.state.rootState.selectedTab, .contacts) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Redux/Reducers/SystemReducer.swift: -------------------------------------------------------------------------------- 1 | import SwiftUIRedux 2 | 3 | func systemStateReducer(state: SystemState, action: Action) -> SystemState { 4 | var newState = state 5 | switch action { 6 | case let action as SystemActions.SetErrorMessage: 7 | newState.errorMessage = action.message 8 | default: 9 | break 10 | } 11 | return newState 12 | } 13 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Redux/Reducers/SystemReducerTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import SwiftUIRedux 3 | @testable import WeChat_SwiftUI 4 | 5 | final class SystemReducerTests: XCTestCase { 6 | 7 | private var store: Store! 8 | 9 | override func setUp() { 10 | super.setUp() 11 | store = Store(initialState: AppState(), reducer: appStateReducer) 12 | } 13 | 14 | override func tearDown() { 15 | super.tearDown() 16 | store = nil 17 | } 18 | 19 | func test_handleSetErrorMessage() { 20 | store.dispatch(action: SystemActions.SetErrorMessage(message: "something went wrong")) 21 | XCTAssertEqual(store.state.systemState.errorMessage, "something went wrong") 22 | 23 | store.dispatch(action: SystemActions.SetErrorMessage(message: nil)) 24 | XCTAssertEqual(store.state.systemState.errorMessage, nil) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Redux/State/AuthState.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | struct AuthState: Codable, Equatable { 4 | var signedInUser: User? 5 | } 6 | 7 | #if DEBUG 8 | extension AuthState { 9 | static var preview: AuthState { 10 | AuthState( 11 | signedInUser: nil 12 | ) 13 | } 14 | } 15 | #endif 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Redux/State/AuthStateTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import WeChat_SwiftUI 3 | 4 | final class AuthStateTests: XCTestCase { 5 | 6 | func test_equals() { 7 | let state1 = AuthState(signedInUser: nil) 8 | let state2 = AuthState(signedInUser: .template) 9 | XCTAssertEqual(state1, state1) 10 | XCTAssertEqual(state2, state2) 11 | XCTAssertNotEqual(state1, state2) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Redux/State/ChatsStateTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import WeChat_SwiftUI 3 | 4 | final class ChatsStateTests: XCTestCase { 5 | 6 | func test_equals() { 7 | let state1 = ChatsState(dialogs: [.template1], dialogMessages: [.template1]) 8 | let state2 = ChatsState(dialogs: [.empty], dialogMessages: [.template2]) 9 | XCTAssertEqual(state1, state1) 10 | XCTAssertEqual(state2, state2) 11 | XCTAssertNotEqual(state1, state2) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Redux/State/ContactsState.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | struct ContactsState: Equatable { 4 | var categories: [ContactCategory] 5 | var contacts: Loadable<[User]> 6 | var officialAccounts: Loadable<[OfficialAccount]> 7 | } 8 | 9 | #if DEBUG 10 | extension ContactsState { 11 | static var preview: ContactsState { 12 | ContactsState( 13 | categories: ContactCategory.allCases, 14 | contacts: .notRequested, 15 | officialAccounts: .notRequested 16 | ) 17 | } 18 | } 19 | #endif 20 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Redux/State/ContactsStateTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import WeChat_SwiftUI 3 | 4 | final class ContactsStateTests: XCTestCase { 5 | 6 | func test_equals() { 7 | let state1 = ContactsState( 8 | categories: ContactCategory.allCases, 9 | contacts: .notRequested, 10 | officialAccounts: .notRequested 11 | ) 12 | let state2 = ContactsState( 13 | categories: [], 14 | contacts: .isLoading(last: nil, cancelBag: CancelBag()), 15 | officialAccounts: .isLoading(last: nil, cancelBag: CancelBag()) 16 | ) 17 | XCTAssertEqual(state1, state1) 18 | XCTAssertEqual(state2, state2) 19 | XCTAssertNotEqual(state1, state2) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Redux/State/DiscoverState.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | struct DiscoverState: Equatable { 4 | var discoverSections: [DiscoverSection] 5 | } 6 | 7 | #if DEBUG 8 | extension DiscoverState { 9 | static var preview: DiscoverState { 10 | DiscoverState( 11 | discoverSections: DiscoverSection.allCases 12 | ) 13 | } 14 | } 15 | #endif 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Redux/State/DiscoverStateTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import WeChat_SwiftUI 3 | 4 | final class DiscoverStateTests: XCTestCase { 5 | 6 | func test_equals() { 7 | let state1 = DiscoverState(discoverSections: DiscoverSection.allCases) 8 | let state2 = DiscoverState(discoverSections: []) 9 | XCTAssertEqual(state1, state1) 10 | XCTAssertEqual(state2, state2) 11 | XCTAssertNotEqual(state1, state2) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Redux/State/RootState.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | struct RootState: Equatable { 4 | var selectedTab: TabBarItem 5 | } 6 | 7 | #if DEBUG 8 | extension RootState { 9 | static var preview: RootState { 10 | RootState( 11 | selectedTab: .chats 12 | ) 13 | } 14 | } 15 | #endif 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Redux/State/RootStateTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import WeChat_SwiftUI 3 | 4 | final class RootStateTests: XCTestCase { 5 | 6 | func test_equals() { 7 | let state1 = RootState(selectedTab: .chats) 8 | let state2 = RootState(selectedTab: .contacts) 9 | XCTAssertEqual(state1, state1) 10 | XCTAssertEqual(state2, state2) 11 | XCTAssertNotEqual(state1, state2) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Redux/State/SystemState.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | struct SystemState: Equatable { 4 | var errorMessage: String? 5 | } 6 | 7 | #if DEBUG 8 | extension SystemState { 9 | static var preview: SystemState { 10 | SystemState( 11 | errorMessage: nil 12 | ) 13 | } 14 | } 15 | #endif 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Redux/State/SystemStateTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import WeChat_SwiftUI 3 | 4 | final class SystemStateTests: XCTestCase { 5 | 6 | func test_equals() { 7 | let state1 = SystemState(errorMessage: nil) 8 | let state2 = SystemState(errorMessage: "error") 9 | XCTAssertEqual(state1, state1) 10 | XCTAssertEqual(state2, state2) 11 | XCTAssertNotEqual(state1, state2) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Redux/Store.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | import SwiftUIRedux 3 | 4 | let store = Store(initialState: AppState(), reducer: appStateReducer) 5 | 6 | // MARK: - Global Dispatch 7 | extension View { 8 | func updateSignedInUser(_ user: User?) { 9 | store.dispatch(action: AuthActions.SetSignedInUser(user: user)) 10 | } 11 | 12 | func setErrorMessage(_ message: String) { 13 | store.dispatch(action: SystemActions.SetErrorMessage(message: message)) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon_1024.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon_120-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon_120-1.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon_120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon_120.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon_180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon_180.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon_40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon_40.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon_58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon_58.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon_60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon_60.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon_80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon_80.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon_87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon_87.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/colors/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/colors/app_bg.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.929", 9 | "green" : "0.929", 10 | "red" : "0.929" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.067", 27 | "green" : "0.067", 28 | "red" : "0.067" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/colors/app_white.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "1.000", 9 | "green" : "1.000", 10 | "red" : "1.000" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.098", 27 | "green" : "0.098", 28 | "red" : "0.098" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/colors/bg_info_100.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.969", 9 | "green" : "0.969", 10 | "red" : "0.969" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.125", 27 | "green" : "0.125", 28 | "red" : "0.125" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/colors/bg_info_150.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.961", 9 | "green" : "0.961", 10 | "red" : "0.961" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.110", 27 | "green" : "0.110", 28 | "red" : "0.110" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/colors/bg_info_170.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.925", 9 | "green" : "0.925", 10 | "red" : "0.925" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.090", 27 | "green" : "0.090", 28 | "red" : "0.090" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/colors/bg_info_200.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.898", 9 | "green" : "0.898", 10 | "red" : "0.898" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.145", 27 | "green" : "0.145", 28 | "red" : "0.145" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/colors/highlighted.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.435", 9 | "green" : "0.741", 10 | "red" : "0.424" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/colors/link.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.569", 9 | "green" : "0.420", 10 | "red" : "0.357" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/colors/text_info_500.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.333", 9 | "green" : "0.333", 10 | "red" : "0.333" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/aaagh!.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "aaagh!@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/aaagh!.imageset/aaagh!@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/aaagh!.imageset/aaagh!@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/angry.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "angry@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/angry.imageset/angry@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/angry.imageset/angry@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/awesome.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "awesome@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/awesome.imageset/awesome@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/awesome.imageset/awesome@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/awkward.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "awkward@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/awkward.imageset/awkward@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/awkward.imageset/awkward@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/bah!l.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "bah!l@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/bah!l.imageset/bah!l@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/bah!l.imageset/bah!l@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/bah!r.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "bah!r@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/bah!r.imageset/bah!r@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/bah!r.imageset/bah!r@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/beckon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "beckon@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/beckon.imageset/beckon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/beckon.imageset/beckon@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/beer.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "beer@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/beer.imageset/beer@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/beer.imageset/beer@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/blessing.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "blessing@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/blessing.imageset/blessing@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/blessing.imageset/blessing@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/blush.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "blush@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/blush.imageset/blush@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/blush.imageset/blush@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/bomb.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "bomb@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/bomb.imageset/bomb@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/bomb.imageset/bomb@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/boring.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "boring@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/boring.imageset/boring@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/boring.imageset/boring@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/broken.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "broken@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/broken.imageset/broken@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/broken.imageset/broken@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/brokenheart.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "brokenheart@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/brokenheart.imageset/brokenheart@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/brokenheart.imageset/brokenheart@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/bye.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "bye@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/bye.imageset/bye@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/bye.imageset/bye@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/cake.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "cake@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/cake.imageset/cake@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/cake.imageset/cake@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/chuckle.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "chuckle@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/chuckle.imageset/chuckle@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/chuckle.imageset/chuckle@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/clap.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "clap@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/clap.imageset/clap@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/clap.imageset/clap@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/cleaver.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "cleaver@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/cleaver.imageset/cleaver@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/cleaver.imageset/cleaver@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/coffee.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "coffee@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/coffee.imageset/coffee@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/coffee.imageset/coffee@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/commando.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "commando@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/commando.imageset/commando@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/commando.imageset/commando@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/concerned.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "concerned@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/concerned.imageset/concerned@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/concerned.imageset/concerned@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/coolguy.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "coolguy@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/coolguy.imageset/coolguy@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/coolguy.imageset/coolguy@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/cry.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "cry0@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/cry.imageset/cry0@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/cry.imageset/cry0@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/determined.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "determined@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/determined.imageset/determined@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/determined.imageset/determined@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/dizzy.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "dizzy@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/dizzy.imageset/dizzy@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/dizzy.imageset/dizzy@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/doge.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "doge@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/doge.imageset/doge@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/doge.imageset/doge@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/drool.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "drool@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/drool.imageset/drool@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/drool.imageset/drool@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/drowsy.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "drowsy@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/drowsy.imageset/drowsy@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/drowsy.imageset/drowsy@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/emm.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "emm@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/emm.imageset/emm@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/emm.imageset/emm@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/facepalm.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "facepalm@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/facepalm.imageset/facepalm@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/facepalm.imageset/facepalm@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/fist.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "fist@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/fist.imageset/fist@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/fist.imageset/fist@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/frown.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "frown@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/frown.imageset/frown@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/frown.imageset/frown@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/goforit.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "goforit@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/goforit.imageset/goforit@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/goforit.imageset/goforit@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/grimace.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "grimace@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/grimace.imageset/grimace@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/grimace.imageset/grimace@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/grin.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "grin@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/grin.imageset/grin@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/grin.imageset/grin@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/hammer.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "hammer@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/hammer.imageset/hammer@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/hammer.imageset/hammer@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/heart.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "heart@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/heart.imageset/heart@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/heart.imageset/heart@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/hey.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "hey@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/hey.imageset/hey@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/hey.imageset/hey@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/hug.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "hug@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/hug.imageset/hug@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/hug.imageset/hug@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/hurt.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "hurt@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/hurt.imageset/hurt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/hurt.imageset/hurt@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/joyful.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "joyful@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/joyful.imageset/joyful@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/joyful.imageset/joyful@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/keepfighting.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "keepfighting@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/keepfighting.imageset/keepfighting@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/keepfighting.imageset/keepfighting@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/kiss.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "kiss@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/kiss.imageset/kiss@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/kiss.imageset/kiss@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/laugh.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "laugh@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/laugh.imageset/laugh@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/laugh.imageset/laugh@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/letmesee.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "letmesee@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/letmesee.imageset/letmesee@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/letmesee.imageset/letmesee@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/lips.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "lips@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/lips.imageset/lips@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/lips.imageset/lips@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/moon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "moon@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/moon.imageset/moon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/moon.imageset/moon@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/mybad.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "mybad@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/mybad.imageset/mybad@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/mybad.imageset/mybad@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/noprob.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "noprob@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/noprob.imageset/noprob@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/noprob.imageset/noprob@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/nosepick.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "nosepick@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/nosepick.imageset/nosepick@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/nosepick.imageset/nosepick@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/ok.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "ok@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/ok.imageset/ok@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/ok.imageset/ok@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/omg.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "omg@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/omg.imageset/omg@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/omg.imageset/omg@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/onlooker.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "onlooker@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/onlooker.imageset/onlooker@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/onlooker.imageset/onlooker@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/packet.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "packet@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/packet.imageset/packet@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/packet.imageset/packet@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/panic.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "panic@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/panic.imageset/panic@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/panic.imageset/panic@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/peace.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "peace@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/peace.imageset/peace@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/peace.imageset/peace@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/pig.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "pig@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/pig.imageset/pig@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/pig.imageset/pig@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/pooh-pooh.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "pooh-pooh@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/pooh-pooh.imageset/pooh-pooh@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/pooh-pooh.imageset/pooh-pooh@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/poop.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "poop@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/poop.imageset/poop@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/poop.imageset/poop@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/puke.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "puke@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/puke.imageset/puke@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/puke.imageset/puke@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/respect.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "respect@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/respect.imageset/respect@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/respect.imageset/respect@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/rich.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "rich@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/rich.imageset/rich@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/rich.imageset/rich@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/rose.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "rose@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/rose.imageset/rose@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/rose.imageset/rose@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/salute.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "salute@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/salute.imageset/salute@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/salute.imageset/salute@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/scold.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "scold@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/scold.imageset/scold@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/scold.imageset/scold@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/scowl.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "scowl@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/scowl.imageset/scowl@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/scowl.imageset/scowl@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/scream.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "scream@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/scream.imageset/scream@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/scream.imageset/scream@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/shake.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "shake@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/shake.imageset/shake@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/shake.imageset/shake@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/shhh.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "shhh@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/shhh.imageset/shhh@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/shhh.imageset/shhh@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/shocked.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "shocked@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/shocked.imageset/shocked@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/shocked.imageset/shocked@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/shrunken.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "shrunken@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/shrunken.imageset/shrunken@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/shrunken.imageset/shrunken@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/shy.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "shy@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/shy.imageset/shy@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/shy.imageset/shy@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/sigh.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "sigh@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/sigh.imageset/sigh@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/sigh.imageset/sigh@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/silent.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "silent@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/silent.imageset/silent@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/silent.imageset/silent@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/skull.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "skull@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/skull.imageset/skull@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/skull.imageset/skull@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/sleep.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "sleep@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/sleep.imageset/sleep@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/sleep.imageset/sleep@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/slight.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "slight@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/slight.imageset/slight@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/slight.imageset/slight@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/sly.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "sly@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/sly.imageset/sly@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/sly.imageset/sly@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/smart.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "smart@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/smart.imageset/smart@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/smart.imageset/smart@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/smile.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "smile@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/smile.imageset/smile@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/smile.imageset/smile@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/smirk.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "smirk@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/smirk.imageset/smirk@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/smirk.imageset/smirk@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/smug.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "smug@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/smug.imageset/smug@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/smug.imageset/smug@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/sob.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "sob@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/sob.imageset/sob@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/sob.imageset/sob@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/speechless.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "speechless@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/speechless.imageset/speechless@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/speechless.imageset/speechless@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/sun.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "sun@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/sun.imageset/sun@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/sun.imageset/sun@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/surprise.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "surprise@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/surprise.imageset/surprise@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/surprise.imageset/surprise@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/sweat.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "sweat@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/sweat.imageset/sweat@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/sweat.imageset/sweat@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/sweats.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "sweats@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/sweats.imageset/sweats@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/sweats.imageset/sweats@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/tearingup.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "tearingup@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/tearingup.imageset/tearingup@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/tearingup.imageset/tearingup@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/thumbsdown.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "thumbsdown@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/thumbsdown.imageset/thumbsdown@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/thumbsdown.imageset/thumbsdown@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/thumbsup.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "thumbsup@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/thumbsup.imageset/thumbsup@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/thumbsup.imageset/thumbsup@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/toasted.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "toasted@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/toasted.imageset/toasted@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/toasted.imageset/toasted@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/tongue.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "tongue@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/tongue.imageset/tongue@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/tongue.imageset/tongue@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/tremble.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "tremble@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/tremble.imageset/tremble@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/tremble.imageset/tremble@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/trick.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "trick@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/trick.imageset/trick@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/trick.imageset/trick@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/twirl.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "twirl@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/twirl.imageset/twirl@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/twirl.imageset/twirl@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/waddle.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "waddle@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/waddle.imageset/waddle@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/waddle.imageset/waddle@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/watermelon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "watermelon@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/watermelon.imageset/watermelon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/watermelon.imageset/watermelon@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/whimper.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "whimper@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/whimper.imageset/whimper@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/whimper.imageset/whimper@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/wilt.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "wilt@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/wilt.imageset/wilt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/wilt.imageset/wilt@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/wow.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "wow@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/wow.imageset/wow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/wow.imageset/wow@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/yeah!.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "yeah!@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | }, 21 | "properties" : { 22 | "template-rendering-intent" : "original" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/expressions/yeah!.imageset/yeah!@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/WeChat-SwiftUI/Resources/Assets.xcassets/expressions/yeah!.imageset/yeah!@2x.png -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/WeWork.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "WeWork.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_filled_camera.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_filled_camera.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_filled_chats.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_filled_chats.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_filled_colorful_female.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_filled_colorful_female.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "original" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_filled_colorful_male.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_filled_colorful_man.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "original" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_filled_contacts.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_filled_contacts.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_filled_discover.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_filled_discover.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_filled_error.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_filled_error.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_filled_fts_default_headimage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_filled_fts_default_headimage.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "original" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_filled_group_detail.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_filled_group_detail.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_filled_me.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_filled_me.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_filled_official_accounts.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_filled_official_accounts.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_filled_tag.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_filled_tag.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_outlined_add.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_outlined_add2.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_outlined_add2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_outlined_add.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_outlined_add2.imageset/icons_outlined_add.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | icons_outlined_add 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_outlined_add_friends.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_outlined_add_friends.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_outlined_back.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_outlined_back.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_outlined_back.imageset/icons_outlined_back.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | icons_outlined_back 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_outlined_channel.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_outlined_channel_2.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_outlined_chats.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_outlined_chats.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_outlined_colorful_favorites.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_outlined_colorful_favorites.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "original" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_outlined_colorful_game.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_outlined_colorful_game.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "original" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_outlined_colorful_moment.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_outlined_colorful_moment.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "original" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_outlined_contacts.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_outlined_contacts.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_outlined_discover.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_outlined_discover.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_outlined_keyboard.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_outlined_keyboard.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_outlined_live_nearby.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_outlined_live_nearby.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_outlined_me.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_outlined_me.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_outlined_news.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_outlined_news.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_outlined_qr_code.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_outlined_qr_code.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_outlined_scan.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_outlined_scan.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_outlined_searchlogo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_outlined_searchlogo.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_outlined_setting.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_outlined_setting.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_outlined_shake.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_outlined_shake.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_outlined_shop.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_outlined_shop.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_outlined_sticker.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_outlined_sticker.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_outlined_videocall.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_outlined_videocall.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_outlined_voice.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_outlined_voice.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Resources/Assets.xcassets/icons/icons_outlined_wechatpay.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icons_outlined_wechatpay.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "original" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/ViewModels/MyProfileFieldUpdateViewModel.swift: -------------------------------------------------------------------------------- 1 | import Combine 2 | import SwiftUI 3 | 4 | final class MyProfileFieldUpdateViewModel: ObservableObject { 5 | 6 | @Published 7 | private(set) var userSelfUpdateStatus: ValueUpdateStatus = .idle 8 | private var userSelfUpdateCancellable: AnyCancellable? 9 | 10 | func updateUserSelf(_ newUser: User) { 11 | userSelfUpdateStatus = .updating 12 | userSelfUpdateCancellable?.cancel() 13 | 14 | userSelfUpdateCancellable = AppEnvironment.current.firestoreService 15 | .overrideUser(newUser) 16 | .sinkForUI(receiveCompletion: { [weak self] completion in 17 | 18 | switch completion { 19 | case .finished: 20 | self?.userSelfUpdateStatus = .finished(newUser) 21 | case let .failure(error): 22 | self?.userSelfUpdateStatus = .failed(error) 23 | } 24 | }) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/ViewModels/OnboardingViewModelTests.swift: -------------------------------------------------------------------------------- 1 | import Combine 2 | import XCTest 3 | @testable import WeChat_SwiftUI 4 | 5 | /// FirebaseAuthServiceType 方法的返回值无法进行 Mock,无法测试 6 | final class OnboardingViewModelTests: XCTestCase { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Views/Chats/ChatsView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct ChatsView: View { 4 | var body: some View { 5 | NavigationView { 6 | DialogsList() 7 | .navigationTitle(Strings.tabbar_chats()) 8 | .navigationBarTitleDisplayMode(.inline) 9 | .navigationBarItems(trailing: Image("icons_outlined_add")) 10 | } 11 | .navigationViewStyle(.stack) 12 | } 13 | } 14 | 15 | struct ChatsView_Previews: PreviewProvider { 16 | static var previews: some View { 17 | ChatsView() 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Views/Chats/Message/MessageContentVideo.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct MessageContentVideo: View { 4 | var body: some View { 5 | Text("Hello, World!") 6 | } 7 | } 8 | 9 | struct MessageContentVideo_Previews: PreviewProvider { 10 | static var previews: some View { 11 | MessageContentVideo() 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Views/Chats/Message/MessagesList.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct MessagesList: View { 4 | let messages: [Message] 5 | 6 | var body: some View { 7 | List { 8 | ForEach(messages, id: \.self) { 9 | MessageRow(message: $0) 10 | .listRowInsets(Constant.listRowInset) 11 | .listRowSeparator(.hidden) 12 | } 13 | } 14 | .background(.app_bg) 15 | .listStyle(.plain) 16 | } 17 | } 18 | 19 | private extension MessagesList { 20 | enum Constant { 21 | static let listRowInset: EdgeInsets = .init(top: 8, leading: 12, bottom: 8, trailing: 12) 22 | } 23 | } 24 | 25 | struct MessagesList_Previews: PreviewProvider { 26 | static var previews: some View { 27 | MessagesList(messages: [Message.textTemplate, Message.textTemplate2]) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Views/Discover/DiscoverView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct DiscoverView: View { 4 | var body: some View { 5 | NavigationView { 6 | DiscoverList() 7 | .navigationTitle(Strings.tabbar_discover()) 8 | .navigationBarTitleDisplayMode(.inline) 9 | } 10 | .navigationViewStyle(.stack) 11 | } 12 | } 13 | 14 | struct DiscoverView_Previews: PreviewProvider { 15 | static var previews: some View { 16 | DiscoverView() 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /WeChat-SwiftUI/Views/Me/MyProfileFieldUpdateView.Field.swift: -------------------------------------------------------------------------------- 1 | extension MyProfileFieldUpdateView { 2 | enum Field { 3 | case name(String) 4 | case gender(User.Gender) 5 | case region 6 | case whatsUp(String) 7 | 8 | var navigationBarTitle: String { 9 | let name: String 10 | switch self { 11 | case .name: 12 | name = Strings.general_name() 13 | case .gender: 14 | name = Strings.general_gender() 15 | case .region: 16 | name = Strings.general_region() 17 | case .whatsUp: 18 | name = Strings.general_whats_up() 19 | } 20 | return "\(Strings.general_set()) \(name)" 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /WeChat-SwiftUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /WeChat-SwiftUIUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /WeChat-SwiftUIUITests/TestExamples.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TestExamples.swift 3 | // WeChat-SwiftUIUITests 4 | // 5 | // Created by Lebron on 2021/6/9. 6 | // 7 | 8 | import XCTest 9 | 10 | class TestExamples: XCTestCase { 11 | 12 | override func setUpWithError() throws { 13 | continueAfterFailure = false 14 | XCUIApplication().launch() 15 | } 16 | 17 | override func tearDownWithError() throws { 18 | } 19 | 20 | func testExample() throws { 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /bin/StringsScript/StringsScript.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /bin/StringsScript/StringsScript.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /bin/StringsScript/StringsScript/Source/Extensions.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | extension Array where Element: Hashable { 4 | public func distincts(_ eq: (Element, Element) -> Bool) -> Array { 5 | var result = Array() 6 | forEach { x in 7 | if !result.contains(where: { eq(x, $0) }) { 8 | result.append(x) 9 | } 10 | } 11 | return result 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /bin/StringsScript/StringsScript/Source/StringsScriptCoreError.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | enum StringsScriptCoreError: Error, LocalizedError { 4 | case errorDecodingLocalesFromJSON 5 | case errorFetchingStringsFromServer(String) 6 | case stringNotFound(String) 7 | case unknownError(String) 8 | 9 | var errorDescription: String? { 10 | switch self { 11 | case .errorDecodingLocalesFromJSON: 12 | return "Error decoding locales from JSON" 13 | case .errorFetchingStringsFromServer(let message): 14 | return "Error fetching strings from server: \(message)" 15 | case .stringNotFound(let lineNumber): 16 | return "String not found. Line: \(lineNumber)" 17 | case .unknownError(let error): 18 | return "Unknown error: \(error)" 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /bin/StringsScript/StringsScript/main.swift: -------------------------------------------------------------------------------- 1 | let tool = StringsScript() 2 | 3 | do { 4 | try tool.run() 5 | } catch { 6 | print("❌ Error: \(error.localizedDescription)") 7 | } 8 | -------------------------------------------------------------------------------- /bin/StringsScript/bin/strings-script: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/bin/StringsScript/bin/strings-script -------------------------------------------------------------------------------- /bin/strings-script: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/bin/strings-script -------------------------------------------------------------------------------- /previews/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/previews/1.png -------------------------------------------------------------------------------- /previews/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/previews/2.png -------------------------------------------------------------------------------- /previews/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/previews/3.png -------------------------------------------------------------------------------- /previews/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/previews/4.png -------------------------------------------------------------------------------- /previews/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/previews/5.png -------------------------------------------------------------------------------- /previews/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/previews/6.png -------------------------------------------------------------------------------- /previews/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/previews/7.png -------------------------------------------------------------------------------- /previews/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lebron1992/WeChat-SwiftUI/b83353ab77881891d12cd7a3214beac2a81a2400/previews/8.png --------------------------------------------------------------------------------