├── .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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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
--------------------------------------------------------------------------------