├── .bundle └── config ├── .editorconfig ├── .eslintrc.js ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.yaml │ ├── custom.md │ └── feature_request.yaml ├── PULL_REQUEST_TEMPLATE │ ├── default.md │ └── pull_request_template.md ├── config.yml ├── config │ └── changelog_configuration.json ├── dependabot.yml ├── stale.yml └── workflows │ ├── release.yml │ └── test.yml ├── .gitignore ├── .husky └── pre-commit ├── .npmrc ├── .prettierrc.js ├── .vscode ├── extensions.json └── settings.json ├── .watchmanconfig ├── CNAME ├── Gemfile ├── LICENSE ├── README.md ├── __tests__ └── App-test.tsx ├── _config.yml ├── _docs ├── ADB.md ├── Help.md ├── Keystores.md └── assets │ └── screenshot │ ├── Android │ ├── detail.jpeg │ ├── list.jpeg │ ├── list2.jpeg │ ├── my.jpeg │ ├── preview.png │ ├── preview2.jpeg │ └── sign.jpeg │ └── iOS │ ├── home_apple.png │ ├── home_dark.png │ ├── home_light.png │ ├── my_en.png │ ├── my_light.png │ ├── preview.png │ └── preview2.jpeg ├── android ├── app │ ├── app.keystore │ ├── build.gradle │ ├── debug.keystore │ ├── proguard-rules.pro │ └── src │ │ ├── debug │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── github │ │ │ └── funnyzak │ │ │ └── v2ex │ │ │ └── ReactNativeFlipper.java │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── github │ │ │ │ └── funnyzak │ │ │ │ └── v2ex │ │ │ │ ├── MainActivity.java │ │ │ │ └── MainApplication.java │ │ └── res │ │ │ ├── drawable-hdpi │ │ │ └── launch_screen.png │ │ │ ├── drawable-ldpi │ │ │ └── launch_screen.png │ │ │ ├── drawable-mdpi │ │ │ └── launch_screen.png │ │ │ ├── drawable-xhdpi │ │ │ └── launch_screen.png │ │ │ ├── drawable-xxhdpi │ │ │ └── launch_screen.png │ │ │ ├── drawable-xxxhdpi │ │ │ └── launch_screen.png │ │ │ ├── drawable │ │ │ ├── launch_screen.png │ │ │ └── rn_edit_text_material.xml │ │ │ ├── ic_launcher-web.png │ │ │ ├── layout │ │ │ └── launch_screen.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-ldpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── playstore-icon.png │ │ │ └── values │ │ │ ├── colors.xml │ │ │ ├── ic_launcher_background.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ └── release │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── github │ │ └── funnyzak │ │ └── v2ex │ │ └── ReactNativeFlipper.java ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle ├── app.json ├── babel.config.js ├── global.d.ts ├── index.js ├── ios ├── .xcode.env ├── Podfile ├── _xcode.env ├── app.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ └── app.xcscheme ├── app.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── app │ ├── AppDelegate.h │ ├── AppDelegate.mm │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ └── ItunesArtwork@2x.png │ │ ├── Contents.json │ │ ├── iTunesArtwork.imageset │ │ │ ├── Contents.json │ │ │ ├── iTunesArtwork@1x.png │ │ │ ├── iTunesArtwork@2x.png │ │ │ └── iTunesArtwork@3x.png │ │ ├── slogo.imageset │ │ │ ├── Contents.json │ │ │ ├── slogo.png │ │ │ ├── slogo@2x.png │ │ │ └── slogo@3x.png │ │ ├── v2exArrow.imageset │ │ │ ├── Contents.json │ │ │ ├── arrow.png │ │ │ ├── arrow@2x.png │ │ │ └── arrow@3x.png │ │ └── v2exArrowDark.imageset │ │ │ ├── Contents.json │ │ │ ├── arrow.png │ │ │ ├── arrow@2x.png │ │ │ └── arrow@3x.png │ ├── Info.plist │ ├── LaunchScreen.storyboard │ └── main.m └── appTests │ ├── Info.plist │ └── appTests.m ├── metro.config.js ├── node-version ├── package.json ├── patches └── @react-navigation │ └── core+6.4.8.patch ├── plop ├── component │ ├── append.hbs │ ├── component.hbs │ ├── index.hbs │ └── prompt.cjs └── screen │ ├── append.hbs │ ├── index.hbs │ ├── prompt.cjs │ └── screen.hbs ├── plopfile.cjs ├── src ├── App.tsx ├── actions │ ├── CacheAction.ts │ ├── MemberActions.ts │ ├── NodeActions.ts │ ├── NotificationActions.ts │ ├── RestActions.ts │ ├── SettingActions.ts │ ├── TopicActions.ts │ ├── index.ts │ └── types.ts ├── api │ ├── index.ts │ ├── lib │ │ ├── member │ │ │ └── index.ts │ │ ├── node │ │ │ └── index.ts │ │ ├── notification │ │ │ └── index.ts │ │ ├── reply │ │ │ └── index.ts │ │ └── topic │ │ │ └── index.ts │ └── types.ts ├── assets │ └── images │ │ └── icons │ │ ├── app │ │ ├── 256.png │ │ ├── 256@2x.png │ │ ├── 256@3x.png │ │ ├── arrow │ │ │ ├── dark.png │ │ │ ├── dark@2x.png │ │ │ ├── dark@3x.png │ │ │ ├── light.png │ │ │ ├── light@2x.png │ │ │ └── light@3x.png │ │ └── slogo │ │ │ ├── dark.png │ │ │ ├── dark@2x.png │ │ │ ├── dark@3x.png │ │ │ ├── light.png │ │ │ ├── light@2x.png │ │ │ └── light@3x.png │ │ ├── draw │ │ ├── fire-active.png │ │ ├── fire-active@2x.png │ │ ├── fire-active@3x.png │ │ ├── fire-inactive.png │ │ ├── fire-inactive@2x.png │ │ ├── fire-inactive@3x.png │ │ ├── news-active.png │ │ ├── news-active@2x.png │ │ ├── news-active@3x.png │ │ ├── news-inactive.png │ │ ├── news-inactive@2x.png │ │ └── news-inactive@3x.png │ │ ├── header │ │ ├── back.png │ │ ├── back@2x.png │ │ ├── back@3x.png │ │ ├── board.png │ │ ├── board@2x.png │ │ ├── board@3x.png │ │ ├── heart.png │ │ ├── heart@2x.png │ │ ├── heart@3x.png │ │ ├── logout.png │ │ ├── logout@2x.png │ │ ├── logout@3x.png │ │ ├── more.png │ │ ├── more@2x.png │ │ ├── more@3x.png │ │ ├── more_vert.png │ │ ├── more_vert@2x.png │ │ ├── more_vert@3x.png │ │ ├── refresh.png │ │ ├── refresh@2x.png │ │ ├── refresh@3x.png │ │ ├── search.png │ │ ├── search@2x.png │ │ ├── search@3x.png │ │ ├── star.png │ │ ├── star@2x.png │ │ ├── star@3x.png │ │ ├── urlscheme.png │ │ ├── urlscheme@2x.png │ │ └── urlscheme@3x.png │ │ ├── node │ │ ├── document.png │ │ ├── document@2x.png │ │ ├── document@3x.png │ │ ├── star.png │ │ ├── star@2x.png │ │ ├── star@3x.png │ │ ├── urlscheme.png │ │ ├── urlscheme@2x.png │ │ └── urlscheme@3x.png │ │ ├── notification │ │ ├── action.png │ │ ├── action@2x.png │ │ ├── action@3x.png │ │ ├── time.png │ │ ├── time@2x.png │ │ └── time@3x.png │ │ ├── placeholder │ │ ├── construction.png │ │ ├── construction@2x.png │ │ ├── construction@3x.png │ │ ├── notification.png │ │ ├── notification@2x.png │ │ ├── notification@3x.png │ │ ├── search.png │ │ ├── search@2x.png │ │ └── search@3x.png │ │ ├── profile │ │ ├── default-avatar.png │ │ ├── github.png │ │ ├── github@2x.png │ │ ├── github@3x.png │ │ ├── location.png │ │ ├── location@2x.png │ │ ├── location@3x.png │ │ ├── telegram.png │ │ ├── telegram@2x.png │ │ ├── telegram@3x.png │ │ ├── twitter.png │ │ ├── twitter@2x.png │ │ ├── twitter@3x.png │ │ ├── urlscheme.png │ │ ├── urlscheme@2x.png │ │ └── urlscheme@3x.png │ │ ├── tab │ │ ├── bottom │ │ │ ├── home-focus.png │ │ │ ├── home-focus@2x.png │ │ │ ├── home-focus@3x.png │ │ │ ├── home.png │ │ │ ├── home@2x.png │ │ │ ├── home@3x.png │ │ │ ├── hot-focus.png │ │ │ ├── hot-focus@2x.png │ │ │ ├── hot-focus@3x.png │ │ │ ├── hot.png │ │ │ ├── hot@2x.png │ │ │ ├── hot@3x.png │ │ │ ├── like-focus.png │ │ │ ├── like-focus@2x.png │ │ │ ├── like-focus@3x.png │ │ │ ├── like.png │ │ │ ├── like@2x.png │ │ │ ├── like@3x.png │ │ │ ├── my-focus.png │ │ │ ├── my-focus@2x.png │ │ │ ├── my-focus@3x.png │ │ │ ├── my.png │ │ │ ├── my@2x.png │ │ │ ├── my@3x.png │ │ │ ├── node-focus.png │ │ │ ├── node-focus@2x.png │ │ │ ├── node-focus@3x.png │ │ │ ├── node.png │ │ │ ├── node@2x.png │ │ │ ├── node@3x.png │ │ │ ├── notification-focus.png │ │ │ ├── notification-focus@2x.png │ │ │ ├── notification-focus@3x.png │ │ │ ├── notification.png │ │ │ ├── notification@2x.png │ │ │ └── notification@3x.png │ │ └── title │ │ │ ├── comment.png │ │ │ ├── comment@2x.png │ │ │ ├── comment@3x.png │ │ │ ├── news.png │ │ │ ├── news@2x.png │ │ │ └── news@3x.png │ │ ├── table │ │ ├── cached.png │ │ ├── cached@2x.png │ │ ├── cached@3x.png │ │ ├── check-right.png │ │ ├── check-right@2x.png │ │ ├── check-right@3x.png │ │ ├── email.png │ │ ├── email@2x.png │ │ ├── email@3x.png │ │ ├── github.png │ │ ├── github@2x.png │ │ ├── github@3x.png │ │ ├── group.png │ │ ├── group@2x.png │ │ ├── group@3x.png │ │ ├── language.png │ │ ├── language@2x.png │ │ ├── language@3x.png │ │ ├── opensource.png │ │ ├── opensource@2x.png │ │ ├── opensource@3x.png │ │ ├── right-arrow.png │ │ ├── right-arrow@2x.png │ │ ├── right-arrow@3x.png │ │ ├── score.png │ │ ├── score@2x.png │ │ ├── score@3x.png │ │ ├── share.png │ │ ├── share@2x.png │ │ ├── share@3x.png │ │ ├── theme.png │ │ ├── theme@2x.png │ │ ├── theme@3x.png │ │ ├── twitter.png │ │ ├── twitter@2x.png │ │ ├── twitter@3x.png │ │ ├── urlscheme.png │ │ ├── urlscheme@2x.png │ │ └── urlscheme@3x.png │ │ └── topic │ │ ├── comment.png │ │ ├── comment@2x.png │ │ ├── comment@3x.png │ │ ├── paper.png │ │ ├── paper@2x.png │ │ ├── paper@3x.png │ │ ├── people-voice.png │ │ ├── people-voice@2x.png │ │ ├── people-voice@3x.png │ │ ├── update.png │ │ ├── update@2x.png │ │ └── update@3x.png ├── components │ ├── actions-sheet │ │ ├── Btn.tsx │ │ ├── ConfirmSheet.tsx │ │ ├── ContentSheet.tsx │ │ ├── MenuSheet.tsx │ │ └── index.ts │ ├── atoms │ │ ├── index.ts │ │ └── logo │ │ │ └── index.tsx │ ├── avatar │ │ └── index.tsx │ ├── common │ │ ├── Button.tsx │ │ ├── CheckUpdate.tsx │ │ ├── Input.tsx │ │ ├── Placeholder.tsx │ │ ├── Spinner.tsx │ │ ├── Text.tsx │ │ └── index.ts │ ├── header │ │ └── index.tsx │ ├── index.ts │ ├── loading-modal │ │ └── index.tsx │ ├── loading │ │ └── index.tsx │ ├── search-bar │ │ ├── ClearIcon.tsx │ │ ├── SearchBar.tsx │ │ ├── SearchIcon.tsx │ │ └── index.ts │ └── toast │ │ ├── ToastContext.ts │ │ ├── ToastProvider.tsx │ │ └── index.ts ├── config │ ├── app.config.ts │ └── constants.ts ├── helper │ ├── app.ts │ ├── cache.ts │ ├── index.ts │ ├── logger.ts │ └── node.ts ├── hooks │ ├── index.ts │ ├── useIsFocus.tsx │ ├── useMember.ts │ ├── useNode.ts │ ├── useSession.ts │ ├── useTopic.ts │ └── useUnRead.ts ├── i18n │ ├── i18n.ts │ ├── index.ts │ ├── locales │ │ ├── en.json │ │ └── zh.json │ └── translate.ts ├── navigation │ ├── NavigationService.ts │ ├── Navigator.tsx │ ├── index.ts │ ├── routes.ts │ └── tabs.ts ├── reducers │ ├── AppReducer.ts │ ├── CacheReducer.ts │ ├── MemberReducer.ts │ ├── NotificationReducer.ts │ ├── SettingReducer.ts │ ├── TabReducer.ts │ ├── UIReducer.ts │ └── index.ts ├── screens │ ├── catalog │ │ └── Draw.tsx │ ├── common │ │ ├── WebLink.tsx │ │ └── index.ts │ ├── components │ │ ├── Layout.tsx │ │ ├── button │ │ │ ├── header │ │ │ │ ├── FollowPeopleHeaderButton.tsx │ │ │ │ ├── LikeNodeHeaderButton.tsx │ │ │ │ ├── LikeTopicHeaderButton.tsx │ │ │ │ ├── LogoutHeaderButton.tsx │ │ │ │ └── index.ts │ │ │ └── index.ts │ │ ├── common │ │ │ ├── General.tsx │ │ │ ├── RenderHTML.tsx │ │ │ ├── TabCardContainer.tsx │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── list │ │ │ ├── GridList.tsx │ │ │ ├── TableList.tsx │ │ │ └── index.ts │ │ ├── node │ │ │ ├── NodeInfoCard.tsx │ │ │ ├── NodeList.tsx │ │ │ ├── NodeSection.tsx │ │ │ ├── NodeTopicTabList.tsx │ │ │ └── index.ts │ │ ├── notification │ │ │ ├── NotificationList.tsx │ │ │ └── index.ts │ │ ├── profile │ │ │ ├── ProfileCard.tsx │ │ │ ├── ProfileCardList.tsx │ │ │ ├── ProfileDetail.tsx │ │ │ ├── ProfileGrid.tsx │ │ │ ├── ProfileInfo.tsx │ │ │ ├── ProfileTopics.tsx │ │ │ ├── SimpleProfileInfoCard.tsx │ │ │ ├── index.ts │ │ │ └── profile.ts │ │ ├── section │ │ │ ├── SettingSection.tsx │ │ │ └── index.ts │ │ ├── skeleton │ │ │ ├── TopicDetailPlaceholer.tsx │ │ │ ├── TopicsPlaceholder.tsx │ │ │ └── index.ts │ │ ├── statusbar │ │ │ └── index.tsx │ │ └── topic │ │ │ ├── FetchTopicCardList.tsx │ │ │ ├── TopicCardItem.tsx │ │ │ ├── TopicCardList.tsx │ │ │ ├── TopicInfo.tsx │ │ │ ├── TopicReplay.tsx │ │ │ ├── TopicReplayItem.tsx │ │ │ ├── TopicReplayList.tsx │ │ │ └── index.ts │ ├── home │ │ ├── HomeTabs.tsx │ │ ├── HotTopics.tsx │ │ ├── LatestTopics.tsx │ │ └── index.tsx │ ├── index.ts │ ├── login │ │ └── SignIn.tsx │ ├── my │ │ ├── Favorite.tsx │ │ ├── Following.tsx │ │ ├── History.tsx │ │ ├── Home.tsx │ │ ├── Topics.tsx │ │ └── index.ts │ ├── node │ │ ├── InterestNodes.tsx │ │ ├── NodeDetail.tsx │ │ ├── Nodes.tsx │ │ └── index.ts │ ├── notification │ │ ├── Notifications.tsx │ │ └── index.ts │ ├── profile │ │ ├── Profile.tsx │ │ └── index.ts │ ├── search │ │ ├── Search.tsx │ │ └── index.ts │ ├── setting │ │ ├── About.tsx │ │ ├── CacheSetting.tsx │ │ ├── ChangeLog.tsx │ │ ├── Feedback.tsx │ │ ├── HowToUse.tsx │ │ ├── Language.tsx │ │ ├── License.tsx │ │ ├── Privacy.tsx │ │ ├── Setting.tsx │ │ ├── SiteStat.tsx │ │ ├── TermsOfService.tsx │ │ ├── Theme.tsx │ │ ├── URLSchemes.tsx │ │ └── index.ts │ └── topic │ │ ├── HomeTabNodeTopicList.tsx │ │ ├── NodeTopicList.tsx │ │ ├── TopicDetail.tsx │ │ └── index.ts ├── store │ ├── index.ts │ └── types.ts ├── theme │ ├── ThemeContext.ts │ ├── ThemeProvider.tsx │ ├── common.ts │ ├── dark │ │ ├── assets.ts │ │ ├── colors.ts │ │ ├── dimens.ts │ │ ├── spacing.ts │ │ └── typography.ts │ ├── index.ts │ ├── light │ │ ├── assets.ts │ │ ├── colors.ts │ │ ├── dimens.ts │ │ ├── spacing.ts │ │ └── typography.ts │ ├── themes.ts │ └── types.ts ├── types │ └── index.ts └── utils │ ├── adapter.ts │ ├── alert.ts │ ├── index.ts │ ├── params.ts │ ├── parser.ts │ ├── promise.ts │ └── utils.ts ├── tsconfig.json └── yarn.lock /.bundle/config: -------------------------------------------------------------------------------- 1 | BUNDLE_PATH: "vendor/bundle" 2 | BUNDLE_FORCE_RUBY_PLATFORM: 1 -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | # need install => EditorConfig for VS Code 3 | root = true 4 | 5 | [*.{js,jsx,tsx}] 6 | indent_style = space 7 | indent_size = 2 8 | end_of_line = lf 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | max_line_length = 100 12 | 13 | [*.md] 14 | trim_trailing_whitespace = true 15 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: ['https://github.com/funnyzak/funnyzak/blob/storage/assets/coffee.png'] 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yaml: -------------------------------------------------------------------------------- 1 | name: Report a bug 2 | description: ——— 3 | labels: [bug] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | # Thanks for reporting this bug! 9 | 10 | Help us replicate and find a fix for the issue by filling in this form. 11 | - type: textarea 12 | attributes: 13 | label: Description 14 | description: | 15 | Describe the issue and how to replicate it. If possible, please include 16 | a minimal example to reproduce the issue. 17 | validations: 18 | required: true -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom Issue Template 3 | about: Tell us something related to the project or general discussion 4 | title: '' 5 | labels: question 6 | assignees: troublediehard 7 | --- 8 | 9 | **Are there certain things to report that are not a bug or feature?** 10 | Please tell us as exactly as possible about your request, thanks. 11 | We will reply as soon as possible. 12 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yaml: -------------------------------------------------------------------------------- 1 | name: Suggest an improvement or new feature 2 | description: ——— 3 | labels: [enhancement] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | # Thanks for filing this feature request! 9 | 10 | Help us understanding this feature and the need for it better by filling in this form. 11 | - type: textarea 12 | attributes: 13 | label: Description 14 | description: Describe the feature in detail 15 | validations: 16 | required: true 17 | - type: textarea 18 | attributes: 19 | label: Why 20 | description: Why should we add this feature? What are potential use cases for it? 21 | validations: 22 | required: true 23 | - type: textarea 24 | attributes: 25 | label: Alternatives 26 | description: Describe the alternatives you have considered, or existing workarounds 27 | validations: 28 | required: true 29 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/default.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | ## Related Issues 7 | 8 | 15 | 16 | ## Description 17 | 18 | 22 | 23 | ### Added 24 | 25 | 28 | 29 | ### Changed 30 | 31 | 35 | 36 | ### Removed 37 | 38 | 41 | 42 | ## Caveats/Problems/Issues 43 | 44 | 48 | 49 | ## Checklist 50 | 51 | - [ ] The issues that this PR fixes/closes have been mentioned above. 52 | - [ ] What this PR adds/changes/removes has been explained. 53 | - [ ] All tests pass. 54 | - [ ] The linter does not throw an errors. 55 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/pull_request_template.md: -------------------------------------------------------------------------------- 1 | **What does this implement/fix? Explain your changes.** 2 | Please explain your changes in addition to your commit messages. 3 | 4 | **Does this close any currently open issues?** 5 | If yes, please mention, else ignore. 6 | 7 | **Screenshots** 8 | If applicable, add screenshots of end result. 9 | 10 | **Any other comments?** 11 | 12 | ## **Where has this been tested?** 13 | 14 | - OS: [e.g. Windows 10] 15 | - Version [e.g. 1.0.0] 16 | - Node.js version [e.g. 12.16.1] 17 | - Yarn version [e.g. 1.22.4] 18 | - ...etc 19 | -------------------------------------------------------------------------------- /.github/config.yml: -------------------------------------------------------------------------------- 1 | newIssueWelcomeComment: > 2 | 感谢你提交的问题或反馈,我会尽快回复,在此期间你可以看看[之前被解决的反馈](https://github.com/funnyzak/react-native-v2ex/issues?q=is%3Aissue+is%3Aclosed)说不定有你需要的答案。 3 | 4 | Thanks for opening this issue, a maintainer will get back to you shortly! 5 | 6 | newPRWelcomeComment: > 7 | 感谢你提交的问题或反馈,我会尽快来审查代码。 8 | 9 | Thanks so much for opening your first PR here! 10 | firstPRMergeComment: > 11 | 感谢贡献 PR 来支持 Funnyzak! :tada: 12 | 13 | Congrats on merging your first pull request here! :tada: How awesome! -------------------------------------------------------------------------------- /.github/config/changelog_configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "categories": [ 3 | { 4 | "title": "## 🚀 Features", 5 | "labels": [ 6 | "feature", 7 | "feat" 8 | ] 9 | }, 10 | { 11 | "title": "## 🐛 Fixes", 12 | "labels": [ 13 | "fix", 14 | "bug", 15 | "fixed" 16 | ] 17 | }, 18 | { 19 | "title": "## 🧪 Tests", 20 | "labels": [ 21 | "test" 22 | ] 23 | }, 24 | { 25 | "title": "## 💬 Other", 26 | "labels": [ 27 | "other" 28 | ] 29 | }, 30 | { 31 | "title": "## ✨ Refactors", 32 | "labels": [ 33 | "refactor" 34 | ] 35 | }, 36 | { 37 | "title": "## 📦 Dependencies", 38 | "labels": [ 39 | "dependencies" 40 | ] 41 | } 42 | ], 43 | "sort": "ASC", 44 | "template": "${{CHANGELOG}}\n\n
\nUncategorized\n\n${{UNCATEGORIZED}}\n
", 45 | "pr_template": "- ${{TITLE}}\n - PR: #${{NUMBER}}", 46 | "empty_template": "- no changes", 47 | "transformers": [ 48 | { 49 | "pattern": "[\\-\\*] (\\[(...|TEST|CI|SKIP)\\])( )?(.+?)\n(.+?[\\-\\*] )(.+)", 50 | "target": "- $4\n - $6" 51 | } 52 | ], 53 | "max_tags_to_fetch": 500, 54 | "max_pull_requests": 500, 55 | "max_back_track_time_days": 500, 56 | "exclude_merge_branches": [ 57 | "Owner/qa" 58 | ] 59 | } -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: npm 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | open-pull-requests-limit: 3 8 | ignore: 9 | - dependency-name: "i18n-js" 10 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 30 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 7 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - pinned 8 | - security 9 | # Label to use when marking an issue as stale 10 | staleLabel: wontfix 11 | # Comment to post when marking an issue as stale. Set to `false` to disable 12 | markComment: > 13 | This issue has been automatically marked as stale because it has not had 14 | recent activity. It will be closed if no further activity occurs. Thank you 15 | for your contributions. 16 | # Comment to post when closing a stale issue. Set to `false` to disable 17 | closeComment: false -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | on: 4 | push: 5 | branches: [ dev, main ] 6 | pull_request: 7 | workflow_dispatch: 8 | jobs: 9 | lint: 10 | runs-on: ubuntu-latest 11 | strategy: 12 | matrix: 13 | node-version: [18.x] 14 | steps: 15 | - 16 | name: Checkout 17 | uses: actions/checkout@v3 18 | - 19 | name: Use Node.js 20 | uses: actions/setup-node@v3 21 | with: 22 | node-version: ${{ matrix.node-version }} 23 | - 24 | name: Get yarn cache directory path 25 | id: yarn-cache-dir-path 26 | run: echo "::set-output name=dir::$(yarn cache dir)" 27 | - 28 | uses: actions/cache@v3 29 | id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) 30 | with: 31 | path: ${{ steps.yarn-cache-dir-path.outputs.dir }} 32 | key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} 33 | restore-keys: | 34 | ${{ runner.os }}-yarn- 35 | - 36 | name: Lint 37 | run: | 38 | yarn 39 | yarn lint 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | ios/.xcode.env.local 24 | 25 | # Android/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | *.hprof 33 | .cxx/ 34 | 35 | # node.js 36 | # 37 | node_modules/ 38 | npm-debug.log 39 | yarn-error.log 40 | 41 | *.keystore 42 | !app.keystore 43 | !debug.keystore 44 | 45 | # fastlane 46 | # 47 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 48 | # screenshots whenever they are needed. 49 | # For more information about the recommended setup visit: 50 | # https://docs.fastlane.tools/best-practices/source-control/ 51 | 52 | **/fastlane/report.xml 53 | **/fastlane/Preview.html 54 | **/fastlane/screenshots 55 | **/fastlane/test_output 56 | 57 | # Bundle artifact 58 | *.jsbundle 59 | 60 | # Ruby / CocoaPods 61 | /ios/Pods/ 62 | /vendor/bundle/ 63 | 64 | .eslintcache 65 | 66 | podfile.lock -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npx lint-staged -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | save-exact=true -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | // https://prettier.io/docs/en/options.html 2 | module.exports = { 3 | // Specify the line length that the printer will wrap on. 4 | printWidth: 120, 5 | // Print trailing commas wherever possible in multi-line comma-separated syntactic structures. (A single-line array, for example, never gets trailing commas.) 6 | trailingComma: 'none', 7 | // Specify the number of spaces per indentation-level. 8 | tabWidth: 2, 9 | useTabs: false, 10 | // Print semicolons at the ends of statements. 11 | semi: false, 12 | // Use single quotes instead of double quotes. 13 | singleQuote: true, 14 | // Change when properties in objects are quoted. 15 | quoteProps: 'consistent', 16 | // Print spaces between brackets in object literals. 17 | bracketSpacing: true, 18 | // Put the > of a multi-line HTML (HTML, JSX, Vue, Angular) element at the end of the last line instead of being alone on the next line (does not apply to self closing elements). 19 | bracketSameLine: true, 20 | // Include parentheses around a sole arrow function parameter. 21 | arrowParens: 'always', 22 | 23 | endOfLine: 'lf' 24 | } 25 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "dbaeumer.vscode-eslint", 4 | "esbenp.prettier-vscode", 5 | "lokalise.i18n-ally", 6 | "yzhang.markdown-all-in-one" 7 | ] 8 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "search.exclude": { 3 | "**/node_modules": false 4 | }, 5 | "[gradle]": { 6 | "files.trimTrailingWhitespace": false, 7 | "spotlessGradle.diagnostics.enable": true, 8 | "spotlessGradle.format.enable": true, 9 | "editor.defaultFormatter": "richardwillis.vscode-spotless-gradle", 10 | "editor.codeActionsOnSave": { 11 | "source.fixAll.spotlessGradle": true 12 | } 13 | }, 14 | "java.configuration.updateBuildConfiguration": "automatic", 15 | "java.compile.nullAnalysis.mode": "disabled" 16 | } -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | v2hub.yycc.dev -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version 4 | ruby '>= 2.6.10' 5 | 6 | gem 'cocoapods', '>= 1.11.3' 7 | -------------------------------------------------------------------------------- /__tests__/App-test.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import 'react-native' 6 | import React from 'react' 7 | import App from '../src/App' 8 | 9 | // Note: test renderer must be required after react-native. 10 | import renderer from 'react-test-renderer' 11 | 12 | it('renders correctly', () => { 13 | renderer.create() 14 | }) 15 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman 2 | show_downloads: true 3 | -------------------------------------------------------------------------------- /_docs/Help.md: -------------------------------------------------------------------------------- 1 | # React Native V2EX 2 | 3 | 这个项目使用了 React Native 构建了一个 [V2EX](https://v2ex.com) 移动客户端应用。主要目的是为了构建一个 React Native 快速开发脚手架。 4 | -------------------------------------------------------------------------------- /_docs/assets/screenshot/Android/detail.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/_docs/assets/screenshot/Android/detail.jpeg -------------------------------------------------------------------------------- /_docs/assets/screenshot/Android/list.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/_docs/assets/screenshot/Android/list.jpeg -------------------------------------------------------------------------------- /_docs/assets/screenshot/Android/list2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/_docs/assets/screenshot/Android/list2.jpeg -------------------------------------------------------------------------------- /_docs/assets/screenshot/Android/my.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/_docs/assets/screenshot/Android/my.jpeg -------------------------------------------------------------------------------- /_docs/assets/screenshot/Android/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/_docs/assets/screenshot/Android/preview.png -------------------------------------------------------------------------------- /_docs/assets/screenshot/Android/preview2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/_docs/assets/screenshot/Android/preview2.jpeg -------------------------------------------------------------------------------- /_docs/assets/screenshot/Android/sign.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/_docs/assets/screenshot/Android/sign.jpeg -------------------------------------------------------------------------------- /_docs/assets/screenshot/iOS/home_apple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/_docs/assets/screenshot/iOS/home_apple.png -------------------------------------------------------------------------------- /_docs/assets/screenshot/iOS/home_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/_docs/assets/screenshot/iOS/home_dark.png -------------------------------------------------------------------------------- /_docs/assets/screenshot/iOS/home_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/_docs/assets/screenshot/iOS/home_light.png -------------------------------------------------------------------------------- /_docs/assets/screenshot/iOS/my_en.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/_docs/assets/screenshot/iOS/my_en.png -------------------------------------------------------------------------------- /_docs/assets/screenshot/iOS/my_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/_docs/assets/screenshot/iOS/my_light.png -------------------------------------------------------------------------------- /_docs/assets/screenshot/iOS/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/_docs/assets/screenshot/iOS/preview.png -------------------------------------------------------------------------------- /_docs/assets/screenshot/iOS/preview2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/_docs/assets/screenshot/iOS/preview2.jpeg -------------------------------------------------------------------------------- /android/app/app.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/android/app/app.keystore -------------------------------------------------------------------------------- /android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/android/app/debug.keystore -------------------------------------------------------------------------------- /android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-hdpi/launch_screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/android/app/src/main/res/drawable-hdpi/launch_screen.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-ldpi/launch_screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/android/app/src/main/res/drawable-ldpi/launch_screen.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-mdpi/launch_screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/android/app/src/main/res/drawable-mdpi/launch_screen.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xhdpi/launch_screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/android/app/src/main/res/drawable-xhdpi/launch_screen.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xxhdpi/launch_screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/android/app/src/main/res/drawable-xxhdpi/launch_screen.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xxxhdpi/launch_screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/android/app/src/main/res/drawable-xxxhdpi/launch_screen.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/android/app/src/main/res/drawable/launch_screen.png -------------------------------------------------------------------------------- /android/app/src/main/res/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/android/app/src/main/res/ic_launcher-web.png -------------------------------------------------------------------------------- /android/app/src/main/res/layout/launch_screen.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-ldpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/android/app/src/main/res/mipmap-ldpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/playstore-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/android/app/src/main/res/playstore-icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #000000 4 | #222223 5 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #242424 4 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | V2HUB 3 | 4 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 13 | 14 | -------------------------------------------------------------------------------- /android/app/src/release/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /android/app/src/release/java/github/funnyzak/v2ex/ReactNativeFlipper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | *

This source code is licensed under the MIT license found in the LICENSE file in the root 5 | * directory of this source tree. 6 | */ 7 | package github.funnyzak.v2ex; 8 | 9 | import android.content.Context; 10 | import com.facebook.react.ReactInstanceManager; 11 | 12 | /** 13 | * Class responsible of loading Flipper inside your React Native application. 14 | * This is the release 15 | * flavor of it so it's empty as we don't want to load Flipper. 16 | */ 17 | public class ReactNativeFlipper { 18 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { 19 | // Do nothing as we don't want to initialize Flipper on Release. 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | ext { 5 | buildToolsVersion = "33.0.0" 6 | minSdkVersion = 21 7 | compileSdkVersion = 33 8 | targetSdkVersion = 33 9 | 10 | // We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP. 11 | ndkVersion = "23.1.7779620" 12 | } 13 | repositories { 14 | google() 15 | mavenCentral() 16 | } 17 | dependencies { 18 | classpath("com.android.tools.build:gradle:7.3.1") 19 | classpath("com.facebook.react:react-native-gradle-plugin") 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Mar 15 10:19:58 CST 2022 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'app' 2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) 3 | include ':app' 4 | includeBuild('../node_modules/react-native-gradle-plugin') 5 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app", 3 | "displayName": "app" 4 | } -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:metro-react-native-babel-preset'], 3 | plugins: [ 4 | [ 5 | 'module-resolver', 6 | { 7 | root: ['./src'], 8 | extensions: ['.ios.js', '.android.js', '.js', '.ts', '.tsx', '.json'], 9 | alias: { 10 | '@src': './src', 11 | '@config': './src/config', 12 | '@res': './src/assets' 13 | } 14 | } 15 | ], 16 | '@babel/plugin-proposal-export-namespace-from', 17 | 'react-native-reanimated/plugin' 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /global.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.png' { 2 | import { ImageSourcePropType } from 'react-native' 3 | const value: ImageSourcePropType 4 | export default value 5 | } 6 | 7 | declare module '*.jpg' { 8 | import { ImageSourcePropType } from 'react-native' 9 | const value: ImageSourcePropType 10 | export default value 11 | } 12 | 13 | declare module '*.jpeg' { 14 | import { ImageSourcePropType } from 'react-native' 15 | const value: ImageSourcePropType 16 | export default value 17 | } 18 | 19 | declare module '*.gif' { 20 | import { ImageSourcePropType } from 'react-native' 21 | const value: ImageSourcePropType 22 | export default value 23 | } 24 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import { AppRegistry, LogBox } from 'react-native' 2 | import App from './src/App' 3 | import { name as appName } from './app.json' 4 | 5 | // Ignore log notification by message: 6 | LogBox.ignoreLogs(['required dispatch_sync', 'flexWrap']) 7 | 8 | // Ignore all log notifications: 9 | // LogBox.ignoreAllLogs(); 10 | 11 | AppRegistry.registerComponent(appName, () => App) 12 | -------------------------------------------------------------------------------- /ios/.xcode.env: -------------------------------------------------------------------------------- 1 | export NODE_BINARY=$(command -v node) 2 | -------------------------------------------------------------------------------- /ios/_xcode.env: -------------------------------------------------------------------------------- 1 | # This `.xcode.env` file is versioned and is used to source the environment 2 | # used when running script phases inside Xcode. 3 | # To customize your local environment, you can create an `.xcode.env.local` 4 | # file that is not versioned. 5 | 6 | # NODE_BINARY variable contains the PATH to the node executable. 7 | # 8 | # Customize the NODE_BINARY variable here. 9 | # For example, to use nvm with brew, add the following line 10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use 11 | export NODE_BINARY=$(command -v node) 12 | -------------------------------------------------------------------------------- /ios/app.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/app.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/app/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : RCTAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /ios/app/AppDelegate.mm: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | #import 3 | #import "RNSplashScreen.h" // react-native-splash-screen 4 | 5 | @implementation AppDelegate 6 | 7 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 8 | { 9 | self.moduleName = @"app"; 10 | // You can add your custom initial props in the dictionary below. 11 | // They will be passed down to the ViewController used by React Native. 12 | self.initialProps = @{}; 13 | 14 | [super application:application didFinishLaunchingWithOptions:launchOptions]; 15 | 16 | [RNSplashScreen show]; // react-native-splash-screen 17 | 18 | return YES; 19 | } 20 | 21 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 22 | { 23 | #if DEBUG 24 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; 25 | #else 26 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 27 | #endif 28 | } 29 | 30 | /// This method controls whether the `concurrentRoot`feature of React18 is turned on or off. 31 | /// 32 | /// @see: https://reactjs.org/blog/2022/03/29/react-v18.html 33 | /// @note: This requires to be rendering on Fabric (i.e. on the New Architecture). 34 | /// @return: `true` if the `concurrentRoot` feature is enabled. Otherwise, it returns `false`. 35 | - (BOOL)concurrentRootEnabled 36 | { 37 | return true; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /ios/app/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/ios/app/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ios/app/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/ios/app/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ios/app/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/ios/app/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ios/app/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/ios/app/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ios/app/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/ios/app/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ios/app/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/ios/app/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ios/app/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/ios/app/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ios/app/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/ios/app/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ios/app/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/ios/app/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ios/app/Images.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/ios/app/Images.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ios/app/Images.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/ios/app/Images.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ios/app/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/ios/app/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ios/app/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/ios/app/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/app/Images.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/ios/app/Images.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ios/app/Images.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/ios/app/Images.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png -------------------------------------------------------------------------------- /ios/app/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ios/app/Images.xcassets/iTunesArtwork.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "iTunesArtwork@1x.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "iTunesArtwork@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "iTunesArtwork@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/app/Images.xcassets/iTunesArtwork.imageset/iTunesArtwork@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/ios/app/Images.xcassets/iTunesArtwork.imageset/iTunesArtwork@1x.png -------------------------------------------------------------------------------- /ios/app/Images.xcassets/iTunesArtwork.imageset/iTunesArtwork@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/ios/app/Images.xcassets/iTunesArtwork.imageset/iTunesArtwork@2x.png -------------------------------------------------------------------------------- /ios/app/Images.xcassets/iTunesArtwork.imageset/iTunesArtwork@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/ios/app/Images.xcassets/iTunesArtwork.imageset/iTunesArtwork@3x.png -------------------------------------------------------------------------------- /ios/app/Images.xcassets/slogo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "slogo.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "slogo@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "slogo@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/app/Images.xcassets/slogo.imageset/slogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/ios/app/Images.xcassets/slogo.imageset/slogo.png -------------------------------------------------------------------------------- /ios/app/Images.xcassets/slogo.imageset/slogo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/ios/app/Images.xcassets/slogo.imageset/slogo@2x.png -------------------------------------------------------------------------------- /ios/app/Images.xcassets/slogo.imageset/slogo@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/ios/app/Images.xcassets/slogo.imageset/slogo@3x.png -------------------------------------------------------------------------------- /ios/app/Images.xcassets/v2exArrow.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "arrow.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "arrow@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "arrow@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/app/Images.xcassets/v2exArrow.imageset/arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/ios/app/Images.xcassets/v2exArrow.imageset/arrow.png -------------------------------------------------------------------------------- /ios/app/Images.xcassets/v2exArrow.imageset/arrow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/ios/app/Images.xcassets/v2exArrow.imageset/arrow@2x.png -------------------------------------------------------------------------------- /ios/app/Images.xcassets/v2exArrow.imageset/arrow@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/ios/app/Images.xcassets/v2exArrow.imageset/arrow@3x.png -------------------------------------------------------------------------------- /ios/app/Images.xcassets/v2exArrowDark.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "arrow.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "arrow@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "arrow@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/app/Images.xcassets/v2exArrowDark.imageset/arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/ios/app/Images.xcassets/v2exArrowDark.imageset/arrow.png -------------------------------------------------------------------------------- /ios/app/Images.xcassets/v2exArrowDark.imageset/arrow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/ios/app/Images.xcassets/v2exArrowDark.imageset/arrow@2x.png -------------------------------------------------------------------------------- /ios/app/Images.xcassets/v2exArrowDark.imageset/arrow@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/ios/app/Images.xcassets/v2exArrowDark.imageset/arrow@3x.png -------------------------------------------------------------------------------- /ios/app/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | @autoreleasepool { 8 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /ios/appTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /metro.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Metro configuration for React Native 3 | * https://github.com/facebook/react-native 4 | * 5 | * @format 6 | */ 7 | 8 | module.exports = { 9 | transformer: { 10 | getTransformOptions: async () => ({ 11 | transform: { 12 | experimentalImportSupport: false, 13 | inlineRequires: true 14 | } 15 | }) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /node-version: -------------------------------------------------------------------------------- 1 | 18 -------------------------------------------------------------------------------- /plop/component/append.hbs: -------------------------------------------------------------------------------- 1 | export { default as {{ upperFirstName }} } from './{{ upperFirstName }}' 2 | -------------------------------------------------------------------------------- /plop/component/component.hbs: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by leon on {{ dtime }} 3 | */ 4 | import { ITheme, useTheme } from '@src/theme' 5 | import React from 'react' 6 | import { StyleProp, View, ViewStyle } from 'react-native' 7 | 8 | interface {{ upperFirstName }}Props { 9 | containerStyle?: StyleProp 10 | } 11 | 12 | const {{ upperFirstName }}Component = ({ containerStyle }: {{ upperFirstName }}Props) => { 13 | const { theme } = useTheme() 14 | 15 | return 16 | } 17 | 18 | const {{ upperFirstName }} = React.memo({{ upperFirstName }}Component) 19 | 20 | const styles = { 21 | container: (theme: ITheme) => ({ 22 | flex: 1 23 | }) 24 | } 25 | 26 | export default {{ upperFirstName }} 27 | -------------------------------------------------------------------------------- /plop/component/index.hbs: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by leon on {{ dtime }} 3 | */ -------------------------------------------------------------------------------- /plop/screen/append.hbs: -------------------------------------------------------------------------------- 1 | export { default as {{ upperFirstName }} } from './{{ upperFirstName }}' 2 | -------------------------------------------------------------------------------- /plop/screen/index.hbs: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by leon on {{ dtime }} 3 | */ 4 | -------------------------------------------------------------------------------- /plop/screen/screen.hbs: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by leon on {{ dtime }} 3 | */ 4 | 5 | import React, { useState } from 'react' 6 | import { connect } from 'react-redux' 7 | import { StyleSheet, View, ViewStyle, TextStyle } from 'react-native' 8 | 9 | import { translate } from '@src/i18n' 10 | import { useTheme, SylCommon } from '@src/theme' 11 | import { IState, ITheme, APPDataObject } from '@src/types' 12 | import * as CompS from '../components' 13 | import { Text, Spinner } from '@src/components' 14 | import { {{ upperFirstName }}ScreenProps as ScreenProps } from '@src/navigation/routes' 15 | import { RootState } from '@src/store' 16 | 17 | const {{ upperFirstName }} = ({ route, navigation, loading }: ScreenProps) => { 18 | const { theme } = useTheme() 19 | return ( 20 | 21 | Hello, {{ upperFirstName }}. 22 | 23 | ) 24 | } 25 | 26 | /** 27 | * @description styles {{ upperFirstName }} 28 | */ 29 | const styles = { 30 | container: (theme: ITheme): ViewStyle => ({ 31 | flex: 1 32 | }) 33 | } 34 | 35 | /** 36 | * default props 37 | */ 38 | {{ upperFirstName }}.defaultProps = { 39 | loading: false 40 | } 41 | 42 | const mapStateToProps = (state: RootState) => { 43 | return { member: state.member } 44 | } 45 | 46 | export default connect(mapStateToProps)({{ upperFirstName }}) 47 | -------------------------------------------------------------------------------- /plopfile.cjs: -------------------------------------------------------------------------------- 1 | const screenGenerator = require('./plop/screen/prompt.cjs') 2 | const componentGenerator = require('./plop/component/prompt.cjs') 3 | 4 | module.exports = function (plop) { 5 | plop.setGenerator('screen', screenGenerator) 6 | plop.setGenerator('component', componentGenerator) 7 | } 8 | -------------------------------------------------------------------------------- /src/App.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-02-18 21:26:32. 3 | * Last modified at 2023-03-05 22:33:59 4 | */ 5 | 6 | import { persistor, store } from '@src/store' 7 | import React from 'react' 8 | import { Provider } from 'react-redux' 9 | import { PersistGate } from 'redux-persist/integration/react' 10 | import { Spinner } from './components/common' 11 | import { onAppStart } from './helper/app' 12 | import { AppNavigationContainer } from './navigation/Navigator' 13 | import { ThemeProvider } from './theme' 14 | onAppStart(store) 15 | const App = () => { 16 | return ( 17 | 18 | } persistor={persistor}> 19 | 20 | 21 | 22 | 23 | 24 | ) 25 | } 26 | export default App 27 | -------------------------------------------------------------------------------- /src/actions/NodeActions.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-02-22 19:58:57. 3 | * Last modified at 2022-10-20 17:37:56 4 | */ 5 | 6 | import { Dispatch } from 'redux' 7 | import { ApiLib } from '@src/api' 8 | import { APP_ALL_NODE_INFO } from './types' 9 | import { logError } from '@src/helper/logger' 10 | export const fetchAllNode = () => async (dispatch: Dispatch) => { 11 | try { 12 | const nodes = await ApiLib.node.all() 13 | dispatch({ 14 | type: APP_ALL_NODE_INFO, 15 | payload: nodes 16 | }) 17 | } catch (e) { 18 | logError(e) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/actions/NotificationActions.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-02-22 19:58:57. 3 | * Last modified at 2022-02-28 13:33:51 4 | */ 5 | 6 | import { APP_NOTIFICATION_LATEST, APP_NOTIFICATION_REMOVE } from './types' 7 | export const notificationList = () => async (dispatch: any) => { 8 | dispatch({ 9 | type: APP_NOTIFICATION_LATEST, 10 | payload: {} 11 | }) 12 | } 13 | export const notificationRemove = () => async (dispatch: any) => { 14 | dispatch({ 15 | type: APP_NOTIFICATION_REMOVE, 16 | payload: {} 17 | }) 18 | } 19 | -------------------------------------------------------------------------------- /src/actions/SettingActions.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-03 18:02:33. 3 | * Last modified at 2022-03-09 22:11:16 4 | */ 5 | 6 | import { Dispatch } from 'redux' 7 | import { APP_SETTING_LOCALES, APP_SETTING_THEME, ThemeType, LanguageTagType } from '../types' 8 | import { changeLocale } from '@src/i18n' 9 | export const setLocales = (languageTag: LanguageTagType) => { 10 | changeLocale(languageTag) 11 | return async (dispatch: Dispatch) => { 12 | dispatch({ 13 | type: APP_SETTING_LOCALES, 14 | payload: languageTag 15 | }) 16 | } 17 | } 18 | export const setTheme = (theme: ThemeType) => ({ 19 | type: APP_SETTING_THEME, 20 | payload: theme 21 | }) 22 | -------------------------------------------------------------------------------- /src/actions/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-02-22 19:58:57. 3 | * Last modified at 2022-04-19 20:08:19 4 | */ 5 | 6 | export * from './RestActions' 7 | export * from './MemberActions' 8 | export * from './NodeActions' 9 | export * from './NotificationActions' 10 | export * from './TopicActions' 11 | export * from './SettingActions' 12 | export * from './CacheAction' 13 | -------------------------------------------------------------------------------- /src/api/lib/member/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-10-20 17:25:36. 3 | * Last modified at 2022-10-21 14:31:58 4 | */ 5 | 6 | import { AppAPI, AppObject } from '../../types' 7 | export default (v2ex: AppAPI.APP): AppAPI.MemberAPI => ({ 8 | myToken: () => v2ex.get('/token', undefined, undefined, undefined, 'v2'), 9 | myProfile: () => v2ex.get('/member', undefined, undefined, undefined, 'v2'), 10 | profile: (id: string | number) => 11 | v2ex.get( 12 | `/members/show.json?${typeof id === 'string' ? 'username' : 'id'}=${id}`, 13 | undefined, 14 | undefined, 15 | undefined, 16 | undefined 17 | ), 18 | token: (token: string) => 19 | v2ex.get( 20 | `/token`, 21 | { 22 | Authorization: `Bearer ${token}` 23 | }, 24 | undefined, 25 | undefined, 26 | 'v2' 27 | ) 28 | }) 29 | -------------------------------------------------------------------------------- /src/api/lib/node/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-10-20 17:25:36. 3 | * Last modified at 2022-10-21 14:31:58 4 | */ 5 | 6 | import { AppAPI, AppObject } from '../../types' 7 | export default (v2ex: AppAPI.APP): AppAPI.NodeAPI => ({ 8 | get: (id: string | number, version: AppAPI.API_VERSION): Promise => 9 | v2ex.get( 10 | version === 'v2' ? `/nodes/${id}` : `/nodes/show.json?${typeof id === 'string' ? 'name' : 'id'}=${id}`, 11 | undefined, 12 | undefined, 13 | undefined, 14 | version 15 | ), 16 | all: () => v2ex.get('/nodes/all.json', undefined, undefined, undefined, undefined) 17 | }) 18 | -------------------------------------------------------------------------------- /src/api/lib/notification/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-10-20 17:25:36. 3 | * Last modified at 2022-10-21 14:31:58 4 | */ 5 | 6 | import { AppAPI, AppObject } from '../../types' 7 | export default (v2ex: AppAPI.APP): AppAPI.NotificationAPI => ({ 8 | list: (page: number) => 9 | v2ex.get(`/notifications?p=${page}`, undefined, undefined, undefined, 'v2'), 10 | /** 11 | * Remove notification 12 | */ 13 | remove: (id: string) => v2ex.delete(`/notifications/${id}`, undefined, undefined, 'v2') 14 | }) 15 | -------------------------------------------------------------------------------- /src/api/lib/reply/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-10-20 17:25:36. 3 | * Last modified at 2022-10-21 14:31:58 4 | */ 5 | 6 | import { AppAPI, AppObject } from '../../types' 7 | export default (v2ex: AppAPI.APP): AppAPI.ReplyAPI => ({ 8 | pager: (topic_id: number, page: number): Promise => 9 | v2ex.get(`/topics/${topic_id}/replies?p=${page}`, undefined, undefined, undefined, 'v2'), 10 | /** 11 | * Get topic replies 12 | * @param topic_id : topic id 13 | */ 14 | replies: (topic_id: number): Promise => 15 | v2ex.get( 16 | `/replies/show.json?topic_id=${topic_id}`, 17 | undefined, 18 | undefined, 19 | undefined, 20 | undefined 21 | ) 22 | }) 23 | -------------------------------------------------------------------------------- /src/api/lib/topic/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-10-20 17:25:36. 3 | * Last modified at 2022-10-21 14:31:58 4 | */ 5 | 6 | import { AppAPI, AppObject } from '../../types' 7 | export default (v2ex: AppAPI.APP): AppAPI.TopicAPI => ({ 8 | pager: (name = 'python', page: number = 1) => 9 | v2ex.get(`/nodes/${name}/topics?p=${page}`, undefined, undefined, undefined, 'v2'), 10 | /** 11 | * get node topic by api version 1 12 | * @param name : node name 13 | */ 14 | topics: (name: number | string = 'python', get_type: 'username' | 'node_id' | 'node_name' | 'id') => 15 | v2ex.get(`/topics/show.json?${get_type}=${name}`, undefined, undefined, undefined, undefined), 16 | /** 17 | * Get latest topic list by api version 1 18 | */ 19 | latestTopics: () => v2ex.get('/topics/latest.json', undefined, undefined, undefined, undefined), 20 | /** 21 | * Get hot topic list by api version 1 22 | */ 23 | hotTopics: () => v2ex.get('/topics/hot.json', undefined, undefined, undefined, undefined), 24 | /** 25 | * Get topic info by topic id 26 | * @param id : topic id 27 | */ 28 | topic: (id: number) => v2ex.get(`/topics/${id}`, undefined, undefined, undefined, 'v2') 29 | }) 30 | -------------------------------------------------------------------------------- /src/assets/images/icons/app/256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/app/256.png -------------------------------------------------------------------------------- /src/assets/images/icons/app/256@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/app/256@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/app/256@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/app/256@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/app/arrow/dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/app/arrow/dark.png -------------------------------------------------------------------------------- /src/assets/images/icons/app/arrow/dark@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/app/arrow/dark@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/app/arrow/dark@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/app/arrow/dark@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/app/arrow/light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/app/arrow/light.png -------------------------------------------------------------------------------- /src/assets/images/icons/app/arrow/light@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/app/arrow/light@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/app/arrow/light@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/app/arrow/light@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/app/slogo/dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/app/slogo/dark.png -------------------------------------------------------------------------------- /src/assets/images/icons/app/slogo/dark@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/app/slogo/dark@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/app/slogo/dark@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/app/slogo/dark@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/app/slogo/light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/app/slogo/light.png -------------------------------------------------------------------------------- /src/assets/images/icons/app/slogo/light@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/app/slogo/light@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/app/slogo/light@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/app/slogo/light@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/draw/fire-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/draw/fire-active.png -------------------------------------------------------------------------------- /src/assets/images/icons/draw/fire-active@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/draw/fire-active@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/draw/fire-active@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/draw/fire-active@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/draw/fire-inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/draw/fire-inactive.png -------------------------------------------------------------------------------- /src/assets/images/icons/draw/fire-inactive@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/draw/fire-inactive@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/draw/fire-inactive@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/draw/fire-inactive@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/draw/news-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/draw/news-active.png -------------------------------------------------------------------------------- /src/assets/images/icons/draw/news-active@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/draw/news-active@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/draw/news-active@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/draw/news-active@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/draw/news-inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/draw/news-inactive.png -------------------------------------------------------------------------------- /src/assets/images/icons/draw/news-inactive@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/draw/news-inactive@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/draw/news-inactive@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/draw/news-inactive@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/header/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/header/back.png -------------------------------------------------------------------------------- /src/assets/images/icons/header/back@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/header/back@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/header/back@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/header/back@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/header/board.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/header/board.png -------------------------------------------------------------------------------- /src/assets/images/icons/header/board@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/header/board@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/header/board@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/header/board@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/header/heart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/header/heart.png -------------------------------------------------------------------------------- /src/assets/images/icons/header/heart@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/header/heart@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/header/heart@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/header/heart@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/header/logout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/header/logout.png -------------------------------------------------------------------------------- /src/assets/images/icons/header/logout@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/header/logout@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/header/logout@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/header/logout@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/header/more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/header/more.png -------------------------------------------------------------------------------- /src/assets/images/icons/header/more@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/header/more@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/header/more@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/header/more@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/header/more_vert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/header/more_vert.png -------------------------------------------------------------------------------- /src/assets/images/icons/header/more_vert@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/header/more_vert@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/header/more_vert@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/header/more_vert@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/header/refresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/header/refresh.png -------------------------------------------------------------------------------- /src/assets/images/icons/header/refresh@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/header/refresh@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/header/refresh@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/header/refresh@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/header/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/header/search.png -------------------------------------------------------------------------------- /src/assets/images/icons/header/search@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/header/search@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/header/search@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/header/search@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/header/star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/header/star.png -------------------------------------------------------------------------------- /src/assets/images/icons/header/star@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/header/star@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/header/star@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/header/star@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/header/urlscheme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/header/urlscheme.png -------------------------------------------------------------------------------- /src/assets/images/icons/header/urlscheme@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/header/urlscheme@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/header/urlscheme@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/header/urlscheme@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/node/document.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/node/document.png -------------------------------------------------------------------------------- /src/assets/images/icons/node/document@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/node/document@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/node/document@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/node/document@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/node/star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/node/star.png -------------------------------------------------------------------------------- /src/assets/images/icons/node/star@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/node/star@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/node/star@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/node/star@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/node/urlscheme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/node/urlscheme.png -------------------------------------------------------------------------------- /src/assets/images/icons/node/urlscheme@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/node/urlscheme@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/node/urlscheme@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/node/urlscheme@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/notification/action.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/notification/action.png -------------------------------------------------------------------------------- /src/assets/images/icons/notification/action@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/notification/action@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/notification/action@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/notification/action@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/notification/time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/notification/time.png -------------------------------------------------------------------------------- /src/assets/images/icons/notification/time@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/notification/time@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/notification/time@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/notification/time@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/placeholder/construction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/placeholder/construction.png -------------------------------------------------------------------------------- /src/assets/images/icons/placeholder/construction@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/placeholder/construction@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/placeholder/construction@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/placeholder/construction@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/placeholder/notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/placeholder/notification.png -------------------------------------------------------------------------------- /src/assets/images/icons/placeholder/notification@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/placeholder/notification@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/placeholder/notification@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/placeholder/notification@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/placeholder/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/placeholder/search.png -------------------------------------------------------------------------------- /src/assets/images/icons/placeholder/search@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/placeholder/search@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/placeholder/search@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/placeholder/search@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/profile/default-avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/profile/default-avatar.png -------------------------------------------------------------------------------- /src/assets/images/icons/profile/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/profile/github.png -------------------------------------------------------------------------------- /src/assets/images/icons/profile/github@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/profile/github@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/profile/github@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/profile/github@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/profile/location.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/profile/location.png -------------------------------------------------------------------------------- /src/assets/images/icons/profile/location@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/profile/location@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/profile/location@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/profile/location@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/profile/telegram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/profile/telegram.png -------------------------------------------------------------------------------- /src/assets/images/icons/profile/telegram@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/profile/telegram@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/profile/telegram@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/profile/telegram@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/profile/twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/profile/twitter.png -------------------------------------------------------------------------------- /src/assets/images/icons/profile/twitter@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/profile/twitter@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/profile/twitter@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/profile/twitter@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/profile/urlscheme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/profile/urlscheme.png -------------------------------------------------------------------------------- /src/assets/images/icons/profile/urlscheme@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/profile/urlscheme@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/profile/urlscheme@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/profile/urlscheme@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/home-focus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/home-focus.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/home-focus@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/home-focus@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/home-focus@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/home-focus@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/home.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/home@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/home@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/home@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/home@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/hot-focus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/hot-focus.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/hot-focus@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/hot-focus@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/hot-focus@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/hot-focus@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/hot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/hot.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/hot@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/hot@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/hot@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/hot@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/like-focus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/like-focus.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/like-focus@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/like-focus@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/like-focus@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/like-focus@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/like.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/like.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/like@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/like@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/like@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/like@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/my-focus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/my-focus.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/my-focus@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/my-focus@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/my-focus@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/my-focus@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/my.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/my.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/my@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/my@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/my@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/my@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/node-focus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/node-focus.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/node-focus@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/node-focus@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/node-focus@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/node-focus@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/node.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/node.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/node@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/node@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/node@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/node@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/notification-focus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/notification-focus.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/notification-focus@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/notification-focus@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/notification-focus@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/notification-focus@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/notification.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/notification@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/notification@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/bottom/notification@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/bottom/notification@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/title/comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/title/comment.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/title/comment@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/title/comment@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/title/comment@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/title/comment@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/title/news.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/title/news.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/title/news@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/title/news@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/tab/title/news@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/tab/title/news@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/cached.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/cached.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/cached@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/cached@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/cached@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/cached@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/check-right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/check-right.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/check-right@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/check-right@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/check-right@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/check-right@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/email.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/email.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/email@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/email@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/email@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/email@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/github.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/github@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/github@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/github@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/github@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/group.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/group@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/group@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/group@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/group@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/language.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/language.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/language@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/language@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/language@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/language@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/opensource.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/opensource.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/opensource@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/opensource@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/opensource@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/opensource@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/right-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/right-arrow.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/right-arrow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/right-arrow@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/right-arrow@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/right-arrow@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/score.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/score.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/score@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/score@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/score@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/score@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/share.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/share@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/share@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/share@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/share@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/theme.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/theme@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/theme@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/theme@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/theme@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/twitter.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/twitter@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/twitter@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/twitter@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/twitter@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/urlscheme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/urlscheme.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/urlscheme@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/urlscheme@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/table/urlscheme@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/table/urlscheme@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/topic/comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/topic/comment.png -------------------------------------------------------------------------------- /src/assets/images/icons/topic/comment@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/topic/comment@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/topic/comment@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/topic/comment@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/topic/paper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/topic/paper.png -------------------------------------------------------------------------------- /src/assets/images/icons/topic/paper@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/topic/paper@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/topic/paper@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/topic/paper@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/topic/people-voice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/topic/people-voice.png -------------------------------------------------------------------------------- /src/assets/images/icons/topic/people-voice@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/topic/people-voice@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/topic/people-voice@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/topic/people-voice@3x.png -------------------------------------------------------------------------------- /src/assets/images/icons/topic/update.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/topic/update.png -------------------------------------------------------------------------------- /src/assets/images/icons/topic/update@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/topic/update@2x.png -------------------------------------------------------------------------------- /src/assets/images/icons/topic/update@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funnyzak/react-native-v2ex/ca38977a5f5b7097d0ddb414e752fbbb54f457a5/src/assets/images/icons/topic/update@3x.png -------------------------------------------------------------------------------- /src/components/actions-sheet/Btn.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-11-05 20:08:36. 3 | * Last modified at 2022-11-05 20:08:36 4 | */ 5 | 6 | import React from 'react' 7 | import { ColorValue, GestureResponderEvent, StyleSheet, Text, TouchableHighlight, View } from 'react-native' 8 | type MenuButtonProps = { 9 | title: string 10 | onPress?: ((event: GestureResponderEvent) => void) | undefined 11 | color?: ColorValue | undefined 12 | } 13 | function MenuButton({ title, color, onPress }: MenuButtonProps) { 14 | return ( 15 | 16 | 17 | {title} 18 | 19 | 20 | ) 21 | } 22 | const styles = StyleSheet.create({ 23 | container: { 24 | flexDirection: 'row', 25 | alignItems: 'center', 26 | width: '100%', 27 | paddingTop: 10, 28 | paddingBottom: 10, 29 | paddingLeft: 20, 30 | paddingRight: 20 31 | }, 32 | title: { 33 | fontSize: 16, 34 | marginLeft: 15, 35 | color: '#1A212E' 36 | } 37 | }) 38 | export default MenuButton 39 | -------------------------------------------------------------------------------- /src/components/actions-sheet/MenuSheet.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-11-05 20:08:36. 3 | * Last modified at 2022-11-05 20:08:36 4 | */ 5 | 6 | import React, { useRef } from 'react' 7 | import ActionSheet, { ActionSheetRef, registerSheet, SheetProps } from 'react-native-actions-sheet' 8 | import MenuButton from './Btn' 9 | const Sheet = (props: SheetProps) => { 10 | const actionSheetRef = useRef(null) 11 | return ( 12 | 19 | console.log('action 1')} /> 20 | console.log('action 2')} /> 21 | console.log('action 3...')} /> 22 | 23 | ) 24 | } 25 | registerSheet('menu-sheet', Sheet) 26 | export default Sheet 27 | -------------------------------------------------------------------------------- /src/components/actions-sheet/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-11-05 20:08:36. 3 | * Last modified at 2022-11-06 13:49:16 4 | */ 5 | 6 | import { registerSheet } from 'react-native-actions-sheet' 7 | import ConfirmSheet from './ConfirmSheet' 8 | import ContentSheet from './ContentSheet' 9 | import './MenuSheet' 10 | registerSheet('confirm-sheet', ConfirmSheet, 'global') 11 | registerSheet('content-sheet', ContentSheet, 'global') 12 | export {} 13 | /** 14 | * Since we are not importing our Sheets in any component or file, we want to make sure 15 | * they are bundled by the JS bundler. Hence we will import this file in App.js. 16 | */ 17 | -------------------------------------------------------------------------------- /src/components/atoms/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-02-28 16:15:21. 3 | * Last modified at 2022-02-28 16:15:21 4 | */ 5 | 6 | export { default as Logo } from './logo' 7 | -------------------------------------------------------------------------------- /src/components/atoms/logo/index.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-02-28 16:15:21. 3 | * Last modified at 2022-04-12 19:50:05 4 | */ 5 | 6 | import { useTheme } from '@src/theme' 7 | import React from 'react' 8 | import { Image, ImageStyle, StyleProp, View } from 'react-native' 9 | interface IProps { 10 | style?: StyleProp 11 | width?: number 12 | height?: number 13 | resizeMode?: 'contain' | 'cover' | 'stretch' | 'repeat' | 'center' 14 | } 15 | const Logo = ({ width = 42, height = 42, style, resizeMode = 'center' }: IProps) => { 16 | const { theme } = useTheme() 17 | return ( 18 | 19 | 24 | 25 | ) 26 | } 27 | export default Logo 28 | const styles = { 29 | logo: { 30 | width: '100%', 31 | height: '100%' 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/components/common/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-02-28 13:33:51. 3 | * Last modified at 2022-11-08 23:51:44 4 | */ 5 | 6 | export * from './Spinner' 7 | export * from './Text' 8 | export * from './Input' 9 | export * from './Button' 10 | export * from './Placeholder' 11 | export { default as CheckUpdate } from './CheckUpdate' 12 | -------------------------------------------------------------------------------- /src/components/header/index.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-02-28 16:15:21. 3 | * Last modified at 2022-03-03 21:32:55 4 | */ 5 | 6 | import { StatusBar, View, ViewStyle } from 'react-native' 7 | import React from 'react' 8 | import { useTheme } from '@src/theme' 9 | import { Theme } from '@src/types' 10 | import { Logo } from '../atoms' 11 | const Header = ({ headerRight }: { headerRight: React.ReactNode }) => { 12 | const { theme } = useTheme() 13 | return ( 14 | 15 | 16 | 17 | {headerRight} 18 | 19 | ) 20 | } 21 | export default Header 22 | const styles = { 23 | header: (theme: Theme) => ({ 24 | backgroundColor: theme.colors.white, 25 | paddingHorizontal: 16, 26 | paddingVertical: 8 27 | }), 28 | headerRight: (): ViewStyle => ({ 29 | position: 'absolute', 30 | right: 16, 31 | top: 4 32 | }) 33 | } 34 | -------------------------------------------------------------------------------- /src/components/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-02-28 16:15:21. 3 | * Last modified at 2022-11-20 21:04:24 4 | */ 5 | 6 | export { default as Header } from './header' 7 | export { default as LoadingModal } from './loading-modal' 8 | export { default as Loading } from './loading' 9 | export * from './atoms' 10 | export * from './common' 11 | export { default as Avatar } from './avatar' 12 | export * from './search-bar' 13 | export * from './toast' 14 | -------------------------------------------------------------------------------- /src/components/loading/index.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-02-28 16:15:21. 3 | * Last modified at 2022-04-07 21:38:17 4 | */ 5 | 6 | import { useTheme } from '@src/theme' 7 | import React from 'react' 8 | import { ActivityIndicator, View } from 'react-native' 9 | interface IProps { 10 | visible: boolean 11 | size?: number 12 | } 13 | const LoadingComponent = ({ visible, size = 70 }: IProps) => { 14 | const { theme } = useTheme() 15 | return {visible && } 16 | } 17 | const Loading = React.memo(LoadingComponent) 18 | export default Loading 19 | -------------------------------------------------------------------------------- /src/components/search-bar/SearchIcon.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-11-20 21:04:09. 3 | * Last modified at 2022-11-20 21:04:09 4 | */ 5 | 6 | import React from 'react' 7 | import Svg, { Path, SvgProps } from 'react-native-svg' 8 | const SearchIconComponent = (props: SvgProps) => { 9 | return ( 10 | 11 | 17 | 18 | ) 19 | } 20 | const SearchIcon = React.memo(SearchIconComponent) 21 | export default SearchIcon 22 | -------------------------------------------------------------------------------- /src/components/search-bar/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-11-20 21:04:09. 3 | * Last modified at 2022-11-20 21:04:09 4 | */ 5 | 6 | export { default as SearchBar } from './SearchBar' 7 | export { default as SearchIcon } from './SearchIcon' 8 | -------------------------------------------------------------------------------- /src/components/toast/ToastContext.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-10 22:00:57. 3 | * Last modified at 2022-04-11 20:33:24 4 | */ 5 | 6 | import React, { ReactNode, useContext } from 'react' 7 | import { ToastShowParams as ToastMessageShowParams } from 'react-native-toast-message/lib' 8 | export type ToastPositionType = 'top' | 'center' | 'bottom' 9 | export interface ToastShowProps { 10 | text: string | ReactNode 11 | position?: ToastPositionType 12 | duration?: number 13 | opacity?: number 14 | callback?: () => void 15 | } 16 | export type ToastShowType = ToastShowProps | string 17 | export interface ToastContextProps { 18 | showToast: (opts: ToastShowType) => void 19 | showMessage: (opts: string | ToastMessageShowParams) => void 20 | hideMessage: (params?: any) => void 21 | closeToast: (duration?: number) => void 22 | } 23 | export const ToastContext = React.createContext({ 24 | showToast: () => {}, 25 | showMessage: () => {}, 26 | hideMessage: () => {}, 27 | closeToast: () => {} 28 | }) 29 | export const useToast = () => useContext(ToastContext) 30 | export default ToastContext 31 | -------------------------------------------------------------------------------- /src/components/toast/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-10 22:00:57. 3 | * Last modified at 2022-03-11 00:32:42 4 | */ 5 | 6 | export { default as ToastProvider } from './ToastProvider' 7 | export * from './ToastContext' 8 | // import { useToast } from '@src/components/toast' 9 | // const component = (props) => { 10 | // const { showToast } = useToast() 11 | // useEffect(() => { 12 | // showToast('hello world') 13 | // showToast({text: 'hello world', position: 'top', opacity: 0.5}) 14 | // }, []) 15 | // .. 16 | // } 17 | -------------------------------------------------------------------------------- /src/config/app.config.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-10-20 17:37:56. 3 | * Last modified at 2022-10-20 17:37:56 4 | */ 5 | 6 | export const AppApiOptions = { 7 | url: 'https://www.v2ex.com', 8 | store: 'api', 9 | userAgent: 'V2ex App API Library', 10 | authentication: { 11 | token: 'hello world' 12 | } 13 | } 14 | export const brandName = 'V2HUB' 15 | export const aboutUs = { 16 | author: 'leon', 17 | email: 'y@yycc.me', 18 | site: 'https://funnyzak.8b.io/', 19 | github: 'funnyzak', 20 | wechat: 'funnyzak', 21 | twitter: 'funnyzak', 22 | weibo: '1580726025', 23 | discord: 'https://discord.gg/S5mCxjHyub', 24 | telegram: 'igeekhub', 25 | copyright: '© 2022 funnyzak' 26 | } 27 | -------------------------------------------------------------------------------- /src/helper/app.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-02-23 21:59:29. 3 | * Last modified at 2022-10-20 17:37:56 4 | */ 5 | 6 | import AsyncStorage from '@react-native-async-storage/async-storage' 7 | import { Store } from 'redux' 8 | import { ApiLib } from '@src/api' 9 | import { initV2ex, setCurrentToken, logout } from '../actions' 10 | import { MEMBER_TOKEN_KEY } from '@src/config/constants' 11 | import { logError } from './logger' 12 | export const onAppStart = async (store: Store) => { 13 | store.dispatch(initV2ex() as any) 14 | const memberToken = await AsyncStorage.getItem(MEMBER_TOKEN_KEY) 15 | if (memberToken !== null) { 16 | try { 17 | const token = await ApiLib.member.token(memberToken) 18 | store.dispatch(setCurrentToken(token)) 19 | } catch (error) { 20 | store.dispatch(logout() as any) 21 | console.log('onAppStart -> unable to retrieve current member', error) 22 | logError(error) 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/helper/cache.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-19 20:42:19. 3 | * Last modified at 2022-10-20 18:07:33 4 | */ 5 | 6 | import { AppObject } from '@src/types' 7 | import { CACHE_EXPIRE_TIME } from '@src/config/constants' 8 | export const memberFromCache = ( 9 | userid: number | string, 10 | list?: { pullTime: number; info: AppObject.Member }[], 11 | cacheExpireTime: number = CACHE_EXPIRE_TIME 12 | ) => { 13 | if (!list || list.length === 0) { 14 | return undefined 15 | } 16 | return ( 17 | list.find( 18 | (v) => 19 | v.pullTime + cacheExpireTime > new Date().getTime() && 20 | (typeof userid === 'number' ? v.info.id === userid : v.info.username === userid) 21 | )?.info ?? undefined 22 | ) 23 | } 24 | export const nodeFromCache = (nodeid: number | string, list?: { pullTime: number; info: AppObject.Node }[]) => { 25 | if (!list || list.length === 0) { 26 | return undefined 27 | } 28 | return ( 29 | list.find( 30 | (v) => 31 | v.pullTime + CACHE_EXPIRE_TIME > new Date().getTime() && 32 | (typeof nodeid === 'number' ? v.info.id === nodeid : v.info.name === nodeid) 33 | )?.info ?? undefined 34 | ) 35 | } 36 | -------------------------------------------------------------------------------- /src/helper/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-10 22:02:18. 3 | * Last modified at 2022-04-14 17:36:16 4 | */ 5 | 6 | export * as AppHelper from './app' 7 | export * as LoggerHelper from './logger' 8 | -------------------------------------------------------------------------------- /src/helper/logger.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-02-23 22:06:29. 3 | * Last modified at 2022-11-05 20:08:36 4 | */ 5 | 6 | // import BugSnag from '@bugsnag/react-native' 7 | // BugSnag.start({ 8 | // context: 'context', 9 | // onBreadcrumb: (breadcrumb) => { 10 | // console.log('onBreadcrumb', breadcrumb) 11 | // }, 12 | // onError: (event, cb) => { 13 | // console.log('onError', event) 14 | // cb(null, true) 15 | // }, 16 | // logger: { 17 | // debug: (...args) => { 18 | // console.log('debug', args) 19 | // }, 20 | // info: (...args) => { 21 | // console.log('info', args) 22 | // }, 23 | // warn: (...args) => { 24 | // console.log('warn', args) 25 | // }, 26 | // error: (...args) => { 27 | // console.log('error', args) 28 | // } 29 | // }, 30 | // metadata: { 31 | // key: 'value' 32 | // }, 33 | // featureFlags: [], 34 | // plugins: [], 35 | // user: { 36 | // id: 'id', 37 | // name: 'name', 38 | // email: 'email' 39 | // } 40 | // }) 41 | // export default BugSnag 42 | export const logError = (error: any) => { 43 | console.log(error) 44 | } 45 | export const logInfo = (...info: any[]) => { 46 | if (info[0] instanceof Error) { 47 | console.error(info) 48 | } else { 49 | console.log(...info) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/helper/node.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-20 23:00:11. 3 | * Last modified at 2022-10-20 18:07:33 4 | */ 5 | 6 | import { store } from '@src/store' 7 | import { AppObject } from '@src/types' 8 | /** 9 | * home tab nodes 10 | */ 11 | export interface TabNodeProps { 12 | title: string 13 | parentNodeNames: any[] 14 | children?: AppObject.Node[] 15 | } 16 | export let TabNodes: TabNodeProps[] = [ 17 | { title: 'Life', parentNodeNames: ['life'] }, 18 | { title: 'Geek', parentNodeNames: ['geek'] }, 19 | { title: 'V2EX', parentNodeNames: ['v2ex'] }, 20 | { title: 'Internet', parentNodeNames: ['internet'] }, 21 | { title: 'Programming', parentNodeNames: ['programming'] }, 22 | { title: 'Apple', parentNodeNames: ['apple'] }, 23 | { title: 'Games', parentNodeNames: ['games'] }, 24 | { title: 'Cloud', parentNodeNames: ['cloud'] }, 25 | { title: 'Hardware', parentNodeNames: ['hardware'] }, 26 | { title: 'Earth', parentNodeNames: ['cn', 'us'] } 27 | ] 28 | export const nodeChildren = (rootNode: TabNodeProps, nodeData?: AppObject.Node[]): AppObject.Node[] => { 29 | const { title, parentNodeNames: parentNodes } = rootNode 30 | let nodes: AppObject.Node[] = [] 31 | const all_node = nodeData ?? store.getState().app.allNode 32 | if (!all_node) return nodes 33 | return all_node.filter((v) => parentNodes.includes(v.parent_node_name)) 34 | } 35 | -------------------------------------------------------------------------------- /src/hooks/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-02-28 14:56:38. 3 | * Last modified at 2022-02-28 15:48:47 4 | */ 5 | 6 | import { AppDispatch, RootState } from '@src/store' 7 | import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux' 8 | export const useAppDispatch = () => useDispatch() 9 | export const useAppSelector: TypedUseSelectorHook = useSelector 10 | -------------------------------------------------------------------------------- /src/hooks/useIsFocus.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-11-06 21:37:04. 3 | * Last modified at 2022-11-06 21:37:04 4 | */ 5 | 6 | import * as React from 'react' 7 | import { StatusBar, StatusBarProps } from 'react-native' 8 | import { useIsFocused } from '@react-navigation/native' 9 | /* 10 | If using a tab or drawer navigator, it's a bit more complex because all of the screens in the navigator might be rendered at once and kept rendered - that means that the last StatusBar config you set will be used (likely on the final tab of your tab navigator, not what the user is seeing). 11 | Usage: 12 | */ 13 | export const FocusAwareStatusBar = (props: StatusBarProps) => { 14 | const isFocused = useIsFocused() 15 | return isFocused ? : null 16 | } 17 | -------------------------------------------------------------------------------- /src/hooks/useMember.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-20 20:13:53. 3 | * Last modified at 2022-10-22 19:06:30 4 | */ 5 | 6 | import { CACHE_EXPIRE_TIME } from '@src/config/constants' 7 | import { memberFromCache } from '@src/helper/cache' 8 | import { RootState } from '@src/store' 9 | import { useEffect, useState } from 'react' 10 | import { useAppDispatch, useAppSelector } from '.' 11 | import { cacheMember } from '../actions' 12 | import { AppObject } from '../types' 13 | export const useMember = ({ userid: id, forcePull = true }: { userid: string | number; forcePull?: boolean }) => { 14 | const members = useAppSelector((_state: RootState) => _state.cache.members) 15 | const [info, setInfo] = useState(memberFromCache(id, members)) 16 | const dispatch = useAppDispatch() 17 | useEffect(() => { 18 | const _info = memberFromCache(id, members, forcePull ? 5 * 1000 : CACHE_EXPIRE_TIME) 19 | if (_info !== undefined) { 20 | setInfo(_info) 21 | } else { 22 | dispatch(cacheMember(id) as any) 23 | } 24 | }, [id, info, members]) // eslint-disable-line react-hooks/exhaustive-deps 25 | return { 26 | member: info 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/hooks/useNode.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-19 20:43:45. 3 | * Last modified at 2022-10-20 18:07:33 4 | */ 5 | 6 | import { nodeFromCache } from '@src/helper/cache' 7 | import { useEffect, useState } from 'react' 8 | import { useAppDispatch, useAppSelector } from '.' 9 | import { cacheNode } from '../actions' 10 | import { AppObject } from '../types' 11 | import { RootState } from '@src/store' 12 | export const useNode = ({ nodeid: id }: { nodeid: number | string }) => { 13 | const nodes = useAppSelector((_state: RootState) => _state.cache.nodes) 14 | const [info, setInfo] = useState(nodeFromCache(id, nodes)) 15 | const dispatch = useAppDispatch() 16 | useEffect(() => { 17 | const _info = nodeFromCache(id, nodes) 18 | if (_info !== undefined) { 19 | setInfo(_info) 20 | } else { 21 | dispatch(cacheNode(id) as any) 22 | } 23 | }, [id, info, nodes]) // eslint-disable-line react-hooks/exhaustive-deps 24 | return { 25 | node: info 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/hooks/useSession.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-20 20:13:53. 3 | * Last modified at 2022-04-20 20:13:53 4 | */ 5 | 6 | import { RootState } from '@src/store' 7 | import { useAppSelector } from '.' 8 | export const useSession = () => { 9 | const member = useAppSelector((_state: RootState) => _state.member) 10 | return { 11 | logined: member.token, 12 | profile: member.profile, 13 | token: member.token 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/hooks/useTopic.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-02-25 22:34:28. 3 | * Last modified at 2022-10-20 18:07:33 4 | */ 5 | 6 | import { RootState } from '@src/store' 7 | import { useEffect, useState } from 'react' 8 | import { readTopic } from '../actions' 9 | import { AppObject } from '../types' 10 | import { useAppDispatch, useAppSelector } from './' 11 | export const useTopic = ({ topicId }: { topicId: number }) => { 12 | const [topic, setTopic] = useState(undefined) 13 | const v2ex = useAppSelector((_state: RootState) => _state.app.v2ex) 14 | const dispatch = useAppDispatch() 15 | useEffect(() => { 16 | const fetchTopic = async () => { 17 | const _topics = await v2ex?.topic.topics(topicId, 'id') 18 | if (_topics?.[0]) { 19 | dispatch(readTopic(_topics?.[0]) as any) 20 | } 21 | setTopic(_topics?.[0]) 22 | } 23 | if (topicId) { 24 | fetchTopic() 25 | } 26 | }, [topicId, v2ex, dispatch]) 27 | return { 28 | topic 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/hooks/useUnRead.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-02-28 21:31:48. 3 | * Last modified at 2022-04-19 21:09:58 4 | */ 5 | 6 | import { useSelector } from 'react-redux' 7 | import { RootState } from '@src/store' 8 | export const useUnRead = () => { 9 | const { unread } = useSelector((state: RootState) => { 10 | return state.notification 11 | }) 12 | return { unread } 13 | } 14 | -------------------------------------------------------------------------------- /src/i18n/i18n.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-02-21 21:25:15. 3 | * Last modified at 2022-04-11 20:06:11 4 | */ 5 | 6 | import * as RNLocalize from 'react-native-localize' 7 | import i18n from 'i18n-js' 8 | const en = require('./locales/en') 9 | const zh = require('./locales/zh') 10 | // Should the app fallback to English if user locale doesn't exists 11 | i18n.fallbacks = true 12 | // Define the supported translation 13 | const translations = { 14 | en, 15 | zh 16 | } as const 17 | i18n.translations = translations 18 | const fallback = { languageTag: 'zh', isRTL: false } 19 | const { languageTag } = RNLocalize.findBestAvailableLanguage(Object.keys(i18n.translations)) || fallback 20 | i18n.locale = languageTag 21 | export default i18n 22 | export type LanguageTagType = keyof typeof translations | 'auto' 23 | export const translationTitle = { 24 | auto: 'Auto', 25 | en: 'English', 26 | zh: '简体中文' 27 | } 28 | -------------------------------------------------------------------------------- /src/i18n/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-02-21 21:25:15. 3 | * Last modified at 2022-04-11 20:06:11 4 | */ 5 | 6 | import i18n, { LanguageTagType, translationTitle } from './i18n' 7 | export * from './translate' 8 | export { i18n, translationTitle } 9 | export type { LanguageTagType } 10 | export function changeLocale(language: LanguageTagType) { 11 | i18n.locale = language === 'auto' ? i18n.currentLocale() : language 12 | console.log('changeLocale', language) 13 | } 14 | -------------------------------------------------------------------------------- /src/i18n/translate.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-02-21 21:25:15. 3 | * Last modified at 2022-02-28 21:31:48 4 | */ 5 | 6 | import i18n from 'i18n-js' 7 | export function translate(key: string, options?: i18n.TranslateOptions) { 8 | return key ? i18n.t(key, options) : key 9 | } 10 | -------------------------------------------------------------------------------- /src/navigation/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-04 19:36:42. 3 | * Last modified at 2022-03-04 19:36:42 4 | */ 5 | 6 | export { default as NavigationService } from './NavigationService' 7 | export * from './routes' 8 | export * from './tabs' 9 | export * from './Navigator' 10 | -------------------------------------------------------------------------------- /src/reducers/AppReducer.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-02-25 15:45:37. 3 | * Last modified at 2022-10-20 17:37:56 4 | */ 5 | 6 | import { 7 | APP_INIT, 8 | APP_INIT_ERROR, 9 | APP_SITE_INFO, 10 | APP_LOGOUT, 11 | APP_LATEST_VERSION, 12 | APP_SITE_STAT, 13 | Action, 14 | IState, 15 | APP_ALL_NODE_INFO 16 | } from '../types' 17 | import { aboutUs } from '@src/config/app.config' 18 | const INITIAL_STATE: IState.AppState = { 19 | aboutUs, 20 | version: { 21 | version: '1.0.0' 22 | } 23 | } 24 | export default (state: IState.AppState = INITIAL_STATE, action: Action): IState.AppState => { 25 | switch (action.type) { 26 | case APP_INIT: 27 | return { ...state, ...action.payload } 28 | case APP_LATEST_VERSION: 29 | return { ...state, latestVersion: action.payload } 30 | case APP_SITE_INFO: 31 | return { ...state, siteInfo: action.payload } 32 | case APP_SITE_STAT: 33 | return { ...state, siteStat: action.payload } 34 | case APP_ALL_NODE_INFO: 35 | return { ...state, allNode: action.payload } 36 | case APP_INIT_ERROR: 37 | return { ...state, errorMessage: action.payload } 38 | case APP_LOGOUT: 39 | return { ...INITIAL_STATE } 40 | default: 41 | return state 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/reducers/NotificationReducer.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-02-25 15:45:37. 3 | * Last modified at 2022-09-25 16:13:58 4 | */ 5 | 6 | import { 7 | APP_NOTIFICATION_PULL, 8 | APP_LOGOUT, 9 | APP_NOTIFICATION_LATEST, 10 | APP_NOTIFICATION_REMOVE, 11 | Action, 12 | IState 13 | } from '../types' 14 | const INITIAL_STATE: IState.NotificationState = { 15 | refreshing: false, 16 | unread: 0 17 | } 18 | export default (state: IState.NotificationState = INITIAL_STATE, action: Action): IState.NotificationState => { 19 | switch (action.type) { 20 | case APP_NOTIFICATION_PULL: 21 | return { ...state, list: undefined, refreshing: true } 22 | case APP_NOTIFICATION_LATEST: 23 | return { ...state, list: action.payload, refreshing: false } 24 | case APP_NOTIFICATION_REMOVE: 25 | return { ...state, list: action.payload, refreshing: false } 26 | case APP_LOGOUT: 27 | return { ...INITIAL_STATE } 28 | default: 29 | return state 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/reducers/SettingReducer.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-02-25 15:45:37. 3 | * Last modified at 2022-03-10 00:13:59 4 | */ 5 | 6 | import { LanguageTagType, APP_SETTING_LOCALES, APP_SETTING_THEME, Action, IState } from '../types' 7 | import { i18n } from '@src/i18n' 8 | const INITIAL_STATE: IState.SettingState = { 9 | languageTag: i18n.currentLocale() as LanguageTagType, 10 | theme: 'light' 11 | } 12 | export default (state: IState.SettingState = INITIAL_STATE, action: Action): IState.SettingState => { 13 | switch (action.type) { 14 | case APP_SETTING_LOCALES: 15 | return { ...state, languageTag: action.payload } 16 | case APP_SETTING_THEME: 17 | return { ...state, theme: action.payload } 18 | default: 19 | return state 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/reducers/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-02-23 21:38:16. 3 | * Last modified at 2022-04-19 20:02:26 4 | */ 5 | 6 | import { combineReducers } from 'redux' 7 | import UIReducer from './UIReducer' 8 | import AppReducer from './AppReducer' 9 | import MemberReducer from './MemberReducer' 10 | import TabReducer from './TabReducer' 11 | import NotificationReducer from './NotificationReducer' 12 | import SettingReducer from './SettingReducer' 13 | import CacheReducer from './CacheReducer' 14 | const reducers = combineReducers({ 15 | ui: UIReducer, 16 | member: MemberReducer, 17 | app: AppReducer, 18 | tab: TabReducer, 19 | notification: NotificationReducer, 20 | setting: SettingReducer, 21 | cache: CacheReducer 22 | }) 23 | export default reducers 24 | -------------------------------------------------------------------------------- /src/screens/catalog/Draw.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-03 11:30:16. 3 | * Last modified at 2022-03-03 11:30:16 4 | */ 5 | 6 | import React from 'react' 7 | import { Text, SafeAreaView, View } from 'react-native' 8 | const Screen = () => { 9 | return ( 10 | 11 | 12 | Draw 13 | 14 | 15 | ) 16 | } 17 | export default Screen 18 | -------------------------------------------------------------------------------- /src/screens/common/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-16 12:22:20. 3 | * Last modified at 2022-03-16 12:22:20 4 | */ 5 | 6 | export { default as WebLinkScreen } from './WebLink' 7 | -------------------------------------------------------------------------------- /src/screens/components/Layout.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-01 14:00:14. 3 | * Last modified at 2022-10-20 18:07:33 4 | */ 5 | 6 | import React from 'react' 7 | import { View, ViewStyle, TextStyle } from 'react-native' 8 | import { Text, Button, Spinner, Placeholder } from '@src/components' 9 | import { Theme, SylCommon, useTheme } from '@src/theme' 10 | import { translate } from '@src/i18n' 11 | import { NavigationService, ROUTES } from '@src/navigation' 12 | import { AppObject } from '@src/types' 13 | /** 14 | * // TODO: Layout 15 | * Layout props 16 | */ 17 | export interface LayoutProps { 18 | /** 19 | * layout width 20 | */ 21 | width?: number | string 22 | /** 23 | * layout height 24 | */ 25 | height?: number | string 26 | } 27 | const Layout: React.FC = ({ width, height }: LayoutProps) => { 28 | const renderContent = () => { 29 | return ( 30 | 31 | Hello World, Layout. 32 | 33 | ) 34 | } 35 | return renderContent() 36 | } 37 | const styles = { 38 | container: (theme: Theme): ViewStyle => ({ 39 | flex: 1 40 | }) 41 | } 42 | export default Layout 43 | -------------------------------------------------------------------------------- /src/screens/components/button/header/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-05-05 17:31:24. 3 | * Last modified at 2022-05-28 19:56:02 4 | */ 5 | 6 | export { default as LikeNodeHeaderButton } from './LikeNodeHeaderButton' 7 | export { default as LikeTopicHeaderButton } from './LikeTopicHeaderButton' 8 | export { default as FollowPeopleHeaderButton } from './FollowPeopleHeaderButton' 9 | export { default as LogoutHeaderButton } from './LogoutHeaderButton' 10 | -------------------------------------------------------------------------------- /src/screens/components/button/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-05-05 17:31:24. 3 | * Last modified at 2022-05-05 17:31:24 4 | */ 5 | 6 | export * from './header' 7 | -------------------------------------------------------------------------------- /src/screens/components/common/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-15 13:48:59. 3 | * Last modified at 2022-05-22 13:08:38 4 | */ 5 | 6 | export { default as TabCardContainer } from './TabCardContainer' 7 | export { default as RenderHTML } from './RenderHTML' 8 | export * from './General' 9 | -------------------------------------------------------------------------------- /src/screens/components/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-04 19:20:02. 3 | * Last modified at 2022-11-05 20:08:36 4 | */ 5 | 6 | export { default as Layout } from './Layout' 7 | export * from './topic' 8 | export * from './profile' 9 | export * from './skeleton' 10 | export * from './common' 11 | export * from './node' 12 | export * from './notification' 13 | export * from './list' 14 | export * from './section' 15 | export { default as SetStatusBar } from './statusbar' 16 | -------------------------------------------------------------------------------- /src/screens/components/list/GridList.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-01 14:00:14. 3 | * Last modified at 2022-04-08 20:22:59 4 | */ 5 | 6 | import { Text } from '@src/components' 7 | import { Theme } from '@src/theme' 8 | import React from 'react' 9 | import { View, ViewStyle } from 'react-native' 10 | /** 11 | * GridList props 12 | */ 13 | export interface GridListProps { 14 | /** 15 | * GridList width 16 | */ 17 | width?: number | string 18 | /** 19 | * GridList height 20 | */ 21 | height?: number | string 22 | } 23 | const GridList: React.FC = ({ width, height }: GridListProps) => { 24 | const renderContent = () => { 25 | return ( 26 | 27 | Hello World, GridList. 28 | 29 | ) 30 | } 31 | return renderContent() 32 | } 33 | const styles = { 34 | container: (theme: Theme): ViewStyle => ({ 35 | flex: 1 36 | }) 37 | } 38 | export default GridList 39 | -------------------------------------------------------------------------------- /src/screens/components/list/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-01 14:00:14. 3 | * Last modified at 2022-04-08 22:18:03 4 | */ 5 | 6 | export { default as GridList } from './GridList' 7 | export * from './TableList' 8 | -------------------------------------------------------------------------------- /src/screens/components/node/NodeList.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-01 14:00:14. 3 | * Last modified at 2022-10-20 18:07:33 4 | */ 5 | 6 | import React from 'react' 7 | import { View, ViewStyle, TextStyle } from 'react-native' 8 | import { Text, Button, Spinner, Placeholder } from '@src/components' 9 | import { Theme, SylCommon, useTheme } from '@src/theme' 10 | import { translate } from '@src/i18n' 11 | import { NavigationService, ROUTES } from '@src/navigation' 12 | import { AppObject } from '@src/types' 13 | /** 14 | * // TODO: NodeList 15 | * NodeList props 16 | */ 17 | export interface NodeListProps { 18 | /** 19 | * NodeList width 20 | */ 21 | width?: number | string 22 | /** 23 | * NodeList height 24 | */ 25 | height?: number | string 26 | } 27 | const NodeList: React.FC = ({ width, height }: NodeListProps) => { 28 | const renderContent = () => { 29 | return ( 30 | 31 | Hello World, NodeList. 32 | 33 | ) 34 | } 35 | return renderContent() 36 | } 37 | const styles = { 38 | container: (theme: Theme): ViewStyle => ({ 39 | flex: 1 40 | }) 41 | } 42 | export default NodeList 43 | -------------------------------------------------------------------------------- /src/screens/components/node/NodeSection.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-01 14:00:14. 3 | * Last modified at 2022-10-20 18:07:33 4 | */ 5 | 6 | import React from 'react' 7 | import { View, ViewStyle, TextStyle } from 'react-native' 8 | import { Text, Button, Spinner, Placeholder } from '@src/components' 9 | import { Theme, SylCommon, useTheme } from '@src/theme' 10 | import { translate } from '@src/i18n' 11 | import { NavigationService, ROUTES } from '@src/navigation' 12 | import { AppObject } from '@src/types' 13 | /** 14 | * // TODO: NodeSection 15 | * NodeSection props 16 | */ 17 | export interface NodeSectionProps { 18 | /** 19 | * NodeSection width 20 | */ 21 | width?: number | string 22 | /** 23 | * NodeSection height 24 | */ 25 | height?: number | string 26 | } 27 | const NodeSection: React.FC = ({ width, height }: NodeSectionProps) => { 28 | const renderContent = () => { 29 | return ( 30 | 31 | Hello World, NodeSection. 32 | 33 | ) 34 | } 35 | return renderContent() 36 | } 37 | const styles = { 38 | container: (theme: Theme): ViewStyle => ({ 39 | flex: 1 40 | }) 41 | } 42 | export default NodeSection 43 | -------------------------------------------------------------------------------- /src/screens/components/node/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-01 14:00:14. 3 | * Last modified at 2022-04-01 14:00:14 4 | */ 5 | 6 | export { default as NodeInfoCard } from './NodeInfoCard' 7 | export { default as NodeList } from './NodeList' 8 | export { default as NodeSection } from './NodeSection' 9 | export { default as NodeTopicTabList } from './NodeTopicTabList' 10 | -------------------------------------------------------------------------------- /src/screens/components/notification/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-01 14:00:14. 3 | * Last modified at 2022-04-01 14:00:14 4 | */ 5 | 6 | export { default as NotificationList } from './NotificationList' 7 | -------------------------------------------------------------------------------- /src/screens/components/profile/ProfileCard.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-01 14:00:14. 3 | * Last modified at 2022-04-07 16:31:33 4 | */ 5 | 6 | import React from 'react' 7 | import ProfileGrid, { ProfileGridProps } from './ProfileGrid' 8 | import ProfileInfo, { ProfileInfoProps } from './ProfileInfo' 9 | import { BorderLine } from '../common' 10 | import { SylCommon, useTheme } from '@src/theme' 11 | import { View, ViewStyle } from 'react-native' 12 | /** 13 | * ProfileCard props 14 | */ 15 | export interface ProfileCardProps { 16 | containerStyle?: ViewStyle 17 | info: ProfileInfoProps 18 | stat: ProfileGridProps 19 | } 20 | const ProfileCard: React.FC = ({ info, stat, containerStyle }: ProfileCardProps) => { 21 | const { theme } = useTheme() 22 | const renderContent = () => { 23 | return ( 24 | 32 | 33 | 34 | 38 | 39 | ) 40 | } 41 | return renderContent() 42 | } 43 | export default ProfileCard 44 | -------------------------------------------------------------------------------- /src/screens/components/profile/ProfileDetail.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-01 14:00:14. 3 | * Last modified at 2022-10-20 18:07:33 4 | */ 5 | 6 | import { Theme, SylCommon, useTheme } from '@src/theme' 7 | import { AppObject } from '@src/types' 8 | import React from 'react' 9 | import { StyleProp, View, ViewStyle } from 'react-native' 10 | import ProfileInfo from './ProfileInfo' 11 | import ProfileTopics from './ProfileTopics' 12 | /** 13 | * ProfileDetail props 14 | */ 15 | export interface ProfileDetailProps { 16 | containerStyle?: StyleProp 17 | profile: AppObject.Member 18 | } 19 | const ProfileDetail: React.FC = ({ containerStyle, profile }: ProfileDetailProps) => { 20 | const { theme } = useTheme() 21 | const renderContent = () => { 22 | return ( 23 | 24 | 29 | 30 | 31 | ) 32 | } 33 | return renderContent() 34 | } 35 | const styles = { 36 | container: (theme: Theme): ViewStyle => ({ 37 | flex: 1 38 | }) 39 | } 40 | export default ProfileDetail 41 | -------------------------------------------------------------------------------- /src/screens/components/profile/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-01 14:00:14. 3 | * Last modified at 2022-05-27 22:03:36 4 | */ 5 | 6 | export { default as ProfileCard } from './ProfileCard' 7 | export { default as ProfileDetail } from './ProfileDetail' 8 | export { default as ProfileGrid } from './ProfileGrid' 9 | export { default as ProfileInfo } from './ProfileInfo' 10 | export { default as ProfileTopics } from './ProfileTopics' 11 | export { default as SimpleProfileInfoCard } from './SimpleProfileInfoCard' 12 | export { default as ProfileCardList } from './ProfileCardList' 13 | -------------------------------------------------------------------------------- /src/screens/components/profile/profile.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-05-27 21:34:46. 3 | * Last modified at 2022-05-27 21:34:46 4 | */ 5 | 6 | import { Theme } from '@src/theme' 7 | import { ViewStyle } from 'react-native' 8 | export const ProfileInfoStyle = { 9 | container: (theme: Theme): ViewStyle => ({ 10 | display: 'flex', 11 | alignItems: 'flex-start', 12 | flexDirection: 'column' 13 | }), 14 | infoItem: (theme: Theme): ViewStyle => ({ 15 | paddingBottom: theme.spacing.medium, 16 | display: 'flex', 17 | flexDirection: 'row', 18 | alignItems: 'flex-start', 19 | justifyContent: 'flex-start', 20 | width: '100%' 21 | }), 22 | baseAvatar: (theme: Theme): ViewStyle => ({ 23 | width: 60, 24 | height: 60, 25 | marginRight: theme.spacing.medium 26 | }), 27 | baseRightBox: (theme: Theme): ViewStyle => ({ 28 | display: 'flex', 29 | flexDirection: 'row', 30 | flex: 1 31 | }), 32 | baseRightInfo: (theme: Theme): ViewStyle => ({ 33 | display: 'flex', 34 | flexDirection: 'column', 35 | flex: 1, 36 | alignItems: 'flex-start' 37 | }), 38 | baseRightArrow: (theme: Theme): ViewStyle => ({ 39 | width: 14, 40 | display: 'flex', 41 | justifyContent: 'center' 42 | }), 43 | baseRightItem: (theme: Theme): ViewStyle => ({ 44 | paddingBottom: theme.spacing.small 45 | }) 46 | } 47 | -------------------------------------------------------------------------------- /src/screens/components/section/SettingSection.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-01 14:00:14. 3 | * Last modified at 2022-05-22 13:09:37 4 | */ 5 | 6 | import { Text } from '@src/components' 7 | import { Theme } from '@src/theme' 8 | import React from 'react' 9 | import { View, ViewStyle } from 'react-native' 10 | /** 11 | * SettingSection props 12 | */ 13 | export interface SettingSectionProps { 14 | /** 15 | * SettingSection width 16 | */ 17 | width?: number | string 18 | /** 19 | * SettingSection height 20 | */ 21 | height?: number | string 22 | } 23 | const SettingSection: React.FC = ({ width, height }: SettingSectionProps) => { 24 | const renderContent = () => { 25 | return ( 26 | 27 | Hello World, SettingSection. 28 | 29 | ) 30 | } 31 | return renderContent() 32 | } 33 | const styles = { 34 | container: (theme: Theme): ViewStyle => ({ 35 | flex: 1 36 | }) 37 | } 38 | export default SettingSection 39 | -------------------------------------------------------------------------------- /src/screens/components/section/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-01 14:00:14. 3 | * Last modified at 2022-04-01 14:00:14 4 | */ 5 | 6 | export { default as SettingSection } from './SettingSection' 7 | -------------------------------------------------------------------------------- /src/screens/components/skeleton/TopicDetailPlaceholer.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-01 10:44:43. 3 | * Last modified at 2022-04-01 10:44:43 4 | */ 5 | 6 | import React from 'react' 7 | import { View } from 'react-native' 8 | import SkeletonPlaceholder from 'react-native-skeleton-placeholder' 9 | const TopicDetailPlaceholder = ({ color = '#CCCCCC' }: { color?: string }) => { 10 | return ( 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | ) 21 | } 22 | export { TopicDetailPlaceholder } 23 | -------------------------------------------------------------------------------- /src/screens/components/skeleton/TopicsPlaceholder.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-01 10:44:43. 3 | * Last modified at 2022-04-01 10:44:43 4 | */ 5 | 6 | import React from 'react' 7 | import { View } from 'react-native' 8 | import SkeletonPlaceholder from 'react-native-skeleton-placeholder' 9 | const TopicsPlaceholder = ({ color = '#CCCCCC' }: { color?: string }) => { 10 | return ( 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | ) 21 | } 22 | export { TopicsPlaceholder } 23 | -------------------------------------------------------------------------------- /src/screens/components/skeleton/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-01 10:44:43. 3 | * Last modified at 2022-04-01 10:44:43 4 | */ 5 | 6 | export * from './TopicDetailPlaceholer' 7 | export * from './TopicsPlaceholder' 8 | -------------------------------------------------------------------------------- /src/screens/components/statusbar/index.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-14 17:36:16. 3 | * Last modified at 2022-04-14 17:50:01 4 | */ 5 | 6 | import { useFocusEffect } from '@react-navigation/native' 7 | import { useTheme } from '@src/theme' 8 | import { useCallback } from 'react' 9 | import { Platform, StatusBar } from 'react-native' 10 | // set statusbar if the screen is currently focused. 11 | // https://reactnavigation.org/docs/use-focus-effect/ 12 | export const SetStatusBar = ({ backgroundColor }: { backgroundColor?: string }) => { 13 | const { theme } = useTheme() 14 | useFocusEffect( 15 | useCallback(() => { 16 | if (Platform.OS === 'android') { 17 | StatusBar.setBackgroundColor( 18 | backgroundColor ?? (theme.name === 'dark' ? theme.colors.primaryDark : theme.colors.primary) 19 | ) 20 | } 21 | StatusBar.setBarStyle(theme.statusBarStyle) 22 | return () => null 23 | }, [backgroundColor, theme]) 24 | ) 25 | return null 26 | } 27 | export default SetStatusBar 28 | -------------------------------------------------------------------------------- /src/screens/components/topic/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-04 19:20:02. 3 | * Last modified at 2022-04-28 20:07:59 4 | */ 5 | 6 | export { default as TopicReplayItem } from './TopicReplayItem' 7 | export { default as ReplayList } from './TopicReplayList' 8 | export { default as TopicCardItem } from './TopicCardItem' 9 | export { default as TopicCardList } from './TopicCardList' 10 | export { default as TopicReplay } from './TopicReplay' 11 | export { default as TopicInfo } from './TopicInfo' 12 | export { default as FetchTopicCardList } from './FetchTopicCardList' 13 | -------------------------------------------------------------------------------- /src/screens/home/HotTopics.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-17 23:12:51. 3 | * Last modified at 2022-11-08 23:52:09 4 | */ 5 | 6 | import { CheckUpdate } from '@src/components' 7 | import { InterestNodesScreenProps as ScreenProps, NODE_TABS } from '@src/navigation' 8 | import { SylCommon, useTheme } from '@src/theme' 9 | import React from 'react' 10 | import { View } from 'react-native' 11 | import { connect } from 'react-redux' 12 | import { FetchTopicCardList } from '../components' 13 | const HotTopics = ({ route, navigation }: ScreenProps) => { 14 | const { theme } = useTheme() 15 | return ( 16 | 17 | 18 | 19 | 20 | ) 21 | } 22 | export default connect()(HotTopics) 23 | -------------------------------------------------------------------------------- /src/screens/home/LatestTopics.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-17 23:12:51. 3 | * Last modified at 2022-04-18 18:34:00 4 | */ 5 | 6 | import { InterestNodesScreenProps as ScreenProps, NODE_TABS } from '@src/navigation' 7 | import { SylCommon, useTheme } from '@src/theme' 8 | import React from 'react' 9 | import { View } from 'react-native' 10 | import { connect } from 'react-redux' 11 | import { FetchTopicCardList } from '../components' 12 | const LatestTopics = ({ route, navigation }: ScreenProps) => { 13 | const { theme } = useTheme() 14 | return ( 15 | 16 | 17 | 18 | ) 19 | } 20 | export default connect()(LatestTopics) 21 | -------------------------------------------------------------------------------- /src/screens/home/index.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-04 19:20:02. 3 | * Last modified at 2022-04-17 23:12:51 4 | */ 5 | 6 | export { default as HomeTopTabListScreen } from './HomeTabs' 7 | export { default as HotScreen } from './HotTopics' 8 | export { default as LatestScreen } from './LatestTopics' 9 | -------------------------------------------------------------------------------- /src/screens/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-03 11:30:16. 3 | * Last modified at 2022-04-01 17:54:02 4 | */ 5 | 6 | export { default as SignInScreen } from './login/SignIn' 7 | export { default as DrawScreen } from './catalog/Draw' 8 | export * from './node' 9 | export * from './notification' 10 | export * from './search' 11 | export * from './profile' 12 | export * from './my' 13 | export * from './topic' 14 | export * from './setting' 15 | export * from './home' 16 | export * from './common' 17 | -------------------------------------------------------------------------------- /src/screens/my/Favorite.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-01 17:54:02. 3 | * Last modified at 2022-10-20 18:07:33 4 | */ 5 | 6 | import { Placeholder } from '@src/components' 7 | import { FavoriteTopicsScreenProps as ScreenProps } from '@src/navigation' 8 | import { RootState } from '@src/store' 9 | import { SylCommon, useTheme } from '@src/theme' 10 | import { AppObject } from '@src/types' 11 | import React from 'react' 12 | import { View } from 'react-native' 13 | import { connect } from 'react-redux' 14 | import { NeedLogin, TopicCardList } from '../components' 15 | const FavoriteTopics = ({ 16 | likeTopics 17 | }: ScreenProps & { 18 | likeTopics: AppObject.Topic[] 19 | }) => { 20 | const { theme } = useTheme() 21 | const renderContent = () => { 22 | if (!likeTopics) { 23 | return 24 | } 25 | return ( 26 | 27 | 28 | 29 | ) 30 | } 31 | return {renderContent()} 32 | } 33 | const mapStateToProps = ({ member }: RootState) => { 34 | const { likeTopics } = member 35 | return { 36 | likeTopics 37 | } 38 | } 39 | export default connect(mapStateToProps)(FavoriteTopics) 40 | -------------------------------------------------------------------------------- /src/screens/my/Following.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-01 17:54:02. 3 | * Last modified at 2022-10-20 18:07:33 4 | */ 5 | 6 | import { Placeholder } from '@src/components' 7 | import { translate } from '@src/i18n' 8 | import { FollowingScreenProps as ScreenProps } from '@src/navigation' 9 | import { RootState } from '@src/store' 10 | import { SylCommon, useTheme } from '@src/theme' 11 | import { AppObject } from '@src/types' 12 | import React from 'react' 13 | import { View } from 'react-native' 14 | import { connect } from 'react-redux' 15 | import { NeedLogin, ProfileCardList } from '../components' 16 | const Following = ({ 17 | followPeoples 18 | }: ScreenProps & { 19 | followPeoples: AppObject.Member[] 20 | }) => { 21 | const { theme } = useTheme() 22 | const renderContent = () => { 23 | if (!followPeoples || followPeoples.length === 0) { 24 | return 25 | } 26 | return ( 27 | 28 | 29 | 30 | ) 31 | } 32 | return {renderContent()} 33 | } 34 | const mapStateToProps = ({ member: { followPeoples } }: RootState) => { 35 | return { 36 | followPeoples 37 | } 38 | } 39 | export default connect(mapStateToProps)(Following) 40 | -------------------------------------------------------------------------------- /src/screens/my/History.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-01 17:54:02. 3 | * Last modified at 2022-10-20 18:07:33 4 | */ 5 | 6 | import { Placeholder } from '@src/components' 7 | import { translate } from '@src/i18n' 8 | import { HistoryScreenProps as ScreenProps } from '@src/navigation/routes' 9 | import { RootState } from '@src/store' 10 | import { SylCommon, useTheme } from '@src/theme' 11 | import { AppObject } from '@src/types' 12 | import React from 'react' 13 | import { View } from 'react-native' 14 | import { connect } from 'react-redux' 15 | import { TopicCardList } from '../components' 16 | const History = ({ 17 | route, 18 | navigation, 19 | readedTopics 20 | }: ScreenProps & { 21 | readedTopics?: AppObject.Topic[] 22 | }) => { 23 | const { theme } = useTheme() 24 | const renderContent = () => { 25 | if (!readedTopics) { 26 | return 27 | } 28 | return 29 | } 30 | return {renderContent()} 31 | } 32 | const mapStateToProps = ({ member }: RootState) => { 33 | const { readedTopics } = member 34 | return { 35 | readedTopics 36 | } 37 | } 38 | export default connect(mapStateToProps)(History) 39 | -------------------------------------------------------------------------------- /src/screens/my/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-04 19:20:02. 3 | * Last modified at 2022-04-07 16:05:22 4 | */ 5 | 6 | export { default as MyScreen } from './Home' 7 | export { default as FollowingScreen } from './Following' 8 | export { default as FavoriteTopicsScreen } from './Favorite' 9 | export { default as HistoryScreen } from './History' 10 | export { default as MyTopics } from './Topics' 11 | -------------------------------------------------------------------------------- /src/screens/node/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-01 17:54:02. 3 | * Last modified at 2022-04-01 17:54:02 4 | */ 5 | 6 | export { default as NodesScreen } from './Nodes' 7 | export { default as NodeDetailScreen } from './NodeDetail' 8 | export { default as InterestNodesScreen } from './InterestNodes' 9 | -------------------------------------------------------------------------------- /src/screens/notification/Notifications.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-01 17:54:02. 3 | * Last modified at 2022-10-20 18:07:33 4 | */ 5 | 6 | import { NotificationsScreenProps as ScreenProps } from '@src/navigation/routes' 7 | import { AppObject } from '@src/types' 8 | import React from 'react' 9 | import { connect } from 'react-redux' 10 | import { NotificationList } from '../components' 11 | const Notification = ({ 12 | route, 13 | navigation, 14 | profile 15 | }: ScreenProps & { 16 | profile?: AppObject.Member 17 | }) => { 18 | return 19 | } 20 | export default connect()(Notification) 21 | -------------------------------------------------------------------------------- /src/screens/notification/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-01 17:54:02. 3 | * Last modified at 2022-04-01 17:54:02 4 | */ 5 | 6 | export { default as NotificationsScreen } from './Notifications' 7 | -------------------------------------------------------------------------------- /src/screens/profile/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-01 17:54:02. 3 | * Last modified at 2022-04-01 17:54:02 4 | */ 5 | 6 | export { default as ProfileScreen } from './Profile' 7 | -------------------------------------------------------------------------------- /src/screens/search/Search.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-01 17:54:02. 3 | * Last modified at 2022-10-20 18:07:33 4 | */ 5 | 6 | import React, { useState } from 'react' 7 | import { connect } from 'react-redux' 8 | import { StyleSheet, View, ViewStyle, TextStyle } from 'react-native' 9 | import { translate } from '@src/i18n' 10 | import { useTheme, SylCommon } from '@src/theme' 11 | import { IState, Theme, AppObject } from '@src/types' 12 | import * as CompS from '../components' 13 | import { Text, Spinner } from '@src/components' 14 | import { SearchScreenProps as ScreenProps } from '@src/navigation/routes' 15 | import { RootState } from '@src/store' 16 | const Search = ({ route, navigation, loading }: ScreenProps) => { 17 | const { theme } = useTheme() 18 | return ( 19 | 20 | Hello, Search. 21 | 22 | ) 23 | } 24 | const styles = { 25 | container: (theme: Theme): ViewStyle => ({ 26 | flex: 1 27 | }) 28 | } 29 | /** 30 | * default props 31 | */ 32 | Search.defaultProps = { 33 | loading: false 34 | } 35 | const mapStateToProps = (state: RootState) => { 36 | return { loading: state.member } 37 | } 38 | export default connect(mapStateToProps)(Search) 39 | -------------------------------------------------------------------------------- /src/screens/search/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-01 17:54:02. 3 | * Last modified at 2022-04-01 17:54:02 4 | */ 5 | 6 | export { default as SearchScreen } from './Search' 7 | -------------------------------------------------------------------------------- /src/screens/setting/ChangeLog.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-30 22:08:54. 3 | * Last modified at 2022-10-20 18:07:33 4 | */ 5 | 6 | import React, { useState } from 'react' 7 | import { connect } from 'react-redux' 8 | import { View, ViewStyle, TouchableOpacity } from 'react-native' 9 | import * as Actions from '@src/actions' 10 | import { translate } from '@src/i18n' 11 | import { useTheme, SylCommon } from '@src/theme' 12 | import { IState, Theme, AppObject } from '@src/types' 13 | import * as CompS from '../components' 14 | import { Text, Spinner, Placeholder } from '@src/components' 15 | import { ChangeLogScreenProps as ScreenProps, ROUTES } from '@src/navigation' 16 | const ChangeLog = ({ route, navigation, loading }: ScreenProps) => { 17 | const { theme } = useTheme() 18 | return ( 19 | 24 | ) 25 | } 26 | const styles = { 27 | container: (theme: Theme): ViewStyle => ({ 28 | flex: 1 29 | }) 30 | } 31 | const mapStateToProps = ({ ui: { login } }: { ui: IState.UIState }) => { 32 | const { error, success, loading } = login 33 | return { error, success, loading } 34 | } 35 | export default connect(mapStateToProps)(ChangeLog) 36 | -------------------------------------------------------------------------------- /src/screens/setting/Feedback.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-04 19:20:02. 3 | * Last modified at 2022-10-20 18:07:33 4 | */ 5 | 6 | import React, { useState } from 'react' 7 | import { connect } from 'react-redux' 8 | import { View, ViewStyle, TouchableOpacity } from 'react-native' 9 | import * as Actions from '@src/actions' 10 | import { translate } from '@src/i18n' 11 | import { useTheme, SylCommon } from '@src/theme' 12 | import { IState, Theme, AppObject } from '@src/types' 13 | import * as CompS from '../components' 14 | import { Text, Spinner } from '@src/components' 15 | import { FeedbackScreenProps as ScreenProps } from '@src/navigation/routes' 16 | const Feedback = ({ route, navigation, loading }: ScreenProps) => { 17 | const { theme } = useTheme() 18 | return ( 19 | 20 | Hello, Feedback. 21 | 22 | ) 23 | } 24 | const styles = { 25 | container: (theme: Theme): ViewStyle => ({ 26 | flex: 1 27 | }) 28 | } 29 | const mapStateToProps = ({ ui: { login } }: { ui: IState.UIState }) => { 30 | const { error, success, loading } = login 31 | return { error, success, loading } 32 | } 33 | export default connect(mapStateToProps)(Feedback) 34 | -------------------------------------------------------------------------------- /src/screens/setting/HowToUse.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-30 22:08:54. 3 | * Last modified at 2022-10-20 18:07:33 4 | */ 5 | 6 | import React, { useState } from 'react' 7 | import { connect } from 'react-redux' 8 | import { View, ViewStyle, TouchableOpacity } from 'react-native' 9 | import * as Actions from '@src/actions' 10 | import { translate } from '@src/i18n' 11 | import { useTheme, SylCommon } from '@src/theme' 12 | import { IState, Theme, AppObject } from '@src/types' 13 | import * as CompS from '../components' 14 | import { Text, Spinner } from '@src/components' 15 | import { HowToUseScreenProps as ScreenProps } from '@src/navigation/routes' 16 | const HowToUse = ({ route, navigation, loading }: ScreenProps) => { 17 | const { theme } = useTheme() 18 | return ( 19 | 20 | Hello, HowToUse. 21 | 22 | ) 23 | } 24 | const styles = { 25 | container: (theme: Theme): ViewStyle => ({ 26 | flex: 1 27 | }) 28 | } 29 | const mapStateToProps = ({ ui: { login } }: { ui: IState.UIState }) => { 30 | const { error, success, loading } = login 31 | return { error, success, loading } 32 | } 33 | export default connect(mapStateToProps)(HowToUse) 34 | -------------------------------------------------------------------------------- /src/screens/setting/License.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-30 22:08:54. 3 | * Last modified at 2022-04-19 17:04:45 4 | */ 5 | 6 | import { OPENSOURCE_LIST } from '@src/config/constants' 7 | import { OpenSourceLicenseScreenProps as ScreenProps, ROUTES } from '@src/navigation/routes' 8 | import { SylCommon, useTheme } from '@src/theme' 9 | import { linking } from '@src/utils' 10 | import React from 'react' 11 | import { View } from 'react-native' 12 | import { connect } from 'react-redux' 13 | import { TableList, TableRow } from '../components' 14 | const OpenSourceLicense = ({ navigation }: ScreenProps) => { 15 | const { theme } = useTheme() 16 | return ( 17 | 18 | 19 | {OPENSOURCE_LIST.map((item, index) => ( 20 | { 25 | navigation.navigate(ROUTES.WebViewer, { url: item.repoUrl }) 26 | }} 27 | /> 28 | ))} 29 | 30 | 31 | ) 32 | } 33 | export default connect()(OpenSourceLicense) 34 | -------------------------------------------------------------------------------- /src/screens/setting/Privacy.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-30 22:08:54. 3 | * Last modified at 2022-10-20 18:07:33 4 | */ 5 | 6 | import React, { useState } from 'react' 7 | import { connect } from 'react-redux' 8 | import { View, ViewStyle, TouchableOpacity } from 'react-native' 9 | import * as Actions from '@src/actions' 10 | import { translate } from '@src/i18n' 11 | import { useTheme, SylCommon } from '@src/theme' 12 | import { IState, Theme, AppObject } from '@src/types' 13 | import * as CompS from '../components' 14 | import { Text, Spinner } from '@src/components' 15 | import { PrivacyPolicyScreenProps as ScreenProps } from '@src/navigation/routes' 16 | const Privacy = ({ route, navigation, loading }: ScreenProps) => { 17 | const { theme } = useTheme() 18 | return ( 19 | 20 | Hello, Privacy. 21 | 22 | ) 23 | } 24 | const styles = { 25 | container: (theme: Theme): ViewStyle => ({ 26 | flex: 1 27 | }) 28 | } 29 | const mapStateToProps = ({ ui: { login } }: { ui: IState.UIState }) => { 30 | const { error, success, loading } = login 31 | return { error, success, loading } 32 | } 33 | export default connect(mapStateToProps)(Privacy) 34 | -------------------------------------------------------------------------------- /src/screens/setting/Setting.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-04 19:20:02. 3 | * Last modified at 2022-10-20 18:07:33 4 | */ 5 | 6 | import React, { useState } from 'react' 7 | import { connect } from 'react-redux' 8 | import { StyleSheet, View, ViewStyle, TextStyle } from 'react-native' 9 | import { translate } from '@src/i18n' 10 | import { useTheme, SylCommon } from '@src/theme' 11 | import { IState, Theme, AppObject } from '@src/types' 12 | import * as CompS from '../components' 13 | import { Text, Spinner } from '@src/components' 14 | import { SettingScreenProps as ScreenProps } from '@src/navigation/routes' 15 | const Setting = ({ route, navigation, loading }: ScreenProps) => { 16 | const { theme } = useTheme() 17 | return ( 18 | 19 | Hello, Setting. 20 | 21 | ) 22 | } 23 | const styles = { 24 | container: (theme: Theme): ViewStyle => ({ 25 | flex: 1 26 | }) 27 | } 28 | /** 29 | * default props 30 | */ 31 | Setting.defaultProps = { 32 | loading: false 33 | } 34 | const mapStateToProps = ({ ui: { login } }: { ui: IState.UIState }) => { 35 | const { error, success, loading } = login 36 | return { error, success, loading } 37 | } 38 | export default connect(mapStateToProps)(Setting) 39 | -------------------------------------------------------------------------------- /src/screens/setting/SiteStat.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-30 22:08:54. 3 | * Last modified at 2022-10-20 18:07:33 4 | */ 5 | 6 | import { translate } from '@src/i18n' 7 | import { SiteStatScreenProps as ScreenProps } from '@src/navigation/routes' 8 | import { SylCommon, useTheme } from '@src/theme' 9 | import { IState, AppObject } from '@src/types' 10 | import React from 'react' 11 | import { View } from 'react-native' 12 | import { connect } from 'react-redux' 13 | import { TableList, TableRow } from '../components' 14 | const SiteStat = ({ 15 | siteStat 16 | }: ScreenProps & { 17 | siteStat?: AppObject.SiteStat 18 | }) => { 19 | const { theme } = useTheme() 20 | return ( 21 | 22 | 23 | 28 | 33 | 34 | 35 | ) 36 | } 37 | const mapStateToProps = ({ app: { siteStat } }: { app: IState.AppState }) => { 38 | return { siteStat } 39 | } 40 | export default connect(mapStateToProps)(SiteStat) 41 | -------------------------------------------------------------------------------- /src/screens/setting/TermsOfService.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-04-14 14:24:27. 3 | * Last modified at 2022-10-20 18:07:33 4 | */ 5 | 6 | import React, { useState } from 'react' 7 | import { connect } from 'react-redux' 8 | import { View, ViewStyle, TouchableOpacity } from 'react-native' 9 | import * as Actions from '@src/actions' 10 | import { translate } from '@src/i18n' 11 | import { useTheme, SylCommon } from '@src/theme' 12 | import { IState, Theme, AppObject } from '@src/types' 13 | import * as CompS from '../components' 14 | import { Text, Spinner } from '@src/components' 15 | import { TermsOfServiceScreenProps as ScreenProps } from '@src/navigation/routes' 16 | const TermsOfServiceScreen = ({ route, navigation, loading }: ScreenProps) => { 17 | const { theme } = useTheme() 18 | return ( 19 | 20 | Hello, TermsOfService. 21 | 22 | ) 23 | } 24 | const styles = { 25 | container: (theme: Theme): ViewStyle => ({ 26 | flex: 1 27 | }) 28 | } 29 | const mapStateToProps = ({ ui: { login } }: { ui: IState.UIState }) => { 30 | const { error, success, loading } = login 31 | return { error, success, loading } 32 | } 33 | export default connect(mapStateToProps)(TermsOfServiceScreen) 34 | -------------------------------------------------------------------------------- /src/screens/setting/URLSchemes.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-30 22:08:54. 3 | * Last modified at 2022-04-19 17:04:45 4 | */ 5 | 6 | import { URLSchemeList } from '@src/config/constants' 7 | import { translate } from '@src/i18n' 8 | import { URLSchemescreenProps as ScreenProps } from '@src/navigation' 9 | import { SylCommon, useTheme } from '@src/theme' 10 | import React from 'react' 11 | import { View } from 'react-native' 12 | import { connect } from 'react-redux' 13 | import { TableList, TableRow } from '../components' 14 | import { useToast } from '@src/components/toast' 15 | const URLSchemes = ({}: ScreenProps) => { 16 | const { theme } = useTheme() 17 | const { showMessage } = useToast() 18 | return ( 19 | 20 | 21 | { 26 | // TODO: open app 27 | showMessage({ 28 | type: 'error', 29 | text2: translate('label.underConstruction') 30 | }) 31 | }} 32 | /> 33 | 34 | 35 | ) 36 | } 37 | export default connect()(URLSchemes) 38 | -------------------------------------------------------------------------------- /src/screens/setting/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-04 19:20:02. 3 | * Last modified at 2022-04-14 14:24:27 4 | */ 5 | 6 | export { default as AboutScreen } from './About' 7 | export { default as FeedbackScreen } from './Feedback' 8 | export { default as LanguageScreen } from './Language' 9 | export { default as SettingScreen } from './Setting' 10 | export { default as ThemeScreen } from './Theme' 11 | export { default as CacheSettingScreen } from './CacheSetting' 12 | export { default as ChangeLogScreen } from './ChangeLog' 13 | export { default as HowToUseScreen } from './HowToUse' 14 | export { default as OpenSourceScreen } from './License' 15 | export { default as PrivacyScreen } from './Privacy' 16 | export { default as SiteStatScreen } from './SiteStat' 17 | export { default as URLSchemesScreen } from './URLSchemes' 18 | export { default as TermsOfServiceScreen } from './TermsOfService' 19 | -------------------------------------------------------------------------------- /src/screens/topic/NodeTopicList.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-04 19:20:02. 3 | * Last modified at 2022-04-20 11:16:10 4 | */ 5 | 6 | import { NodeTopicsScreenProps as ScreenProps } from '@src/navigation' 7 | import React, { useEffect } from 'react' 8 | import { FetchTopicCardList } from '../components' 9 | const NodeTopics = ({ route, navigation }: ScreenProps) => { 10 | useEffect(() => { 11 | navigation.setOptions({ 12 | title: route.params && route.params.nodeTitle 13 | }) 14 | }, [route, navigation]) 15 | return 16 | } 17 | export default NodeTopics 18 | -------------------------------------------------------------------------------- /src/screens/topic/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-04 19:20:02. 3 | * Last modified at 2022-03-15 21:39:55 4 | */ 5 | 6 | export { default as TopicDetailScreen } from './TopicDetail' 7 | export { default as NodeTopicListScreen } from './NodeTopicList' 8 | export { default as HomeTabNodeTopicListScreen } from './HomeTabNodeTopicList' 9 | -------------------------------------------------------------------------------- /src/theme/ThemeContext.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-02-24 10:13:44. 3 | * Last modified at 2022-03-10 09:46:27 4 | */ 5 | 6 | import React, { useContext } from 'react' 7 | import { Theme } from './types' 8 | import themes, { ThemeType } from './themes' 9 | export interface ThemeContextProps { 10 | theme: Theme 11 | themeName: ThemeType 12 | resetTheme: (theme: ThemeType) => void 13 | } 14 | const ThemeContext = React.createContext({ 15 | theme: themes.light, 16 | themeName: 'light', 17 | resetTheme: (themeName: string) => {} 18 | }) 19 | export default ThemeContext 20 | export const useTheme = () => useContext(ThemeContext) 21 | -------------------------------------------------------------------------------- /src/theme/ThemeProvider.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-02-24 10:13:44. 3 | * Last modified at 2022-09-25 16:13:58 4 | */ 5 | 6 | import { store } from '@src/store' 7 | import React, { useMemo, useState } from 'react' 8 | import { useColorScheme } from 'react-native' 9 | import ThemeContext from './ThemeContext' 10 | import themes, { ThemeType } from './themes' 11 | type Props = { 12 | children?: JSX.Element 13 | } 14 | 15 | const ThemeProvider = ({ children }: Props) => { 16 | const [themeName, resetTheme] = useState((store.getState() as any).setting.theme) 17 | const colorScheme = useColorScheme() 18 | 19 | const theme = useMemo( 20 | () => (themeName === 'auto' ? themes[colorScheme !== 'dark' ? 'light' : 'dark'] : themes[themeName]), 21 | [themeName] 22 | ) 23 | return {children} 24 | } 25 | export default ThemeProvider 26 | -------------------------------------------------------------------------------- /src/theme/dark/assets.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-03 18:01:46. 3 | * Last modified at 2022-03-30 21:35:37 4 | */ 5 | 6 | import lightAssets from '../light/assets' 7 | import { ThemeAssets } from '../types' 8 | const Assets: ThemeAssets = { 9 | ...lightAssets 10 | } 11 | export default Assets 12 | -------------------------------------------------------------------------------- /src/theme/dark/dimens.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-03 18:01:46. 3 | * Last modified at 2022-03-30 21:35:37 4 | */ 5 | 6 | import lightDimens from '../light/dimens' 7 | import { Dimensions } from './../types' 8 | const dimens: Dimensions = { 9 | ...lightDimens 10 | } 11 | export default dimens 12 | -------------------------------------------------------------------------------- /src/theme/dark/spacing.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-03 18:01:46. 3 | * Last modified at 2022-03-30 21:35:37 4 | */ 5 | 6 | import { Spacing } from '../types' 7 | import lightSpacing from '../light/spacing' 8 | const spacing: Spacing = { 9 | /** 10 | * base on light theme spacing 11 | */ 12 | ...lightSpacing 13 | } 14 | export default spacing 15 | -------------------------------------------------------------------------------- /src/theme/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-02-24 10:13:44. 3 | * Last modified at 2022-03-09 18:31:19 4 | */ 5 | 6 | import themes, { ThemeType, light, dark } from './themes' 7 | import ThemeContext, { useTheme } from './ThemeContext' 8 | import ThemeProvider from './ThemeProvider' 9 | export type { ThemeType } 10 | export { ThemeProvider, ThemeContext, themes, useTheme } 11 | export * from './types' 12 | export * as SylCommon from './common' 13 | 14 | export { light, dark } 15 | -------------------------------------------------------------------------------- /src/theme/light/dimens.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-03 21:32:14. 3 | * Last modified at 2022-04-19 17:04:45 4 | */ 5 | 6 | import { Dimensions as _Dimensions } from 'react-native' 7 | const screenWidth = _Dimensions.get('window').width 8 | const screenHeight = _Dimensions.get('window').height 9 | import { Dimensions } from '../types' 10 | const layoutContainerHorizontalMargin = 15 11 | const dimens: Dimensions = { 12 | WINDOW_WIDTH: screenWidth, 13 | WINDOW_HEIGHT: screenHeight, 14 | layoutContainerWidth: screenWidth - layoutContainerHorizontalMargin * 2, 15 | layoutContainerHorizontalMargin: layoutContainerHorizontalMargin, 16 | headerButtonSize: 23, 17 | headerHeight: 50, 18 | borderRadius: 2, 19 | badgeSize: 18, 20 | defaultButtonWidth: screenWidth - 60, 21 | defaultButtonHeight: 42, 22 | defaultButtonRadius: 5, 23 | defaultLineWidth: 0.3, 24 | defaultInputBoxHeight: 40 25 | } 26 | export default dimens 27 | -------------------------------------------------------------------------------- /src/theme/light/spacing.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-03 21:32:14. 3 | * Last modified at 2022-03-03 21:32:14 4 | */ 5 | 6 | import { Spacing } from '../types' 7 | const baseSpacing = 10 8 | const spacing: Spacing = { 9 | tiny: baseSpacing * 0.4, 10 | small: baseSpacing * 0.8, 11 | medium: baseSpacing * 1.2, 12 | large: baseSpacing * 1.6, 13 | extraLarge: baseSpacing * 2.4 14 | } 15 | export default spacing 16 | -------------------------------------------------------------------------------- /src/theme/themes.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-03 18:17:31. 3 | * Last modified at 2022-03-10 09:46:27 4 | */ 5 | 6 | import { Theme } from './types' 7 | import light_colors from './light/colors' 8 | import light_spacing from './light/spacing' 9 | import light_dimens from './light/dimens' 10 | import light_typography from './light/typography' 11 | import light_assets from './light/assets' 12 | import dark_colors from './dark/colors' 13 | import dark_spacing from './dark/spacing' 14 | import dark_dimens from './dark/dimens' 15 | import dark_typography from './dark/typography' 16 | import dark_assets from './dark/assets' 17 | 18 | export const light: Theme = { 19 | name: 'light', 20 | isDark: false, 21 | statusBarStyle: 'dark-content', 22 | colors: light_colors, 23 | spacing: light_spacing, 24 | dimensions: light_dimens, 25 | typography: light_typography, 26 | assets: light_assets 27 | } 28 | export const dark: Theme = { 29 | name: 'dark', 30 | isDark: true, 31 | statusBarStyle: 'light-content', 32 | colors: dark_colors, 33 | spacing: dark_spacing, 34 | dimensions: dark_dimens, 35 | typography: dark_typography, 36 | assets: dark_assets 37 | } 38 | export const auto = undefined 39 | const themes = { 40 | auto, 41 | light, 42 | dark 43 | } as const 44 | export type ThemeType = keyof typeof themes 45 | export default themes 46 | -------------------------------------------------------------------------------- /src/types/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-02-28 13:33:51. 3 | * Last modified at 2022-10-20 17:25:36 4 | */ 5 | 6 | import { ThemeType } from '@src/theme' 7 | import { LanguageTagType } from '@src/i18n' 8 | export * from '@src/store/types' 9 | export * from '@src/api/types' 10 | export * from '@src/actions/types' 11 | export * from '@src/theme/types' 12 | export type { ThemeType, LanguageTagType } 13 | -------------------------------------------------------------------------------- /src/utils/adapter.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-02-24 18:12:41. 3 | * Last modified at 2022-09-25 16:30:09 4 | */ 5 | 6 | import { Dimensions, Platform, StatusBar, PixelRatio } from 'react-native' 7 | export function isIphoneX() { 8 | const X_WIDTH = 375 9 | const X_HEIGHT = 812 10 | return Platform.OS === IOS && screenHeight === X_HEIGHT && screenWidth === X_WIDTH 11 | } 12 | /** 13 | * 返回状态栏的高度 14 | * @returns {number} 15 | */ 16 | export function getStatusBarHeight() { 17 | let statusBarHeight = 20 18 | if (Platform.OS === ANDROID) { 19 | statusBarHeight = StatusBar.currentHeight || 20 20 | } 21 | if (isIphoneX()) { 22 | statusBarHeight = 44 23 | } 24 | return statusBarHeight 25 | } 26 | // 设计稿的宽度和高度 27 | const designWidth = 375 28 | const designHeight = 667 29 | export const screenWidth = Dimensions.get('window').width 30 | export const screenHeight = Dimensions.get('window').height 31 | export const unitWidth = screenWidth / designWidth 32 | export const unitHeight = screenHeight / designHeight 33 | export const statusBarHeight = getStatusBarHeight() 34 | export const safeAreaViewHeight = isIphoneX() ? 34 : 0 35 | // 标题栏的高度 36 | export const titleHeight = unitWidth * 100 + statusBarHeight 37 | // 字体缩放比例,一般情况下不用考虑。 38 | // 当应用中的字体需要根据手机设置中字体大小改变的话需要用到缩放比例 39 | export const fontscale = PixelRatio.getFontScale() 40 | export const ANDROID = 'android' 41 | export const IOS = 'ios' 42 | -------------------------------------------------------------------------------- /src/utils/alert.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-01 16:43:25. 3 | * Last modified at 2022-09-25 16:30:09 4 | */ 5 | 6 | import { Alert } from 'react-native' 7 | import { translate } from '@src/i18n' 8 | interface IBaseAlert { 9 | title?: string 10 | message: string 11 | } 12 | interface IAlert extends IBaseAlert { 13 | title?: string 14 | message: string 15 | onPress?: (value?: string | undefined) => void 16 | } 17 | interface IConfirm extends IBaseAlert { 18 | onOk?: (value?: string | undefined) => void 19 | onCancel?: (value?: string | undefined) => void 20 | } 21 | export const alert = ({ title = translate('common.tip'), message, onPress }: IAlert) => { 22 | Alert.alert(title, message, [{ text: translate('common.ok'), onPress: onPress }]) 23 | } 24 | export const confirm = ({ title = translate('common.tip'), message, onOk: onOK, onCancel }: IConfirm) => { 25 | Alert.alert(title, message, [ 26 | { text: translate('common.ok'), onPress: onOK, style: 'default' }, 27 | { text: translate('common.cancel'), onPress: onCancel, style: 'cancel' } 28 | ]) 29 | } 30 | -------------------------------------------------------------------------------- /src/utils/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-05 17:28:05. 3 | * Last modified at 2022-03-15 21:39:20 4 | */ 5 | 6 | import { Linking, Platform } from 'react-native' 7 | export * as Utils from './utils' 8 | export * as Adapter from './adapter' 9 | export * as Params from './params' 10 | export * as Parser from './parser' 11 | export * as Alert from './alert' 12 | import * as Alert from './alert' 13 | export const linking = async (url: string) => { 14 | const supported = await Linking.canOpenURL(url) 15 | try { 16 | await Linking.openURL(url) 17 | } catch (err) { 18 | Alert.alert({ message: `Don't know how to open this URL: ${url}` }) 19 | } 20 | } 21 | export function validKey(key: string | number | symbol, object: object): key is keyof typeof object { 22 | return key in object 23 | } 24 | -------------------------------------------------------------------------------- /src/utils/params.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-02-24 18:12:41. 3 | * Last modified at 2022-02-24 18:12:41 4 | */ 5 | 6 | export function typedKeys(o: T): (keyof T)[] { 7 | // type cast should be safe because that's what really Object.keys() does 8 | return Object.keys(o) as (keyof T)[] 9 | } 10 | export function getUrlParams(url: string) { 11 | const regex = /[?&]([^=#]+)=([^&#]*)/g 12 | const params = new Map() 13 | let match 14 | while ((match = regex.exec(url))) { 15 | params.set(match[1], match[2]) 16 | } 17 | return params 18 | } 19 | -------------------------------------------------------------------------------- /src/utils/parser.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-02-24 18:12:41. 3 | * Last modified at 2022-02-24 18:12:41 4 | */ 5 | 6 | export const parseDate2Ts = (date: string) => { 7 | return new Date(Date.parse(date.replace(/-/g, '/'))).getTime() 8 | } 9 | -------------------------------------------------------------------------------- /src/utils/promise.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-11-08 23:49:23. 3 | * Last modified at 2022-11-08 23:49:23 4 | */ 5 | 6 | export const resolve = async ( 7 | promiseLike: Promise | T 8 | ): Promise<[E, undefined] | [undefined, T]> => { 9 | try { 10 | const data = await promiseLike 11 | return [undefined, data] 12 | } catch (error: unknown) { 13 | return [error as E, undefined] 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/utils/utils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Leon at 2022-03-05 17:28:05. 3 | * Last modified at 2022-11-08 23:49:23 4 | */ 5 | 6 | export const wait = (timeout: number, callback?: () => void) => { 7 | return new Promise((resolve) => { 8 | setTimeout(() => { 9 | callback && callback() 10 | resolve(true) 11 | }, timeout) 12 | }) 13 | } 14 | /** 15 | * compareVersion('1.11.0', '1.9.9') 16 | // 1 新版本 0相同版本 -1低版本 17 | */ 18 | export function compareVersion(_v1: string, _v2: string) { 19 | const v1 = _v1.split('.') 20 | const v2 = _v2.split('.') 21 | const len = Math.max(v1.length, v2.length) 22 | while (v1.length < len) { 23 | v1.push('0') 24 | } 25 | while (v2.length < len) { 26 | v2.push('0') 27 | } 28 | for (let i = 0; i < len; i++) { 29 | const num1 = parseInt(v1[i], 10) 30 | const num2 = parseInt(v2[i], 10) 31 | if (num1 > num2) { 32 | return 1 33 | } 34 | if (num1 < num2) { 35 | return -1 36 | } 37 | } 38 | return 0 39 | } 40 | --------------------------------------------------------------------------------