├── .bundle └── config ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ ├── ci.yml │ ├── packages-check.yml │ └── pr-check.yml ├── .gitignore ├── .husky └── pre-commit ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── PULL_REQUEST_TEMPLATE.md ├── README.md ├── SECURITY.md ├── apps └── thu-info-app │ ├── .babelrc │ ├── .eslintrc.json │ ├── .gitignore │ ├── .increment.js │ ├── .jestsetup.js │ ├── .prettierrc.json │ ├── .watchmanconfig │ ├── android │ ├── app │ │ ├── THUInfo.jks.enc │ │ ├── build.gradle │ │ ├── debug.keystore │ │ ├── proguard-rules.pro │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── ic_launcher-playstore.png │ │ │ ├── java │ │ │ └── com │ │ │ │ └── unidy2002 │ │ │ │ └── thuinfo │ │ │ │ ├── MainActivity.kt │ │ │ │ ├── MainApplication.kt │ │ │ │ └── utils.kt │ │ │ └── res │ │ │ ├── drawable │ │ │ ├── ic_launcher_foreground.xml │ │ │ └── rn_edit_text_material.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── values │ │ │ ├── ic_launcher_background.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ │ └── xml │ │ │ └── network_config.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle │ ├── app.json │ ├── babel.config.json │ ├── harmony │ ├── .gitignore │ ├── .ohpmrc │ ├── AppScope │ │ ├── app.json5 │ │ └── resources │ │ │ └── base │ │ │ ├── element │ │ │ └── string.json │ │ │ └── media │ │ │ └── app_icon.png │ ├── build-profile.json5 │ ├── code-linter.json5 │ ├── entry │ │ ├── .gitignore │ │ ├── build-profile.json5 │ │ ├── hvigorfile.ts │ │ ├── obfuscation-rules.txt │ │ ├── oh-package-lock.json5 │ │ ├── oh-package.json5 │ │ └── src │ │ │ ├── main │ │ │ ├── cpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── PackageProvider.cpp │ │ │ ├── ets │ │ │ │ ├── GeneratedPackage.ets │ │ │ │ ├── RNPackagesFactory.ets │ │ │ │ ├── entryability │ │ │ │ │ └── EntryAbility.ets │ │ │ │ ├── entrybackupability │ │ │ │ │ └── EntryBackupAbility.ets │ │ │ │ ├── pages │ │ │ │ │ └── Index.ets │ │ │ │ └── turbomodule │ │ │ │ │ └── NetworkUtilsModule.ts │ │ │ ├── module.json5 │ │ │ └── resources │ │ │ │ ├── base │ │ │ │ ├── element │ │ │ │ │ ├── color.json │ │ │ │ │ └── string.json │ │ │ │ ├── media │ │ │ │ │ ├── background.png │ │ │ │ │ ├── foreground.png │ │ │ │ │ ├── layered_image.json │ │ │ │ │ └── startIcon.png │ │ │ │ └── profile │ │ │ │ │ ├── backup_config.json │ │ │ │ │ └── main_pages.json │ │ │ │ ├── dark │ │ │ │ └── element │ │ │ │ │ └── color.json │ │ │ │ ├── en_US │ │ │ │ └── element │ │ │ │ │ └── string.json │ │ │ │ ├── phone-ldpi │ │ │ │ └── media │ │ │ │ │ ├── icon.png │ │ │ │ │ └── icon_startwindow.png │ │ │ │ ├── phone-mdpi │ │ │ │ └── media │ │ │ │ │ ├── icon.png │ │ │ │ │ └── icon_startwindow.png │ │ │ │ ├── phone-sdpi │ │ │ │ └── media │ │ │ │ │ ├── icon.png │ │ │ │ │ └── icon_startwindow.png │ │ │ │ ├── phone-xldpi │ │ │ │ └── media │ │ │ │ │ ├── icon.png │ │ │ │ │ └── icon_startwindow.png │ │ │ │ ├── phone-xxldpi │ │ │ │ └── media │ │ │ │ │ ├── icon.png │ │ │ │ │ └── icon_startwindow.png │ │ │ │ ├── phone-xxxldpi │ │ │ │ └── media │ │ │ │ │ ├── icon.png │ │ │ │ │ └── icon_startwindow.png │ │ │ │ └── zh_CN │ │ │ │ └── element │ │ │ │ └── string.json │ │ │ ├── mock │ │ │ └── mock-config.json5 │ │ │ ├── ohosTest │ │ │ ├── ets │ │ │ │ └── test │ │ │ │ │ ├── Ability.test.ets │ │ │ │ │ └── List.test.ets │ │ │ └── module.json5 │ │ │ └── test │ │ │ ├── List.test.ets │ │ │ └── LocalUnit.test.ets │ ├── hvigor │ │ └── hvigor-config.json5 │ ├── hvigorfile.ts │ ├── hvigorw │ ├── hvigorw.js │ ├── oh-package-lock.json5 │ └── oh-package.json5 │ ├── index.js │ ├── ios │ ├── .xcode.env │ ├── AppDelegate.swift │ ├── Podfile │ ├── Podfile.lock │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── fastlane │ │ ├── Appfile │ │ ├── Deliverfile │ │ ├── Fastfile │ │ ├── Matchfile │ │ ├── README.md │ │ └── metadata │ │ │ ├── copyright.txt │ │ │ ├── primary_category.txt │ │ │ ├── primary_first_sub_category.txt │ │ │ ├── primary_second_sub_category.txt │ │ │ ├── review_information │ │ │ ├── demo_password.txt │ │ │ ├── demo_user.txt │ │ │ ├── email_address.txt │ │ │ ├── first_name.txt │ │ │ ├── last_name.txt │ │ │ ├── notes.txt │ │ │ └── phone_number.txt │ │ │ ├── secondary_category.txt │ │ │ ├── secondary_first_sub_category.txt │ │ │ ├── secondary_second_sub_category.txt │ │ │ └── zh-Hans │ │ │ ├── apple_tv_privacy_policy.txt │ │ │ ├── description.txt │ │ │ ├── keywords.txt │ │ │ ├── marketing_url.txt │ │ │ ├── name.txt │ │ │ ├── privacy_url.txt │ │ │ ├── promotional_text.txt │ │ │ ├── release_notes.txt │ │ │ ├── subtitle.txt │ │ │ └── support_url.txt │ ├── thu_info.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── thu_info.xcscheme │ ├── thu_info.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ ├── thu_info │ │ ├── Base.lproj │ │ │ └── LaunchScreen.xib │ │ ├── Images.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ ├── 100.png │ │ │ │ ├── 1024.png │ │ │ │ ├── 114.png │ │ │ │ ├── 120.png │ │ │ │ ├── 128.png │ │ │ │ ├── 144.png │ │ │ │ ├── 152.png │ │ │ │ ├── 16.png │ │ │ │ ├── 167.png │ │ │ │ ├── 172.png │ │ │ │ ├── 180.png │ │ │ │ ├── 196.png │ │ │ │ ├── 20.png │ │ │ │ ├── 216.png │ │ │ │ ├── 256.png │ │ │ │ ├── 29.png │ │ │ │ ├── 32.png │ │ │ │ ├── 40.png │ │ │ │ ├── 48.png │ │ │ │ ├── 50.png │ │ │ │ ├── 512.png │ │ │ │ ├── 55.png │ │ │ │ ├── 57.png │ │ │ │ ├── 58.png │ │ │ │ ├── 60.png │ │ │ │ ├── 64.png │ │ │ │ ├── 72.png │ │ │ │ ├── 76.png │ │ │ │ ├── 80.png │ │ │ │ ├── 87.png │ │ │ │ ├── 88.png │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── Info.plist │ │ ├── PrivacyInfo.xcprivacy │ │ └── zh-Hans.lproj │ │ │ └── LaunchScreen.strings │ └── zh-Hans.lproj │ │ └── InfoPlist.strings │ ├── jest.config.json │ ├── metro.config.js │ ├── package.json │ ├── patches │ └── react-native-safearea-height+1.0.8.patch │ ├── src │ ├── App.tsx │ ├── assets │ │ ├── colors │ │ │ ├── dark.ts │ │ │ ├── light.ts │ │ │ ├── pkuDark.ts │ │ │ └── pkuLight.ts │ │ ├── icons │ │ │ ├── IconAdd.tsx │ │ │ ├── IconAlipay.tsx │ │ │ ├── IconBankCard.tsx │ │ │ ├── IconBankPayment.tsx │ │ │ ├── IconBoard.tsx │ │ │ ├── IconBook.tsx │ │ │ ├── IconCalendar.tsx │ │ │ ├── IconCheck.tsx │ │ │ ├── IconCheckGrey.tsx │ │ │ ├── IconClassroom.tsx │ │ │ ├── IconConfig.tsx │ │ │ ├── IconCopy.tsx │ │ │ ├── IconCr.tsx │ │ │ ├── IconDeepSeek.tsx │ │ │ ├── IconDeepSeekTab.tsx │ │ │ ├── IconDisable.tsx │ │ │ ├── IconDorm.tsx │ │ │ ├── IconDormScore.tsx │ │ │ ├── IconDown.tsx │ │ │ ├── IconDownload.tsx │ │ │ ├── IconDrink.tsx │ │ │ ├── IconDropdown.tsx │ │ │ ├── IconEleRecharge.tsx │ │ │ ├── IconEvaluation.tsx │ │ │ ├── IconExchange.tsx │ │ │ ├── IconExclamation.tsx │ │ │ ├── IconExpenditure.tsx │ │ │ ├── IconFinance.tsx │ │ │ ├── IconFormStar.tsx │ │ │ ├── IconGrades.tsx │ │ │ ├── IconHamburger.tsx │ │ │ ├── IconHamburgerMenu.tsx │ │ │ ├── IconHistory.tsx │ │ │ ├── IconHomeTab.tsx │ │ │ ├── IconIncome.tsx │ │ │ ├── IconInvoice.tsx │ │ │ ├── IconLeft.tsx │ │ │ ├── IconLibRoom.tsx │ │ │ ├── IconLibrary.tsx │ │ │ ├── IconLocal.tsx │ │ │ ├── IconLock.tsx │ │ │ ├── IconLoseCard.tsx │ │ │ ├── IconMain.tsx │ │ │ ├── IconMinus.tsx │ │ │ ├── IconNetwork.tsx │ │ │ ├── IconNetworkDetail.tsx │ │ │ ├── IconNetworkOnlineDevices.tsx │ │ │ ├── IconNewsTab.tsx │ │ │ ├── IconNoodles.tsx │ │ │ ├── IconNotSelected.tsx │ │ │ ├── IconPeek.tsx │ │ │ ├── IconPeople.tsx │ │ │ ├── IconPerson.tsx │ │ │ ├── IconPhysicalExam.tsx │ │ │ ├── IconPot.tsx │ │ │ ├── IconRefresh.tsx │ │ │ ├── IconReport.tsx │ │ │ ├── IconReserve.tsx │ │ │ ├── IconRice.tsx │ │ │ ├── IconRight.tsx │ │ │ ├── IconScheduleTab.tsx │ │ │ ├── IconSearch.tsx │ │ │ ├── IconSelected.tsx │ │ │ ├── IconSend.tsx │ │ │ ├── IconSettingsTab.tsx │ │ │ ├── IconShare.tsx │ │ │ ├── IconShopping.tsx │ │ │ ├── IconShower.tsx │ │ │ ├── IconSocket.tsx │ │ │ ├── IconSports.tsx │ │ │ ├── IconStar.tsx │ │ │ ├── IconStarActive.tsx │ │ │ ├── IconSubscription.tsx │ │ │ ├── IconSubscriptionLogo.tsx │ │ │ ├── IconSuccess.tsx │ │ │ ├── IconSwim.tsx │ │ │ ├── IconTime.tsx │ │ │ ├── IconTrademark.tsx │ │ │ ├── IconWasher.tsx │ │ │ ├── IconWater.tsx │ │ │ └── IconWechat.tsx │ │ ├── themes │ │ │ └── themes.ts │ │ └── translations │ │ │ ├── en.ts │ │ │ └── zh.ts │ ├── components │ │ ├── LazyImage.tsx │ │ ├── Root.tsx │ │ ├── easySnackbars.ts │ │ ├── home │ │ │ ├── cr.tsx │ │ │ ├── form.tsx │ │ │ ├── icon.tsx │ │ │ ├── libRoomBookTimeIndicator.tsx │ │ │ ├── libraryRefreshListScreen.tsx │ │ │ └── secondaryItems.tsx │ │ ├── news │ │ │ ├── IconStarButton.tsx │ │ │ └── NewsListItem.tsx │ │ ├── schedule │ │ │ └── schedule.tsx │ │ ├── settings │ │ │ ├── items.tsx │ │ │ ├── paginatedRefreshListScreen.tsx │ │ │ └── simpleRefreshListScreen.tsx │ │ └── views.tsx │ ├── constants │ │ └── strings.ts │ ├── network │ │ └── water.ts │ ├── redux │ │ ├── slices │ │ │ ├── announcement.ts │ │ │ ├── auth.ts │ │ │ ├── campusCard.ts │ │ │ ├── config.ts │ │ │ ├── credentials.ts │ │ │ ├── deepseek.ts │ │ │ ├── reservation.ts │ │ │ ├── schedule.ts │ │ │ ├── timetable.ts │ │ │ └── top5.ts │ │ └── store.ts │ ├── ui │ │ ├── home │ │ │ ├── bankPayment.tsx │ │ │ ├── campusCard.tsx │ │ │ ├── classroomDetail.tsx │ │ │ ├── classroomList.tsx │ │ │ ├── crCoursePlan.tsx │ │ │ ├── crHome.tsx │ │ │ ├── crSearchResult.tsx │ │ │ ├── deepseek.tsx │ │ │ ├── dorm.tsx │ │ │ ├── dormScore.tsx │ │ │ ├── eleRecord.tsx │ │ │ ├── electricity.tsx │ │ │ ├── evaluation.tsx │ │ │ ├── expenditure.tsx │ │ │ ├── finance.tsx │ │ │ ├── form.tsx │ │ │ ├── home.tsx │ │ │ ├── income.tsx │ │ │ ├── invoice.tsx │ │ │ ├── invoicePDF.tsx │ │ │ ├── libBookRecord.tsx │ │ │ ├── libRoomBook.tsx │ │ │ ├── libRoomBookRecord.tsx │ │ │ ├── libRoomPerformBook.tsx │ │ │ ├── libRoomSelect.tsx │ │ │ ├── library.tsx │ │ │ ├── libraryFloor.tsx │ │ │ ├── libraryMap.tsx │ │ │ ├── librarySeat.tsx │ │ │ ├── librarySection.tsx │ │ │ ├── loseCard.tsx │ │ │ ├── network.tsx │ │ │ ├── networkDetail.tsx │ │ │ ├── networkLogin.tsx │ │ │ ├── networkOnlineDevices.tsx │ │ │ ├── peekScore.tsx │ │ │ ├── physicalExam.tsx │ │ │ ├── report.tsx │ │ │ ├── reserve.tsx │ │ │ ├── reservesLibPDF.tsx │ │ │ ├── reservesLibWelcome.tsx │ │ │ ├── schoolCalendar.tsx │ │ │ ├── sports.tsx │ │ │ ├── sportsDetail.tsx │ │ │ ├── sportsRecord.tsx │ │ │ ├── sportsSelect.tsx │ │ │ ├── sportsSelectField.tsx │ │ │ ├── sportsSelectTitle.tsx │ │ │ ├── sportsSuccess.tsx │ │ │ ├── washer.tsx │ │ │ └── water.tsx │ │ ├── news │ │ │ ├── news.tsx │ │ │ ├── newsDetail.tsx │ │ │ ├── newsFav.tsx │ │ │ └── newsSub.tsx │ │ ├── schedule │ │ │ ├── schedule.tsx │ │ │ ├── scheduleAdd.tsx │ │ │ ├── scheduleDetail.tsx │ │ │ ├── scheduleHidden.tsx │ │ │ └── scheduleSync.tsx │ │ └── settings │ │ │ ├── about.tsx │ │ │ ├── account.tsx │ │ │ ├── appSecret.tsx │ │ │ ├── appSecretCustomize.tsx │ │ │ ├── appSecretSelectLockTime.tsx │ │ │ ├── darkMode.tsx │ │ │ ├── deepseekSettings.tsx │ │ │ ├── digitalPassword.tsx │ │ │ ├── feedback.tsx │ │ │ ├── feishuFeedback.tsx │ │ │ ├── functionManagement.tsx │ │ │ ├── general.tsx │ │ │ ├── language.tsx │ │ │ ├── login.tsx │ │ │ ├── myhomeLogin.tsx │ │ │ ├── popi.tsx │ │ │ ├── privacy.tsx │ │ │ ├── resetDormPassword.tsx │ │ │ ├── scheduleSettings.tsx │ │ │ ├── settings.tsx │ │ │ └── twoFactorAuth.tsx │ └── utils │ │ ├── alipay.ts │ │ ├── calendar.ts │ │ ├── checkUpdate.ts │ │ ├── easterEgg.ts │ │ ├── extensions.ts │ │ ├── extensionsDeclaration.d.ts │ │ ├── i18n.ts │ │ ├── saveImg.ts │ │ ├── themedStyles.ts │ │ └── webApi.ts │ ├── test │ ├── i18n.test.ts │ └── render.test.tsx │ └── tsconfig.json ├── lerna.json ├── package.json ├── packages ├── RTNNetworkUtils │ ├── index.ts │ ├── package.json │ └── src │ │ └── specs │ │ ├── v1 │ │ └── .gitkeep │ │ └── v2 │ │ └── NativeNetworkUtils.ts └── thu-info-lib │ ├── .eslintrc.json │ ├── .gitignore │ ├── README.md │ ├── __tests__ │ ├── auth.ts │ ├── schedule.ts │ └── tsconfig.json │ ├── demo.js │ ├── demo │ ├── browser-polyfill.min.js │ ├── index.html │ ├── index.ts │ └── manifest.json │ ├── openssl.cnf │ ├── package.json │ ├── src │ ├── constants │ │ └── strings.ts │ ├── index.ts │ ├── lib │ │ ├── app.ts │ │ ├── basics.ts │ │ ├── card.ts │ │ ├── core.ts │ │ ├── cr.ts │ │ ├── dorm.ts │ │ ├── gitlab.ts │ │ ├── library.ts │ │ ├── network.ts │ │ ├── news.ts │ │ ├── program.ts │ │ ├── reserves-lib.ts │ │ ├── schedule.ts │ │ ├── sports.ts │ │ └── thos.ts │ ├── mocks │ │ ├── app.ts │ │ ├── basics.ts │ │ ├── card.ts │ │ ├── cr.ts │ │ ├── dorm.ts │ │ ├── gitlab.ts │ │ ├── library.ts │ │ ├── news.ts │ │ ├── program.ts │ │ ├── reserves-lib.ts │ │ ├── schedule.ts │ │ ├── sports.ts │ │ └── thos.ts │ ├── models │ │ ├── app │ │ │ ├── announcement.ts │ │ │ ├── feedback.ts │ │ │ └── version.ts │ │ ├── card │ │ │ ├── info.ts │ │ │ ├── recharge.ts │ │ │ └── transaction.ts │ │ ├── cr │ │ │ └── cr.ts │ │ ├── gitlab │ │ │ └── gitlab.ts │ │ ├── home │ │ │ ├── assessment.ts │ │ │ ├── bank.ts │ │ │ ├── classroom.ts │ │ │ ├── invoice.ts │ │ │ ├── library.ts │ │ │ ├── report.ts │ │ │ ├── reserves-lib.ts │ │ │ ├── sports.ts │ │ │ └── thos.ts │ │ ├── network │ │ │ ├── account.ts │ │ │ ├── balance.ts │ │ │ ├── detail.ts │ │ │ └── device.ts │ │ ├── news │ │ │ └── news.ts │ │ ├── program │ │ │ └── program.ts │ │ └── schedule │ │ │ ├── calendar.ts │ │ │ └── schedule.ts │ └── utils │ │ ├── alipay.ts │ │ ├── cheerio.ts │ │ ├── error.ts │ │ └── network.ts │ ├── tsconfig.json │ └── webpack.config.js ├── release-notes.md ├── renovate.json ├── setup-harmony.sh └── yarn.lock /.bundle/config: -------------------------------------------------------------------------------- 1 | BUNDLE_PATH: "vendor/bundle" 2 | BUNDLE_FORCE_RUBY_PLATFORM: 1 3 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | 12 | **Describe the bug** 13 | A clear and concise description of what the bug is. 14 | 15 | **To Reproduce** 16 | Steps to reproduce the behavior: 17 | 1. 18 | 2. 19 | 3. 20 | 4. 21 | 22 | **Expected behavior** 23 | A clear and concise description of what you expected to happen. 24 | 25 | **Screenshots** 26 | If applicable, add screenshots to help explain your problem. 27 | 28 | **Version** 29 | Enter the version of your application. 30 | 31 | **Device** 32 | Enter your device information. 33 | 34 | **Additional context** 35 | Add any other context about the problem here. 36 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: feature 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | 12 | **Is your feature request related to a problem? Please describe.** 13 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 14 | 15 | **Describe the solution you'd like** 16 | A clear and concise description of what you want to happen. 17 | 18 | **Describe alternatives you've considered** 19 | A clear and concise description of any alternative solutions or features you've considered. 20 | 21 | **Additional context** 22 | Add any other context or screenshots about the feature request here. 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | builds/* 9 | *.pbxuser 10 | !default.pbxuser 11 | *.mode1v3 12 | !default.mode1v3 13 | *.mode2v3 14 | !default.mode2v3 15 | *.perspectivev3 16 | !default.perspectivev3 17 | xcuserdata 18 | *.xccheckout 19 | *.moved-aside 20 | DerivedData 21 | *.hmap 22 | *.ipa 23 | *.xcuserstate 24 | *.xcarchive 25 | ios/.xcode.env.local 26 | 27 | # Android/IntelliJ 28 | # 29 | # build/ 30 | .idea 31 | .gradle 32 | local.properties 33 | *.iml 34 | *.hprof 35 | .cxx/ 36 | *.jks 37 | *.keystore 38 | !debug.keystore 39 | .kotlin/ 40 | 41 | # Visual Studio Code 42 | # 43 | .vscode/ 44 | 45 | # Eclipse 46 | # 47 | .settings/ 48 | .classpath 49 | .project 50 | 51 | # node.js 52 | # 53 | node_modules/ 54 | npm-debug.log 55 | yarn-error.log 56 | 57 | # testing 58 | /coverage 59 | 60 | # fastlane 61 | # 62 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 63 | # screenshots whenever they are needed. 64 | # For more information about the recommended setup visit: 65 | # https://docs.fastlane.tools/best-practices/source-control/ 66 | 67 | **/fastlane/report.xml 68 | **/fastlane/Preview.html 69 | **/fastlane/screenshots 70 | **/fastlane/test_output 71 | 72 | # Bundle artifact 73 | *.jsbundle 74 | 75 | # Ruby / CocoaPods 76 | /ios/Pods/ 77 | /vendor/bundle/ 78 | 79 | # Temporary files created by Metro to check the health of the file watcher 80 | .metro-health-check* 81 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | yarn lint 2 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "cocoapods", "1.16.2" 4 | gem "fastlane", "2.227.2" 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Business Source License 1.1 https://mariadb.com/bsl11/ 2 | Licensor: UNIDY2002 3 | Licensed Work: THU Info APP 4 | Additional Use Grant: None 5 | Change Date: Four years from first release for the specific version. 6 | Change License: MIT, text at https://opensource.org/license/mit/ with the following copyright notice: 7 | Copyright 2020-present UNIDY2002 8 | -------------------------------------------------------------------------------- /PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | :tada: Thanks for taking time to contribute! :tada: 2 | 3 | Before we move on, fill out the template so that we can better understand your contribution. 4 | 5 | **What is the purpose of this PR?** 6 | 7 | - [ ] Fixing a bug 8 | - [ ] Adding a feature 9 | 10 | **Is there a related issue?** 11 | 12 | 13 | 14 | - [ ] I understand that *adding a new feature* before *creating a feature request issue* has a high chance of rejection. 15 | 16 | **Please describe your changes.** 17 | 18 | 19 | 20 | **Are there any possible drawbacks or side-effects?** 21 | 22 | 23 | 24 | **How to verify the changes?** 25 | 26 | 37 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | If you discover a security vulnerability, please contact us at [i@thuinfo.net](mailto:i@thuinfo.net). We shall reply in no longer than 24 hours. 4 | -------------------------------------------------------------------------------- /apps/thu-info-app/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "production": { 4 | "plugins": [ 5 | "transform-remove-console" 6 | ] 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /apps/thu-info-app/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": "@react-native", 4 | "rules": { 5 | "react/react-in-jsx-scope": "off", 6 | "react/no-unstable-nested-components": "off", 7 | "react-native/no-inline-styles": "off", 8 | "quotes": [ 9 | "error", 10 | "double" 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /apps/thu-info-app/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | builds/* 9 | *.pbxuser 10 | !default.pbxuser 11 | *.mode1v3 12 | !default.mode1v3 13 | *.mode2v3 14 | !default.mode2v3 15 | *.perspectivev3 16 | !default.perspectivev3 17 | xcuserdata 18 | *.xccheckout 19 | *.moved-aside 20 | DerivedData 21 | *.hmap 22 | *.ipa 23 | *.xcuserstate 24 | *.xcarchive 25 | ios/.xcode.env.local 26 | 27 | # Android/IntelliJ 28 | # 29 | # build/ 30 | .idea 31 | .gradle 32 | local.properties 33 | *.iml 34 | *.hprof 35 | .cxx/ 36 | *.jks 37 | *.keystore 38 | !debug.keystore 39 | 40 | # Visual Studio Code 41 | # 42 | .vscode/ 43 | 44 | # Eclipse 45 | # 46 | .settings/ 47 | .classpath 48 | .project 49 | 50 | # node.js 51 | # 52 | node_modules/ 53 | npm-debug.log 54 | yarn-error.log 55 | 56 | # testing 57 | /coverage 58 | 59 | # fastlane 60 | # 61 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 62 | # screenshots whenever they are needed. 63 | # For more information about the recommended setup visit: 64 | # https://docs.fastlane.tools/best-practices/source-control/ 65 | 66 | **/fastlane/report.xml 67 | **/fastlane/Preview.html 68 | **/fastlane/screenshots 69 | **/fastlane/test_output 70 | 71 | # Bundle artifact 72 | *.jsbundle 73 | 74 | # Ruby / CocoaPods 75 | /ios/Pods/ 76 | /vendor/bundle/ 77 | 78 | # Temporary files created by Metro to check the health of the file watcher 79 | .metro-health-check* 80 | -------------------------------------------------------------------------------- /apps/thu-info-app/.increment.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const pkg = require("./package.json"); 3 | 4 | const pkgString = fs.readFileSync("./package.json").toString(); 5 | fs.writeFileSync("./package.json", pkgString.replace(`"build": ${pkg.build}`, `"build": ${pkg.build + 1}`).replace(`"@thu-info/lib": "${pkg.dependencies["@thu-info/lib"]}"`, `"@thu-info/lib": "*"`)); 6 | -------------------------------------------------------------------------------- /apps/thu-info-app/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "bracketSpacing": false, 3 | "bracketSameLine": true, 4 | "singleQuote": false, 5 | "trailingComma": "all", 6 | "useTabs": true, 7 | "endOfLine": "auto" 8 | } 9 | -------------------------------------------------------------------------------- /apps/thu-info-app/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /apps/thu-info-app/android/app/THUInfo.jks.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/android/app/THUInfo.jks.enc -------------------------------------------------------------------------------- /apps/thu-info-app/android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/android/app/debug.keystore -------------------------------------------------------------------------------- /apps/thu-info-app/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: 11 | 12 | -keep public class com.horcrux.svg.** {*;} 13 | -keep class com.facebook.react.turbomodule.** {*;} 14 | -------------------------------------------------------------------------------- /apps/thu-info-app/android/app/src/main/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/android/app/src/main/ic_launcher-playstore.png -------------------------------------------------------------------------------- /apps/thu-info-app/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /apps/thu-info-app/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /apps/thu-info-app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /apps/thu-info-app/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /apps/thu-info-app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /apps/thu-info-app/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /apps/thu-info-app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /apps/thu-info-app/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /apps/thu-info-app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /apps/thu-info-app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /apps/thu-info-app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /apps/thu-info-app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /apps/thu-info-app/android/app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #A652CB 4 | -------------------------------------------------------------------------------- /apps/thu-info-app/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | THU Info 3 | 4 | -------------------------------------------------------------------------------- /apps/thu-info-app/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /apps/thu-info-app/android/app/src/main/res/xml/network_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /apps/thu-info-app/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | import groovy.json.JsonSlurper 4 | 5 | static def getNpmVersion() { 6 | def inputFile = new File("../package.json") 7 | def packageJson = new JsonSlurper().parseText(inputFile.text) 8 | return [packageJson["version"], packageJson["build"]] 9 | } 10 | 11 | buildscript { 12 | ext { 13 | buildToolsVersion = "35.0.0" 14 | minSdkVersion = 24 15 | compileSdkVersion = 35 16 | targetSdkVersion = 35 17 | ndkVersion = "26.1.10909125" 18 | kotlinVersion = "1.9.24" 19 | } 20 | repositories { 21 | google() 22 | mavenCentral() 23 | } 24 | dependencies { 25 | classpath("com.android.tools.build:gradle") 26 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") 27 | classpath("com.facebook.react:react-native-gradle-plugin") 28 | } 29 | } 30 | 31 | subprojects { 32 | ext { 33 | def npmVersion = getNpmVersion() 34 | npmVersionName = npmVersion[0] 35 | npmVersionCode = npmVersion[1] 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /apps/thu-info-app/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /apps/thu-info-app/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /apps/thu-info-app/android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { includeBuild("../../../node_modules/@react-native/gradle-plugin") } 2 | plugins { id("com.facebook.react.settings") } 3 | extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() } 4 | rootProject.name = 'thu_info' 5 | include ':app' 6 | includeBuild('../../../node_modules/@react-native/gradle-plugin') 7 | -------------------------------------------------------------------------------- /apps/thu-info-app/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "thu_info", 3 | "displayName": "THUInfo" 4 | } 5 | -------------------------------------------------------------------------------- /apps/thu-info-app/babel.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "module:@react-native/babel-preset" 4 | ], 5 | "plugins": [ 6 | "@babel/plugin-transform-export-namespace-from" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /oh_modules 3 | /local.properties 4 | /.idea 5 | **/build 6 | /.hvigor 7 | .cxx 8 | /.clangd 9 | /.clang-format 10 | /.clang-tidy 11 | **/.test 12 | /.appanalyzer 13 | generated 14 | -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/.ohpmrc: -------------------------------------------------------------------------------- 1 | registry=https://ohpm.openharmony.cn/ohpm/ 2 | -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/AppScope/app.json5: -------------------------------------------------------------------------------- 1 | { 2 | "app": { 3 | "bundleName": "com.unidy2002.thuinfo", 4 | "vendor": "unidy2002", 5 | "versionCode": 2, 6 | "versionName": "3.12.1", 7 | "icon": "$media:app_icon", 8 | "label": "$string:app_name" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/AppScope/resources/base/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "app_name", 5 | "value": "THU Info" 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/AppScope/resources/base/media/app_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/harmony/AppScope/resources/base/media/app_icon.png -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/build-profile.json5: -------------------------------------------------------------------------------- 1 | { 2 | "app": { 3 | "signingConfigs": [], 4 | "products": [ 5 | { 6 | "name": "default", 7 | "signingConfig": "default", 8 | "compatibleSdkVersion": "5.0.0(12)", 9 | "runtimeOS": "HarmonyOS", 10 | "buildOption": { 11 | "strictMode": { 12 | "caseSensitiveCheck": true, 13 | "useNormalizedOHMUrl": true 14 | } 15 | } 16 | } 17 | ], 18 | "buildModeSet": [ 19 | { 20 | "name": "debug", 21 | }, 22 | { 23 | "name": "release" 24 | } 25 | ] 26 | }, 27 | "modules": [ 28 | { 29 | "name": "entry", 30 | "srcPath": "./entry", 31 | "targets": [ 32 | { 33 | "name": "default", 34 | "applyToProducts": [ 35 | "default" 36 | ] 37 | } 38 | ] 39 | } 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/code-linter.json5: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | "**/*.ets" 4 | ], 5 | "ignore": [ 6 | "**/src/ohosTest/**/*", 7 | "**/src/test/**/*", 8 | "**/src/mock/**/*", 9 | "**/node_modules/**/*", 10 | "**/oh_modules/**/*", 11 | "**/build/**/*", 12 | "**/.preview/**/*" 13 | ], 14 | "ruleSet": [ 15 | "plugin:@performance/recommended", 16 | "plugin:@typescript-eslint/recommended" 17 | ], 18 | "rules": { 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /oh_modules 3 | /.preview 4 | /build 5 | /.cxx 6 | /.test 7 | bundle.harmony.js 8 | -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/build-profile.json5: -------------------------------------------------------------------------------- 1 | { 2 | "apiType": "stageMode", 3 | "buildOption": { 4 | "externalNativeOptions": { 5 | "path": "./src/main/cpp/CMakeLists.txt", 6 | "arguments": "", 7 | "cppFlags": "", 8 | } 9 | }, 10 | "buildOptionSet": [ 11 | { 12 | "name": "release", 13 | "arkOptions": { 14 | "obfuscation": { 15 | "ruleOptions": { 16 | "enable": false, 17 | "files": [ 18 | "./obfuscation-rules.txt" 19 | ] 20 | } 21 | } 22 | } 23 | }, 24 | ], 25 | "targets": [ 26 | { 27 | "name": "default" 28 | }, 29 | { 30 | "name": "ohosTest", 31 | } 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/hvigorfile.ts: -------------------------------------------------------------------------------- 1 | import { hapTasks } from '@ohos/hvigor-ohos-plugin'; 2 | 3 | export default { 4 | system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ 5 | plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ 6 | } 7 | -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/obfuscation-rules.txt: -------------------------------------------------------------------------------- 1 | # Define project specific obfuscation rules here. 2 | # You can include the obfuscation configuration files in the current module's build-profile.json5. 3 | # 4 | # For more details, see 5 | # https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 6 | 7 | # Obfuscation options: 8 | # -disable-obfuscation: disable all obfuscations 9 | # -enable-property-obfuscation: obfuscate the property names 10 | # -enable-toplevel-obfuscation: obfuscate the names in the global scope 11 | # -compact: remove unnecessary blank spaces and all line feeds 12 | # -remove-log: remove all console.* statements 13 | # -print-namecache: print the name cache that contains the mapping from the old names to new names 14 | # -apply-namecache: reuse the given cache file 15 | 16 | # Keep options: 17 | # -keep-property-name: specifies property names that you want to keep 18 | # -keep-global-name: specifies names that you want to keep in the global scope 19 | 20 | -enable-property-obfuscation 21 | -enable-toplevel-obfuscation 22 | -enable-filename-obfuscation 23 | -enable-export-obfuscation 24 | -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/main/cpp/PackageProvider.cpp: -------------------------------------------------------------------------------- 1 | #include "RNOH/PackageProvider.h" 2 | #include "BlurPackage.h" 3 | #include "GestureHandlerPackage.h" 4 | #include "AsyncStoragePackage.h" 5 | #include "generated/RNOHGeneratedPackage.h" 6 | #include "CookiesPackage.h" 7 | #include "SVGPackage.h" 8 | #include "SafeAreaViewPackage.h" 9 | #include "SliderPackage.h" 10 | #include "generated/rtn_network_utils/RNOH/generated/BaseRtnNetworkUtilsPackage.h" 11 | 12 | using namespace rnoh; 13 | 14 | std::vector> PackageProvider::getPackages(Package::Context ctx) { 15 | return { 16 | std::make_shared(ctx), std::make_shared(ctx), 17 | std::make_shared(ctx), std::make_shared(ctx), 18 | std::make_shared(ctx), std::make_shared(ctx), 19 | std::make_shared(ctx), std::make_shared(ctx), 20 | std::make_shared(ctx) 21 | }; 22 | } -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/main/ets/GeneratedPackage.ets: -------------------------------------------------------------------------------- 1 | import { RNPackage, TurboModulesFactory } from '@rnoh/react-native-openharmony/ts'; 2 | import type { 3 | TurboModule, 4 | TurboModuleContext 5 | } from '@rnoh/react-native-openharmony/ts'; 6 | import { TM } from "@rnoh/react-native-openharmony/generated/ts" 7 | import { NetworkUtilsModule } from './turbomodule/NetworkUtilsModule'; 8 | class GeneratedTurboModulesFactory extends TurboModulesFactory { 9 | createTurboModule(name: string): TurboModule | null { 10 | if (name === TM.RTNNativeNetworkUtils.NAME) { 11 | return new NetworkUtilsModule(this.ctx); 12 | } 13 | return null; 14 | } 15 | hasTurboModule(name: string): boolean { 16 | return name === TM.RTNNativeNetworkUtils.NAME; 17 | } 18 | } 19 | export class GeneratedPackage extends RNPackage { 20 | createTurboModulesFactory(ctx: TurboModuleContext): TurboModulesFactory { 21 | return new GeneratedTurboModulesFactory(ctx); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets: -------------------------------------------------------------------------------- 1 | import { hilog } from '@kit.PerformanceAnalysisKit'; 2 | import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; 3 | 4 | export default class EntryBackupAbility extends BackupExtensionAbility { 5 | async onBackup() { 6 | hilog.info(0x0000, 'testTag', 'onBackup ok'); 7 | } 8 | 9 | async onRestore(bundleVersion: BundleVersion) { 10 | hilog.info(0x0000, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); 11 | } 12 | } -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/main/ets/turbomodule/NetworkUtilsModule.ts: -------------------------------------------------------------------------------- 1 | import { TurboModule } from "@rnoh/react-native-openharmony/ts"; 2 | import { TM } from "@rnoh/react-native-openharmony/generated/ts"; 3 | import { rcp } from "@kit.RemoteCommunicationKit"; 4 | import { BusinessError } from "@kit.BasicServicesKit"; 5 | 6 | export class NetworkUtilsModule extends TurboModule implements TM.RTNNativeNetworkUtils.Spec { 7 | getRedirectLocation(url: string): Promise{ 8 | const request = new rcp.Request(url, "GET"); 9 | const session = rcp.createSession({ 10 | requestConfiguration: { 11 | transfer: { 12 | autoRedirect: false, 13 | }, 14 | }, 15 | }); 16 | return session.fetch(request).then((rep: rcp.Response) => { 17 | return rep.headers?.location; 18 | }).catch((_err: BusinessError) => { 19 | // console.error(`Response err: Code is ${err.code}, message is ${JSON.stringify(err)}`); 20 | return undefined; 21 | }); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/main/resources/base/element/color.json: -------------------------------------------------------------------------------- 1 | { 2 | "color": [ 3 | { 4 | "name": "start_window_background", 5 | "value": "#FFFFFF" 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/main/resources/base/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "module_desc", 5 | "value": "module description" 6 | }, 7 | { 8 | "name": "EntryAbility_desc", 9 | "value": "description" 10 | }, 11 | { 12 | "name": "EntryAbility_label", 13 | "value": "THU Info" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/main/resources/base/media/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/harmony/entry/src/main/resources/base/media/background.png -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/main/resources/base/media/foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/harmony/entry/src/main/resources/base/media/foreground.png -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/main/resources/base/media/layered_image.json: -------------------------------------------------------------------------------- 1 | { 2 | "layered-image": 3 | { 4 | "background" : "$media:background", 5 | "foreground" : "$media:foreground" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/main/resources/base/media/startIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/harmony/entry/src/main/resources/base/media/startIcon.png -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/main/resources/base/profile/backup_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "allowToBackupRestore": true 3 | } 4 | -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/main/resources/base/profile/main_pages.json: -------------------------------------------------------------------------------- 1 | { 2 | "src": [ 3 | "pages/Index" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/main/resources/dark/element/color.json: -------------------------------------------------------------------------------- 1 | { 2 | "color": [ 3 | { 4 | "name": "start_window_background", 5 | "value": "#000000" 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/main/resources/en_US/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "module_desc", 5 | "value": "module description" 6 | }, 7 | { 8 | "name": "EntryAbility_desc", 9 | "value": "description" 10 | }, 11 | { 12 | "name": "EntryAbility_label", 13 | "value": "THU Info" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/main/resources/phone-ldpi/media/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/harmony/entry/src/main/resources/phone-ldpi/media/icon.png -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/main/resources/phone-ldpi/media/icon_startwindow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/harmony/entry/src/main/resources/phone-ldpi/media/icon_startwindow.png -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/main/resources/phone-mdpi/media/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/harmony/entry/src/main/resources/phone-mdpi/media/icon.png -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/main/resources/phone-mdpi/media/icon_startwindow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/harmony/entry/src/main/resources/phone-mdpi/media/icon_startwindow.png -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/main/resources/phone-sdpi/media/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/harmony/entry/src/main/resources/phone-sdpi/media/icon.png -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/main/resources/phone-sdpi/media/icon_startwindow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/harmony/entry/src/main/resources/phone-sdpi/media/icon_startwindow.png -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/main/resources/phone-xldpi/media/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/harmony/entry/src/main/resources/phone-xldpi/media/icon.png -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/main/resources/phone-xldpi/media/icon_startwindow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/harmony/entry/src/main/resources/phone-xldpi/media/icon_startwindow.png -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/main/resources/phone-xxldpi/media/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/harmony/entry/src/main/resources/phone-xxldpi/media/icon.png -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/main/resources/phone-xxldpi/media/icon_startwindow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/harmony/entry/src/main/resources/phone-xxldpi/media/icon_startwindow.png -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/main/resources/phone-xxxldpi/media/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/harmony/entry/src/main/resources/phone-xxxldpi/media/icon.png -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/main/resources/phone-xxxldpi/media/icon_startwindow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/harmony/entry/src/main/resources/phone-xxxldpi/media/icon_startwindow.png -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/main/resources/zh_CN/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "module_desc", 5 | "value": "模块描述" 6 | }, 7 | { 8 | "name": "EntryAbility_desc", 9 | "value": "description" 10 | }, 11 | { 12 | "name": "EntryAbility_label", 13 | "value": "THU Info" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/mock/mock-config.json5: -------------------------------------------------------------------------------- 1 | { 2 | } 3 | -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/ohosTest/ets/test/List.test.ets: -------------------------------------------------------------------------------- 1 | import abilityTest from './Ability.test'; 2 | 3 | export default function testsuite() { 4 | abilityTest(); 5 | } -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/ohosTest/module.json5: -------------------------------------------------------------------------------- 1 | { 2 | "module": { 3 | "name": "entry_test", 4 | "type": "feature", 5 | "deviceTypes": [ 6 | "phone" 7 | ], 8 | "deliveryWithInstall": true, 9 | "installationFree": false 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/entry/src/test/List.test.ets: -------------------------------------------------------------------------------- 1 | import localUnitTest from './LocalUnit.test'; 2 | 3 | export default function testsuite() { 4 | localUnitTest(); 5 | } -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/hvigor/hvigor-config.json5: -------------------------------------------------------------------------------- 1 | { 2 | "modelVersion": "5.0.1", 3 | "dependencies": { 4 | "@ohos/hvigor": "5.13.1", 5 | "@ohos/hvigor-ohos-plugin": "5.13.1" 6 | }, 7 | "execution": { 8 | // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ 9 | // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ 10 | // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ 11 | // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ 12 | // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ 13 | }, 14 | "logging": { 15 | // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ 16 | }, 17 | "debugging": { 18 | // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ 19 | }, 20 | "nodeOptions": { 21 | // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ 22 | // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/hvigorfile.ts: -------------------------------------------------------------------------------- 1 | import { appTasks } from '@ohos/hvigor-ohos-plugin'; 2 | 3 | export default { 4 | system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ 5 | plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ 6 | } 7 | -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/oh-package-lock.json5: -------------------------------------------------------------------------------- 1 | { 2 | "meta": { 3 | "stableOrder": true 4 | }, 5 | "lockfileVersion": 3, 6 | "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", 7 | "specifiers": { 8 | "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", 9 | "@ohos/hypium@1.0.19": "@ohos/hypium@1.0.19" 10 | }, 11 | "packages": { 12 | "@ohos/hamock@1.0.0": { 13 | "name": "@ohos/hamock", 14 | "version": "1.0.0", 15 | "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", 16 | "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hamock/-/hamock-1.0.0.har", 17 | "registryType": "ohpm" 18 | }, 19 | "@ohos/hypium@1.0.19": { 20 | "name": "@ohos/hypium", 21 | "version": "1.0.19", 22 | "integrity": "sha512-cEjDgLFCm3cWZDeRXk7agBUkPqjWxUo6AQeiu0gEkb3J8ESqlduQLSIXeo3cCsm8U/asL7iKjF85ZyOuufAGSQ==", 23 | "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.19.har", 24 | "registryType": "ohpm" 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /apps/thu-info-app/harmony/oh-package.json5: -------------------------------------------------------------------------------- 1 | { 2 | "modelVersion": "5.0.1", 3 | "description": "Please describe the basic information.", 4 | "dependencies": { 5 | }, 6 | "devDependencies": { 7 | "@ohos/hypium": "1.0.19", 8 | "@ohos/hamock": "1.0.0" 9 | }, 10 | "overrides": { 11 | "@rnoh/react-native-openharmony": "../node_modules/@react-native-oh/react-native-harmony/react_native_openharmony.har" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /apps/thu-info-app/index.js: -------------------------------------------------------------------------------- 1 | import "react-native-gesture-handler"; 2 | import React from "react"; 3 | import {AppRegistry, Text} from "react-native"; 4 | import { polyfill as polyfillBase64 } from 'react-native-polyfill-globals/src/base64'; 5 | import { polyfill as polyfillEncoding } from 'react-native-polyfill-globals/src/encoding'; 6 | import { polyfill as polyfillReadableStream } from 'react-native-polyfill-globals/src/readable-stream'; 7 | import { polyfill as polyfillURL } from 'react-native-polyfill-globals/src/url'; 8 | import { polyfill as polyfillCrypto } from 'react-native-polyfill-globals/src/crypto'; 9 | polyfillBase64(); 10 | polyfillEncoding(); 11 | polyfillReadableStream(); 12 | polyfillURL(); 13 | polyfillCrypto(); 14 | import {name} from "./app.json"; 15 | import {App} from "./src/App"; 16 | import dayjs from "dayjs"; 17 | import customParseFormat from "dayjs/plugin/customParseFormat"; 18 | 19 | const Buffer = require('buffer/').Buffer; 20 | global.Buffer = Buffer; 21 | 22 | const moment = require("moment"); 23 | require("moment/locale/zh-cn"); 24 | moment.locale("zh-cn"); 25 | 26 | dayjs.extend(customParseFormat); 27 | 28 | const oldRender = Text.render; 29 | Text.render = function (props, ...extraArgs) { 30 | return oldRender.call( 31 | this, 32 | {...props, textBreakStrategy: "simple"}, 33 | ...extraArgs, 34 | ); 35 | }; 36 | 37 | AppRegistry.registerComponent(name, () => App); 38 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/.xcode.env: -------------------------------------------------------------------------------- 1 | export NODE_BINARY=$(command -v node) 2 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import React 3 | import React_RCTAppDelegate 4 | import ReactAppDependencyProvider 5 | 6 | @main 7 | class AppDelegate: UIResponder, UIApplicationDelegate { 8 | var window: UIWindow? 9 | 10 | var reactNativeDelegate: ReactNativeDelegate? 11 | var reactNativeFactory: RCTReactNativeFactory? 12 | 13 | func application( 14 | _ application: UIApplication, 15 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil 16 | ) -> Bool { 17 | let delegate = ReactNativeDelegate() 18 | let factory = RCTReactNativeFactory(delegate: delegate) 19 | delegate.dependencyProvider = RCTAppDependencyProvider() 20 | 21 | reactNativeDelegate = delegate 22 | reactNativeFactory = factory 23 | 24 | window = UIWindow(frame: UIScreen.main.bounds) 25 | 26 | factory.startReactNative( 27 | withModuleName: "thu_info", 28 | in: window, 29 | launchOptions: launchOptions 30 | ) 31 | 32 | return true 33 | } 34 | } 35 | 36 | class ReactNativeDelegate: RCTDefaultReactNativeFactoryDelegate { 37 | override func sourceURL(for bridge: RCTBridge) -> URL? { 38 | self.bundleURL() 39 | } 40 | 41 | override func bundleURL() -> URL? { 42 | #if DEBUG 43 | RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index") 44 | #else 45 | Bundle.main.url(forResource: "main", withExtension: "jsbundle") 46 | #endif 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/Podfile: -------------------------------------------------------------------------------- 1 | inhibit_all_warnings! 2 | 3 | require_relative '../../../node_modules/react-native-permissions/scripts/setup' 4 | 5 | # Resolve react_native_pods.rb with node to allow for hoisting 6 | require Pod::Executable.execute_command('node', ['-p', 7 | 'require.resolve( 8 | "react-native/scripts/react_native_pods.rb", 9 | {paths: [process.argv[1]]}, 10 | )', __dir__]).strip 11 | 12 | platform :ios, min_ios_version_supported 13 | prepare_react_native_project! 14 | 15 | setup_permissions([ 16 | 'PhotoLibrary', 17 | 'PhotoLibraryAddOnly', 18 | ]) 19 | 20 | linkage = ENV['USE_FRAMEWORKS'] 21 | if linkage != nil 22 | Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green 23 | use_frameworks! :linkage => linkage.to_sym 24 | end 25 | 26 | target 'thu_info' do 27 | config = use_native_modules! 28 | 29 | use_react_native!( 30 | privacy_file_aggregation_enabled: false, 31 | new_arch_enabled: false, 32 | :path => config[:reactNativePath], 33 | # An absolute path to your application root. 34 | :app_path => "#{Pod::Config.instance.installation_root}/.." 35 | ) 36 | 37 | post_install do |installer| 38 | # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202 39 | react_native_post_install( 40 | installer, 41 | config[:reactNativePath], 42 | :mac_catalyst_enabled => false, 43 | :ccache_enabled => true 44 | ) 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* 2 | InfoPlist.strings 3 | thu_info 4 | 5 | Created by 钱钱厚德 on 2020/8/5. 6 | 7 | */ 8 | 9 | NSPhotoLibraryUsageDescription = "We only use your data of camara roll to save schedule to your phone."; 10 | 11 | NSPhotoLibraryAddUsageDescription = "We only use your data of camara roll to save schedule to your phone."; 12 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/fastlane/Appfile: -------------------------------------------------------------------------------- 1 | app_identifier("org.reactjs.native.example.thu-info") # The bundle identifier of your app 2 | apple_id("h99652@126.com") # Your Apple Developer Portal username 3 | 4 | itc_team_id("121970572") # App Store Connect Team ID 5 | team_id("F3D2L9HSSK") # Developer Portal Team ID 6 | 7 | # For more information about the Appfile, see: 8 | # https://docs.fastlane.tools/advanced/#appfile 9 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/fastlane/Deliverfile: -------------------------------------------------------------------------------- 1 | # The Deliverfile allows you to store various App Store Connect metadata 2 | # For more information, check out the docs 3 | # https://docs.fastlane.tools/actions/deliver/ 4 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/fastlane/Fastfile: -------------------------------------------------------------------------------- 1 | # This file contains the fastlane.tools configuration 2 | # You can find the documentation at https://docs.fastlane.tools 3 | # 4 | # For a list of all available actions, check out 5 | # 6 | # https://docs.fastlane.tools/actions 7 | # 8 | # For a list of all available plugins, check out 9 | # 10 | # https://docs.fastlane.tools/plugins/available-plugins 11 | # 12 | 13 | # Uncomment the line if you want fastlane to automatically update itself 14 | # update_fastlane 15 | 16 | default_platform(:ios) 17 | # git_url("git@github.com:Ashitemaru/THUInfo-certificates.git") 18 | 19 | platform :ios do 20 | desc "Push a new release build to the App Store" 21 | lane :release do 22 | 23 | end 24 | 25 | lane :beta do 26 | increment_build_number( 27 | build_number: ENV["GITHUB_RUN_NUMBER"], 28 | xcodeproj: "thu_info.xcodeproj" 29 | ) 30 | 31 | setup_ci 32 | sync_code_signing 33 | match(type: "appstore", git_basic_authorization: ENV["MATCH_PASSWORD"]) 34 | build_app(derived_data_path: "./DerivedData") 35 | 36 | api_key = app_store_connect_api_key( 37 | key_id: ENV["APPSTORE_API_PRIVATE_KEY_ID"], 38 | issuer_id: ENV["APPSTORE_ISSUER_ID"], 39 | key_content: ENV["APPSTORE_API_PRIVATE_KEY"], 40 | duration: 1200, 41 | in_house: false 42 | ) 43 | upload_to_testflight(api_key: api_key, skip_waiting_for_build_processing: true) 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/fastlane/Matchfile: -------------------------------------------------------------------------------- 1 | git_url("git@github.com:Ashitemaru/THUInfo-certificates.git") 2 | 3 | storage_mode("git") 4 | 5 | type("appstore") # The default type, can be: appstore, adhoc, enterprise or development 6 | 7 | # app_identifier(["tools.fastlane.app", "tools.fastlane.app2"]) 8 | # username("user@fastlane.tools") # Your Apple Developer Portal username 9 | 10 | # For all available options run `fastlane match --help` 11 | # Remove the # in the beginning of the line to enable the other options 12 | 13 | # The docs are available on https://docs.fastlane.tools/actions/match 14 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/fastlane/README.md: -------------------------------------------------------------------------------- 1 | fastlane documentation 2 | ---- 3 | 4 | # Installation 5 | 6 | Make sure you have the latest version of the Xcode command line tools installed: 7 | 8 | ```sh 9 | xcode-select --install 10 | ``` 11 | 12 | For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane) 13 | 14 | # Available Actions 15 | 16 | ## iOS 17 | 18 | ### ios release 19 | 20 | ```sh 21 | [bundle exec] fastlane ios release 22 | ``` 23 | 24 | Push a new release build to the App Store 25 | 26 | ### ios beta 27 | 28 | ```sh 29 | [bundle exec] fastlane ios beta 30 | ``` 31 | 32 | 33 | 34 | ---- 35 | 36 | This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run. 37 | 38 | More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools). 39 | 40 | The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools). 41 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/fastlane/metadata/copyright.txt: -------------------------------------------------------------------------------- 1 | 2020 UNIDY 2 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/fastlane/metadata/primary_category.txt: -------------------------------------------------------------------------------- 1 | EDUCATION 2 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/fastlane/metadata/primary_first_sub_category.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/fastlane/metadata/primary_second_sub_category.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/fastlane/metadata/review_information/demo_password.txt: -------------------------------------------------------------------------------- 1 | 8888 2 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/fastlane/metadata/review_information/demo_user.txt: -------------------------------------------------------------------------------- 1 | 8888 2 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/fastlane/metadata/review_information/email_address.txt: -------------------------------------------------------------------------------- 1 | qhd19@mails.tsinghua.edu.cn 2 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/fastlane/metadata/review_information/first_name.txt: -------------------------------------------------------------------------------- 1 | 厚德 2 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/fastlane/metadata/review_information/last_name.txt: -------------------------------------------------------------------------------- 1 | 钱 2 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/fastlane/metadata/review_information/notes.txt: -------------------------------------------------------------------------------- 1 | 该账户为测试账号,可以使用大部分APP功能,但是不能使用类似电费充值等功能。 2 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/fastlane/metadata/review_information/phone_number.txt: -------------------------------------------------------------------------------- 1 | +86 15301422111 2 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/fastlane/metadata/secondary_category.txt: -------------------------------------------------------------------------------- 1 | UTILITIES 2 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/fastlane/metadata/secondary_first_sub_category.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/fastlane/metadata/secondary_second_sub_category.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/fastlane/metadata/zh-Hans/apple_tv_privacy_policy.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/fastlane/metadata/zh-Hans/description.txt: -------------------------------------------------------------------------------- 1 | 清华大学Info网站一站式访问APP,整合Info零碎信息,提供更好的用户体验。 2 | 3 | - 查询成绩/体测成绩 4 | 5 | 不需要Info的繁琐登陆环节,APP主页点击即可查询成绩,并提供每学期GPA小结与总GPA。同时提供新旧绩点切换,必限任与必限切换以及自选成绩单功能。 6 | 7 | - 教学评估 8 | 9 | 厌倦与不方便的教学评估网站?本APP提供更优良的用户界面,以及一键满分功能。 10 | 11 | - 教室资源查询 12 | 13 | 想自习但是不知道哪个教室空着?主页直接查询各个教室使用情况,让你最快速度找到合适的空教室。 14 | (老师拖堂不在本APP负责范围内) 15 | 16 | - 图书馆查询/预约 17 | 18 | 快速查找图书馆空位,并且提供一键预约功能。设置界面之中可以查询所有图书馆预约记录。 19 | 20 | - 消费查询/学生卡快速挂失 21 | 22 | 不知道卡里面还有多少钱?直接主页查询,显示近日所有消费记录,统计总消费,显示当前余额。再也不要在去食堂的时候纠结要不要拐圈存机啦! 23 | (由于学校数据问题,余额偏差还请设置界面手动设置) 24 | 25 | - 卫生成绩 26 | 27 | 支持一键查询寝室卫生成绩。 28 | 29 | - Info新闻集合查看 30 | 31 | 将办公通知、教务公告、科研通知、海报集合于一个界面上显示,第一时间查看学校通知。 32 | 33 | - 课程表/计划功能 34 | 35 | 登陆即导入所有课程表,支持二级课程表。同时为防止导入失误,支持手动修改课程表。也可以手动添加自定义计划。如果想要把课程表保存,也可以一键保存课程表到相册。 36 | 37 | 由于开发者水平有限,本APP还会存在缺陷,还请同学们多多在反馈窗口向我们提出意见! 38 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/fastlane/metadata/zh-Hans/keywords.txt: -------------------------------------------------------------------------------- 1 | THU, thu, info, Info, 清华, 信息门户, thu_info, thu info, THU Info 2 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/fastlane/metadata/zh-Hans/marketing_url.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/fastlane/metadata/zh-Hans/name.txt: -------------------------------------------------------------------------------- 1 | THU Info 2 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/fastlane/metadata/zh-Hans/privacy_url.txt: -------------------------------------------------------------------------------- 1 | https://thuinfo.net/privacy 2 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/fastlane/metadata/zh-Hans/promotional_text.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/fastlane/metadata/zh-Hans/release_notes.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/fastlane/metadata/zh-Hans/subtitle.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/fastlane/metadata/zh-Hans/support_url.txt: -------------------------------------------------------------------------------- 1 | https://www.thuinfo.net 2 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/100.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/1024.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/114.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/120.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/128.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/144.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/152.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/16.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/167.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/172.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/172.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/180.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/196.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/196.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/20.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/216.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/216.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/256.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/29.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/32.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/40.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/48.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/50.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/512.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/55.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/57.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/58.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/60.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/64.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/72.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/76.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/80.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/87.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/88.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/apps/thu-info-app/ios/thu_info/Images.xcassets/AppIcon.appiconset/88.png -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info": { 3 | "version": 1, 4 | "author": "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/PrivacyInfo.xcprivacy: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSPrivacyCollectedDataTypes 6 | 7 | 8 | NSPrivacyAccessedAPITypes 9 | 10 | 11 | NSPrivacyAccessedAPIType 12 | NSPrivacyAccessedAPICategoryFileTimestamp 13 | NSPrivacyAccessedAPITypeReasons 14 | 15 | C617.1 16 | 17 | 18 | 19 | NSPrivacyAccessedAPIType 20 | NSPrivacyAccessedAPICategoryUserDefaults 21 | NSPrivacyAccessedAPITypeReasons 22 | 23 | CA92.1 24 | 25 | 26 | 27 | NSPrivacyAccessedAPIType 28 | NSPrivacyAccessedAPICategorySystemBootTime 29 | NSPrivacyAccessedAPITypeReasons 30 | 31 | 35F9.1 32 | 33 | 34 | 35 | NSPrivacyTracking 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/thu_info/zh-Hans.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UILabel"; text = "Powered by React Native"; ObjectID = "8ie-xW-0ye"; */ 3 | "8ie-xW-0ye.text" = "Powered by React Native"; 4 | 5 | /* Class = "UILabel"; text = "THU Info"; ObjectID = "kId-c2-rCX"; */ 6 | "kId-c2-rCX.text" = "THU Info"; 7 | -------------------------------------------------------------------------------- /apps/thu-info-app/ios/zh-Hans.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* 2 | InfoPlist.strings 3 | thu_info 4 | 5 | Created by 钱钱厚德 on 2020/8/5. 6 | 7 | */ 8 | 9 | 10 | NSPhotoLibraryUsageDescription = "我们只会在将课程表存储到照片图库的时候使用您的照片数据。"; 11 | 12 | NSPhotoLibraryAddUsageDescription = "我们只会在将课程表存储到照片图库的时候使用您的照片数据。"; 13 | -------------------------------------------------------------------------------- /apps/thu-info-app/jest.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preset": "react-native", 3 | "setupFiles": [ 4 | "/.jestsetup.js" 5 | ], 6 | "transformIgnorePatterns": [ 7 | "node_modules/(?!(react-native|react-redux|redux-persist|react-native-gesture-handler|redux-persist-keychain-storage|react-native-keychain|react-native-markdown-display|react-native-sse|react-native-version-number|@react-native-cookies/cookies|@react-native-community/blur|react-native-image-zoom-viewer|react-native-image-pan-zoom|react-native-webview|react-native-easy-grid|react-native-view-shot|@react-native-community/cameraroll|@react-native|@react-native-async-storage/async-storage|react-native-pdf|react-native-blob-util|react-native-permissions|react-native-qrcode-svg|react-native-confirmation-code-field|react-native-wheel-scrollview-picker|react-native-safearea-height|@react-navigation|react-native-device-time-format|uuid)/)" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /apps/thu-info-app/metro.config.js: -------------------------------------------------------------------------------- 1 | const {getDefaultConfig, mergeConfig} = require("@react-native/metro-config"); 2 | const {createHarmonyMetroConfig} = require("@react-native-oh/react-native-harmony/metro.config"); 3 | const path = require("path"); 4 | 5 | // Find the project and workspace directories 6 | const projectRoot = __dirname; 7 | // This can be replaced with `find-yarn-workspace-root` 8 | const workspaceRoot = path.resolve(projectRoot, "../.."); 9 | 10 | /** 11 | * Metro configuration 12 | * https://reactnative.dev/docs/metro 13 | * 14 | * @type {import('@react-native/metro-config').MetroConfig} 15 | */ 16 | const config = { 17 | watchFolders: [workspaceRoot], 18 | resolver: { 19 | nodeModulesPaths: [ 20 | path.resolve(projectRoot, "node_modules"), 21 | path.resolve(workspaceRoot, "node_modules"), 22 | ], 23 | }, 24 | server: { 25 | enhanceMiddleware: (middleware) => { 26 | return (req, res, next) => { 27 | // When an asset is imported outside the project root, it has wrong path on Android 28 | // So we fix the path to correct one 29 | if (/\/assets\/.+\.png\?platform=android.+$/.test(req.url)) { 30 | req.url = `/assets/../..${req.url}`; 31 | } 32 | 33 | return middleware(req, res, next); 34 | }; 35 | }, 36 | }, 37 | }; 38 | 39 | module.exports = mergeConfig(getDefaultConfig(__dirname), createHarmonyMetroConfig({ 40 | reactNativeHarmonyPackageName: "@react-native-oh/react-native-harmony", 41 | }), config); 42 | -------------------------------------------------------------------------------- /apps/thu-info-app/patches/react-native-safearea-height+1.0.8.patch: -------------------------------------------------------------------------------- 1 | diff --git a/node_modules/react-native-safearea-height/index.js b/node_modules/react-native-safearea-height/index.js 2 | index 5c0076e..b1e0ca5 100644 3 | --- a/node_modules/react-native-safearea-height/index.js 4 | +++ b/node_modules/react-native-safearea-height/index.js 5 | @@ -136,6 +136,7 @@ export function getStatusBarHeight(skipAndroid) { 6 | return Platform.select({ 7 | ios: statusBarHeight, 8 | android: skipAndroid ? 0 : StatusBar.currentHeight, 9 | + harmony: StatusBar.currentHeight, 10 | default: 0, 11 | }); 12 | } 13 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/colors/dark.ts: -------------------------------------------------------------------------------- 1 | import {ColorTheme} from "../themes/themes"; 2 | 3 | export const colorDark: ColorTheme = { 4 | primaryLight: "#AB55C4", 5 | primary: "#7A2694", 6 | primaryDark: "#3E0558", 7 | accent: "#023EA2", 8 | text: "#CCCCCC", 9 | contentBackground: "#222222", 10 | themeBackground: "#000000", 11 | inputBorder: "#333333", 12 | transparent: "#00000000", 13 | 14 | // to be decided 15 | mainTheme: "#672AD7", 16 | fontB0: "#FFFFFF", 17 | fontB1: "#CCCCCC", 18 | fontB2: "#999999", 19 | fontB3: "#666666", 20 | statusNormal: "", //TODO 21 | statusDisabled: {rgb: "#999999", alpha: 0.3}, 22 | statusWarning: "#FF3B30", 23 | statusWarningOpacity: "#FF3B3019", 24 | statusError: "#DF1515", 25 | themeGreen: "#34C759", 26 | themeBlue: "#007AFF", 27 | themeTransparentPurple: "#8B55E46A", 28 | themePurple: "#8B55E4", 29 | themeDarkPurple: "#6300BB", 30 | themeLightPurple: "#A883E8", 31 | themeDarkGrey: "#B5B5B5", 32 | themeGrey: "#D6D3DB", 33 | themeLightGrey: "#E9E9E9", 34 | themeTransparentGrey: "#88888822", 35 | themeGold: "#FFCC00", 36 | courseItemColorList: [ 37 | "#00a6f2", 38 | "#3cb3c8", 39 | "#fc6b50", 40 | "#f067bb", 41 | "#ef5b75", 42 | "#7d7aea", 43 | "#bf73e5", 44 | "#ff9900", 45 | "#eebe00", 46 | "#5b8eff", 47 | "#139161", 48 | ], 49 | }; 50 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/colors/light.ts: -------------------------------------------------------------------------------- 1 | import {ColorTheme} from "../themes/themes"; 2 | 3 | export const colorLight: ColorTheme = { 4 | primaryLight: "#9E64FF", 5 | primary: "#671E7F", 6 | primaryDark: "#380052", 7 | accent: "#2979FF", 8 | text: "#000000", 9 | contentBackground: "#FFFFFF", 10 | themeBackground: "#F6F6F6", 11 | inputBorder: "#CCCCCC", 12 | transparent: "#00000000", 13 | 14 | mainTheme: "#B791F0", 15 | fontB0: "#000000", 16 | fontB1: "#333333", 17 | fontB2: "#666666", 18 | fontB3: "#999999", 19 | statusNormal: "", //TODO 20 | statusDisabled: {rgb: "#999999", alpha: 0.3}, 21 | statusWarning: "#FF3B30", 22 | statusWarningOpacity: "#FF3B3019", 23 | statusError: "#DF1515", 24 | themeGreen: "#34C759", 25 | themeBlue: "#007AFF", 26 | themeTransparentPurple: "#8B55E46A", 27 | themePurple: "#8B55E4", 28 | themeDarkPurple: "#6300BB", 29 | themeLightPurple: "#A883E8", 30 | themeDarkGrey: "#B5B5B5", 31 | themeGrey: "#D6D3DB", 32 | themeLightGrey: "#E9E9E9", 33 | themeTransparentGrey: "#88888822", 34 | themeGold: "#FFCC00", 35 | courseItemColorList: [ 36 | "#00a6f2", 37 | "#3cb3c8", 38 | "#fc6b50", 39 | "#f067bb", 40 | "#ef5b75", 41 | "#7d7aea", 42 | "#bf73e5", 43 | "#ff9900", 44 | "#eebe00", 45 | "#5b8eff", 46 | "#139161", 47 | ], 48 | }; 49 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/colors/pkuDark.ts: -------------------------------------------------------------------------------- 1 | import {ColorTheme} from "../themes/themes"; 2 | 3 | export const colorPkuDark: ColorTheme = { 4 | primaryLight: "#8B0016", 5 | primary: "#8B0012", 6 | primaryDark: "#700005", 7 | accent: "#004F3E", 8 | text: "#CCCCCC", 9 | contentBackground: "#222222", 10 | themeBackground: "#000000", 11 | inputBorder: "#333333", 12 | transparent: "#00000000", 13 | 14 | mainTheme: "#B81E28", 15 | fontB0: "#FFFFFF", 16 | fontB1: "#CCCCCC", 17 | fontB2: "#999999", 18 | fontB3: "#666666", 19 | statusNormal: "", //TODO 20 | statusDisabled: {rgb: "#999999", alpha: 0.3}, 21 | statusWarning: "#FF3B30", 22 | statusWarningOpacity: "#FF3B3019", 23 | statusError: "#DF1515", 24 | themeGreen: "#34C759", 25 | themeBlue: "#007AFF", 26 | themeTransparentPurple: "#7B00006A", 27 | themePurple: "#AB0000", 28 | themeDarkPurple: "#9B0000", 29 | themeLightPurple: "#BB0000", 30 | themeDarkGrey: "#B5B5B5", 31 | themeGrey: "#D6D3DB", 32 | themeLightGrey: "#E9E9E9", 33 | themeTransparentGrey: "#AA888822", 34 | themeGold: "#FFCC00", 35 | courseItemColorList: [ 36 | "#00a6f2", 37 | "#3cb3c8", 38 | "#fc6b50", 39 | "#f067bb", 40 | "#ef5b75", 41 | "#7d7aea", 42 | "#bf73e5", 43 | "#ff9900", 44 | "#eebe00", 45 | "#5b8eff", 46 | "#139161", 47 | ], 48 | }; 49 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/colors/pkuLight.ts: -------------------------------------------------------------------------------- 1 | import {ColorTheme} from "../themes/themes"; 2 | 3 | export const colorPkuLight: ColorTheme = { 4 | primaryLight: "#8B0016", 5 | primary: "#8B0012", 6 | primaryDark: "#700005", 7 | accent: "#008B78", 8 | text: "#000000", 9 | contentBackground: "#FFFFFF", 10 | themeBackground: "#F6F6F6", 11 | inputBorder: "#CCCCCC", 12 | transparent: "#00000000", 13 | 14 | mainTheme: "#C26064", 15 | fontB0: "#000000", 16 | fontB1: "#333333", 17 | fontB2: "#666666", 18 | fontB3: "#999999", 19 | statusNormal: "", //TODO 20 | statusDisabled: {rgb: "#999999", alpha: 0.3}, 21 | statusWarning: "#FF3B30", 22 | statusWarningOpacity: "#FF3B3019", 23 | statusError: "#DF1515", 24 | themeGreen: "#34C759", 25 | themeBlue: "#007AFF", 26 | themeTransparentPurple: "#9B00006A", 27 | themePurple: "#9B0000", 28 | themeDarkPurple: "#9B0000", 29 | themeLightPurple: "#BB0000", 30 | themeDarkGrey: "#B5B5B5", 31 | themeGrey: "#D6D3DB", 32 | themeLightGrey: "#E9E9E9", 33 | themeTransparentGrey: "#AA888822", 34 | themeGold: "#FFCC00", 35 | courseItemColorList: [ 36 | "#00a6f2", 37 | "#3cb3c8", 38 | "#fc6b50", 39 | "#f067bb", 40 | "#ef5b75", 41 | "#7d7aea", 42 | "#bf73e5", 43 | "#ff9900", 44 | "#eebe00", 45 | "#5b8eff", 46 | "#139161", 47 | ], 48 | }; 49 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconAdd.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const {colors} = themes(themeName); 8 | return ( 9 | 10 | 18 | 27 | 36 | 37 | ); 38 | }; 39 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconBankPayment.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width?: number; height?: number}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | return ( 9 | 10 | 17 | 21 | 28 | 35 | 36 | ); 37 | }; 38 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconBoard.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path, Rect} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const {colors} = themes(themeName); 8 | return ( 9 | 10 | 21 | 27 | 33 | 39 | 45 | 46 | ); 47 | }; 48 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconBook.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const {colors} = themes(themeName); 8 | return ( 9 | 10 | 17 | 21 | 28 | 29 | ); 30 | }; 31 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconCalendar.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path, Rect} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const {colors} = themes(themeName); 8 | 9 | return ( 10 | 11 | 12 | 23 | 30 | {Array.from(new Array(9), (_, k) => { 31 | const i = Math.floor(k / 3) + 1, 32 | j = k % 3; 33 | return ( 34 | 42 | ); 43 | })} 44 | 45 | ); 46 | }; 47 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconCheck.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | return ( 9 | 10 | 17 | 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconCheckGrey.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | return ( 9 | 10 | 17 | 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconConfig.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const {colors} = themes(themeName); 8 | return ( 9 | 10 | 17 | 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconCopy.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({ width, height, color }: { width: number; height: number; color?: string }) => { 6 | if (!color) { 7 | const themeName = useColorScheme(); 8 | const { colors } = themes(themeName); 9 | color = colors.fontB1; 10 | } 11 | return ( 12 | 13 | 22 | 31 | 32 | ); 33 | }; 34 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconCr.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | return ( 9 | 10 | 16 | 23 | 31 | 32 | ); 33 | }; 34 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconDisable.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({size}: {size: number}) => { 6 | const themeName = useColorScheme(); 7 | const {colors} = themes(themeName); 8 | return ( 9 | 10 | 14 | 15 | ); 16 | }; 17 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconDorm.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | return ( 9 | 10 | 17 | 25 | 32 | 33 | ); 34 | }; 35 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconDormScore.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width?: number; height?: number}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | return ( 9 | 10 | 18 | 25 | 32 | 33 | ); 34 | }; 35 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconDown.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const {colors} = themes(themeName); 8 | return ( 9 | 10 | 17 | 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconDownload.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | return ( 9 | 10 | 17 | 24 | 25 | ); 26 | }; 27 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconDrink.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Line, Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const {colors} = themes(themeName); 8 | return ( 9 | 10 | 19 | 24 | 30 | 36 | 37 | ); 38 | }; 39 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconDropdown.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | 3 | export default ({ 4 | width, 5 | height, 6 | color, 7 | }: { 8 | width: number; 9 | height: number; 10 | color: string; 11 | }) => { 12 | return ( 13 | 14 | 21 | 22 | ); 23 | }; 24 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconEleRecharge.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width?: number; height?: number}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | return ( 9 | 10 | 16 | 23 | 24 | ); 25 | }; 26 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconEvaluation.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | return ( 9 | 10 | 17 | 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconExchange.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | return ( 9 | 10 | 17 | 24 | 31 | 38 | 39 | ); 40 | }; 41 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconExclamation.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | return ( 9 | 10 | 19 | 25 | 31 | 32 | ); 33 | }; 34 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconExpenditure.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path, Rect} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width?: number; height?: number}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | return ( 9 | 10 | 17 | 29 | 36 | 37 | ); 38 | }; 39 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconFinance.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | return ( 9 | 10 | 17 | 24 | 25 | ); 26 | }; 27 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconFormStar.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({full}: {full: boolean}) => { 6 | const themeName = useColorScheme(); 7 | const {colors} = themes(themeName); 8 | return ( 9 | 10 | 17 | 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconHamburger.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path, Rect} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const {colors} = themes(themeName); 8 | return ( 9 | 10 | 20 | 31 | 38 | 39 | ); 40 | }; 41 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconHamburgerMenu.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const {colors} = themes(themeName); 8 | return ( 9 | 10 | 17 | 24 | 31 | 32 | ); 33 | }; 34 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconHistory.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | return ( 9 | 10 | 16 | 22 | 28 | 29 | ); 30 | }; 31 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconHomeTab.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({size, active}: {size: number; active: boolean}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | const color = active ? theme.colors.mainTheme : theme.colors.transparent; 9 | return ( 10 | 11 | 12 | 19 | 26 | 32 | 33 | ); 34 | }; 35 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconInvoice.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width?: number; height?: number}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | return ( 9 | 10 | 11 | 18 | 25 | 26 | ); 27 | }; 28 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconLeft.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | return ( 9 | 10 | 17 | 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconLibRoom.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path, Rect} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width?: number; height?: number}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | return ( 9 | 10 | 21 | 28 | 36 | 37 | ); 38 | }; 39 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconLibrary.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width?: number; height?: number}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | return ( 9 | 10 | 17 | 24 | 25 | ); 26 | }; 27 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconLocal.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | return ( 9 | 10 | 16 | 22 | 23 | ); 24 | }; 25 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconLock.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path, Rect} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | return ( 9 | 10 | 20 | 27 | 28 | ); 29 | }; 30 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconLoseCard.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path, Rect} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | return ( 9 | 10 | 20 | 26 | 33 | 34 | ); 35 | }; 36 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconMinus.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const {colors} = themes(themeName); 8 | return ( 9 | 10 | 18 | 27 | 28 | ); 29 | }; 30 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconNewsTab.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({size, active}: {size: number; active: boolean}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | const color = active ? theme.colors.mainTheme : theme.colors.transparent; 9 | return ( 10 | 11 | 19 | 26 | 27 | ); 28 | }; 29 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconNoodles.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const {colors} = themes(themeName); 8 | return ( 9 | 10 | 20 | 27 | 34 | 41 | 48 | 55 | 56 | ); 57 | }; 58 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconNotSelected.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const {colors} = themes(themeName); 8 | return ( 9 | 10 | 15 | 16 | ); 17 | }; 18 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconPeek.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const {colors} = themes(themeName); 8 | return ( 9 | 10 | 16 | 23 | 30 | 31 | ); 32 | }; 33 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconPerson.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | return ( 9 | 10 | 17 | 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconPhysicalExam.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | return ( 9 | 10 | 16 | 17 | ); 18 | }; 19 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconPot.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const {colors} = themes(themeName); 8 | return ( 9 | 10 | 17 | 25 | 32 | 39 | 46 | 47 | ); 48 | }; 49 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconRefresh.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({ 6 | width, 7 | height, 8 | color, 9 | }: { 10 | width: number; 11 | height: number; 12 | color?: string; 13 | }) => { 14 | if (!color) { 15 | const themeName = useColorScheme(); 16 | const {colors} = themes(themeName); 17 | color = colors.fontB1; 18 | } 19 | return ( 20 | 21 | 28 | 29 | ); 30 | }; 31 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconReport.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import themes from "../themes/themes"; 3 | import {useColorScheme} from "react-native"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | return ( 9 | 10 | 17 | 23 | 31 | 32 | ); 33 | }; 34 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconReserve.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import themes from "../themes/themes"; 3 | import {useColorScheme} from "react-native"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | return ( 9 | 10 | 17 | 24 | 25 | ); 26 | }; 27 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconRice.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const {colors} = themes(themeName); 8 | return ( 9 | 10 | 16 | 21 | 26 | 32 | 38 | 45 | 46 | ); 47 | }; 48 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconRight.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | return ( 9 | 10 | 17 | 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconScheduleTab.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path, Rect} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({size, active}: {size: number; active: boolean}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | const color = active ? theme.colors.mainTheme : theme.colors.transparent; 9 | return ( 10 | 11 | 23 | 29 | 30 | ); 31 | }; 32 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconSearch.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const {colors} = themes(themeName); 8 | return ( 9 | 10 | 16 | 23 | 24 | ); 25 | }; 26 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconSelected.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const {colors} = themes(themeName); 8 | return ( 9 | 10 | 15 | 23 | 24 | ); 25 | }; 26 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconSend.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | 3 | export default ({width, height, color}: {width: number; height: number; color: string}) => { 4 | return ( 5 | 6 | 13 | 20 | 21 | ); 22 | }; 23 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconSettingsTab.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({size, active}: {size: number; active: boolean}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | const color = active ? theme.colors.mainTheme : theme.colors.transparent; 9 | return ( 10 | 11 | 18 | 25 | 26 | ); 27 | }; 28 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconShare.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | return ( 9 | 10 | 17 | 24 | 25 | ); 26 | }; 27 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconShopping.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Circle, Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const {colors} = themes(themeName); 8 | return ( 9 | 10 | 17 | 26 | 35 | 36 | ); 37 | }; 38 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconSocket.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | 3 | export default ({size, color}: {size: number; color: string}) => { 4 | return ( 5 | 6 | 7 | 13 | 20 | 27 | 34 | 35 | ); 36 | }; 37 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconSports.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width?: number; height?: number}) => { 6 | const themeName = useColorScheme(); 7 | const {colors} = themes(themeName); 8 | return ( 9 | 10 | 18 | 27 | 36 | 37 | ); 38 | }; 39 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconStar.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const {colors} = themes(themeName); 8 | return ( 9 | 10 | 16 | 17 | ); 18 | }; 19 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconStarActive.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const {colors} = themes(themeName); 8 | return ( 9 | 10 | 17 | 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconSubscriptionLogo.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const {colors} = themes(themeName); 8 | return ( 9 | 10 | 17 | 24 | 31 | 32 | ); 33 | }; 34 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconSuccess.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const {colors} = themes(themeName); 8 | return ( 9 | 10 | 16 | 21 | 22 | ); 23 | }; 24 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconTime.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const {colors} = themes(themeName); 8 | return ( 9 | 10 | 18 | 27 | 28 | ); 29 | }; 30 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconTrademark.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Circle, Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width: number; height: number}) => { 6 | const themeName = useColorScheme(); 7 | const {colors} = themes(themeName); 8 | return ( 9 | 10 | 17 | 24 | 31 | 32 | ); 33 | }; 34 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconWasher.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path, Rect, Circle} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width?: number; height?: number}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | return ( 9 | 10 | 19 | 25 | 26 | 27 | 35 | 36 | ); 37 | }; 38 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/icons/IconWater.tsx: -------------------------------------------------------------------------------- 1 | import Svg, {Path} from "react-native-svg"; 2 | import {useColorScheme} from "react-native"; 3 | import themes from "../themes/themes"; 4 | 5 | export default ({width, height}: {width?: number; height?: number}) => { 6 | const themeName = useColorScheme(); 7 | const theme = themes(themeName); 8 | return ( 9 | 10 | 17 | 24 | 32 | 33 | ); 34 | }; 35 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/assets/themes/themes.ts: -------------------------------------------------------------------------------- 1 | import {colorLight} from "../colors/light"; 2 | import {colorDark} from "../colors/dark"; 3 | import {currState} from "../../redux/store"; 4 | import {enableEasterEgg} from "../../utils/easterEgg"; 5 | import {colorPkuDark} from "../colors/pkuDark"; 6 | import {colorPkuLight} from "../colors/pkuLight"; 7 | 8 | export interface ColorTheme { 9 | primaryLight: string; 10 | primary: string; 11 | primaryDark: string; 12 | accent: string; 13 | text: string; 14 | contentBackground: string; 15 | themeBackground: string; 16 | inputBorder: string; 17 | transparent: string; 18 | 19 | mainTheme: string; 20 | fontB0: string; 21 | fontB1: string; 22 | fontB2: string; 23 | fontB3: string; 24 | statusNormal: string; 25 | statusDisabled: {rgb: string; alpha: number}; 26 | statusWarning: string; 27 | statusWarningOpacity: string; 28 | statusError: string; 29 | themeGreen: string; 30 | themeBlue: string; 31 | themeTransparentPurple: string; 32 | themePurple: string; 33 | themeDarkPurple: string; 34 | themeLightPurple: string; 35 | themeDarkGrey: string; 36 | themeGrey: string; 37 | themeLightGrey: string; 38 | themeTransparentGrey: string; 39 | themeGold: string; 40 | courseItemColorList: string[]; 41 | } 42 | 43 | export interface Theme { 44 | colors: ColorTheme; 45 | } 46 | 47 | export default (themeName: string | null | undefined): Theme => ({ 48 | colors: 49 | currState().config.darkMode || themeName === "dark" 50 | ? enableEasterEgg() 51 | ? colorPkuDark 52 | : colorDark 53 | : enableEasterEgg() 54 | ? colorPkuLight 55 | : colorLight, 56 | }); 57 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/components/LazyImage.tsx: -------------------------------------------------------------------------------- 1 | import {Image, ImageProps, View} from "react-native"; 2 | import {useEffect, useState} from "react"; 3 | 4 | export const LazyImage = ( 5 | props: ImageProps & { 6 | appearance: boolean; 7 | source: {uri: string}; 8 | style: {height: number; width: number}; 9 | }, 10 | ) => { 11 | const { 12 | appearance, 13 | style: {height, width}, 14 | } = props; 15 | 16 | const [lazyAppearance, setLazyAppearance] = useState(false); 17 | 18 | useEffect(() => { 19 | if (appearance) { 20 | setLazyAppearance(true); 21 | } 22 | }, [appearance]); 23 | 24 | return lazyAppearance ? ( 25 | 26 | ) : ( 27 | 28 | ); 29 | }; 30 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/components/easySnackbars.ts: -------------------------------------------------------------------------------- 1 | import Snackbar from "react-native-snackbar"; 2 | import {getStr} from "../utils/i18n"; 3 | 4 | export const NetworkRetry = (e?: any) => 5 | Snackbar.show({ 6 | text: getStr("networkRetry") + (e?.message ?? ""), 7 | duration: Snackbar.LENGTH_SHORT, 8 | }); 9 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/components/home/cr.tsx: -------------------------------------------------------------------------------- 1 | import {useColorScheme, View} from "react-native"; 2 | import themes from "../../assets/themes/themes"; 3 | 4 | export const CourseTimeQuickGlance = ({ 5 | time, 6 | width, 7 | height, 8 | }: { 9 | time: string; 10 | width: number; 11 | height: number; 12 | }) => { 13 | const themeName = useColorScheme(); 14 | const {colors} = themes(themeName); 15 | const segments = 16 | time.match(/\d-\d/g)?.map((s) => ({ 17 | dayOfWeek: Number(s[0]), 18 | section: Number(s[2]), 19 | })) ?? []; 20 | const widthPerDay = width / 7; 21 | const heightPerSection = height / 6; 22 | return ( 23 | 24 | {segments.map(({dayOfWeek, section}) => ( 25 | 36 | ))} 37 | 47 | 48 | ); 49 | }; 50 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/components/home/icon.tsx: -------------------------------------------------------------------------------- 1 | import {ReactElement} from "react"; 2 | import {GestureResponderEvent, Text, TouchableOpacity} from "react-native"; 3 | import zh from "../../assets/translations/zh"; 4 | import {getStr} from "../../utils/i18n"; 5 | import {useColorScheme} from "react-native"; 6 | import themes from "../../assets/themes/themes"; 7 | 8 | export const HomeIcon = ({ 9 | title, 10 | onPress, 11 | children, 12 | }: { 13 | title: keyof typeof zh; 14 | onPress: (event: GestureResponderEvent) => void; 15 | children: ReactElement; 16 | }) => { 17 | const themeName = useColorScheme(); 18 | const theme = themes(themeName); 19 | 20 | return ( 21 | 31 | {children} 32 | 36 | {getStr(title)} 37 | 38 | 39 | ); 40 | }; 41 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/components/news/IconStarButton.tsx: -------------------------------------------------------------------------------- 1 | import {TouchableOpacity} from "react-native"; 2 | import IconStarActive from "../../assets/icons/IconStarActive"; 3 | import IconStar from "../../assets/icons/IconStar"; 4 | 5 | export const IconStarButton = ({ 6 | active, 7 | onPress, 8 | size = 18, 9 | }: { 10 | active: boolean; 11 | onPress: () => void; 12 | size?: number; 13 | }) => { 14 | if (active) { 15 | return ( 16 | 17 | 18 | 19 | ); 20 | } else { 21 | return ( 22 | 23 | 24 | 25 | ); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/constants/strings.ts: -------------------------------------------------------------------------------- 1 | export const GITHUB_ORG_URL = "https://github.com/thu-info-community"; 2 | export const TUNA_BASE_URL = 3 | "https://mirrors.tuna.tsinghua.edu.cn/github-release/thu-info-community/thu-info-app/"; 4 | export const TUNA_LATEST_URL = 5 | "https://mirrors.tuna.tsinghua.edu.cn/github-release/thu-info-community/thu-info-app/LatestRelease/"; 6 | export const ICP_URL = "https://beian.miit.gov.cn"; 7 | export const UNIDY2002_URL = "https://github.com/UNIDY2002"; 8 | export const ASHITEMARU_URL = "https://github.com/Ashitemaru"; 9 | export const WERKEYTOM_URL = "https://github.com/werkeytom"; 10 | export const EVEELSEIF_URL = "https://github.com/EveElseIf"; 11 | export const YONGQI_URL = "https://github.com/Yongqi-Zhuo"; 12 | export const _84634E1A607A_URL = "https://github.com/84634E1A607A"; 13 | export const Johnny_URL = "https://github.com/JohnnyBGoodeLithium"; 14 | export const VZHAO_21_URL = "https://github.com/vzhao-21"; 15 | export const WATER_USER_URL = "http://dingshui.bjqzhd.com/auser/getuser.html"; 16 | export const WATER_SUB_URL = "http://dingshui.bjqzhd.com/buy/subs.html"; 17 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/network/water.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Original author: THUzxj 3 | */ 4 | import {WATER_SUB_URL, WATER_USER_URL} from "../constants/strings"; 5 | import {stringify} from "@thu-info/lib/src/utils/network"; 6 | import {CONTENT_TYPE_FORM} from "@thu-info/lib/src/constants/strings"; 7 | 8 | export interface WaterUserInformation { 9 | name: string; 10 | address: string; 11 | } 12 | 13 | export const getWaterUserInformation = async ( 14 | id: string, 15 | ): Promise => { 16 | if (id.trim().length === 0) { 17 | return {name: "", address: ""}; 18 | } else { 19 | return fetch(WATER_USER_URL, { 20 | headers: {"Content-Type": CONTENT_TYPE_FORM}, 21 | method: "POST", 22 | body: stringify({name: "pw", param: id}), 23 | }).then((r) => r.json()); 24 | } 25 | }; 26 | 27 | export const waterBrandIdToName: {[key: string]: string} = { 28 | "6": "清紫源泉矿泉水(高端)", 29 | "10": "燕园泉矿泉水(高端)", 30 | "12": "农夫山泉桶装水(19L)", 31 | "11": "清紫源泉矿泉水", 32 | "8": "喜士天然矿泉水(大)", 33 | "9": "喜士天然矿泉水(小)", 34 | "1": "娃哈哈矿泉水", 35 | "7": "娃哈哈纯净水", 36 | "5": "清紫源泉纯净水", 37 | }; 38 | 39 | export const postWaterSubmission = ( 40 | id: string, 41 | num: string, // 订水量 42 | num1: string, // 订水票量 43 | lid: string, // 水种类 44 | address: string, 45 | ): Promise => 46 | fetch(WATER_SUB_URL, { 47 | headers: {"Content-Type": CONTENT_TYPE_FORM}, 48 | method: "POST", 49 | body: stringify({pw: id, num, num1, lid, address}), 50 | }) 51 | .then((r) => r.text()) 52 | .then((res) => { 53 | if (!res.includes("成功")) { 54 | throw new Error("Submission failed"); 55 | } 56 | }); 57 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/redux/slices/announcement.ts: -------------------------------------------------------------------------------- 1 | import {createSlice} from "@reduxjs/toolkit"; 2 | import type {PayloadAction} from "@reduxjs/toolkit"; 3 | import {Announcement} from "@thu-info/lib/src/models/app/announcement"; 4 | 5 | export interface AppAnnouncement extends Announcement { 6 | read: boolean; 7 | } 8 | 9 | export interface AnnouncementState { 10 | announcements: AppAnnouncement[]; 11 | } 12 | 13 | const initialState: AnnouncementState = { 14 | announcements: [], 15 | }; 16 | 17 | export const defaultAnnouncement = initialState; 18 | 19 | export const announcementSlice = createSlice({ 20 | name: "announcement", 21 | initialState, 22 | reducers: { 23 | updateAnnouncements: (state, {payload}: PayloadAction) => { 24 | state.announcements = payload.map((a) => ({ 25 | ...a, 26 | read: state.announcements.some(({id, read}) => id === a.id && read), 27 | })); 28 | }, 29 | toggleReadStatus: (state, {payload}: PayloadAction) => { 30 | state.announcements 31 | .filter(({id}) => id === payload) 32 | .forEach((a) => (a.read = !a.read)); 33 | }, 34 | }, 35 | }); 36 | 37 | export const {updateAnnouncements, toggleReadStatus} = 38 | announcementSlice.actions; 39 | 40 | export const announcementReducer = announcementSlice.reducer; 41 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/redux/slices/auth.ts: -------------------------------------------------------------------------------- 1 | import {createSlice} from "@reduxjs/toolkit"; 2 | import type {PayloadAction} from "@reduxjs/toolkit"; 3 | import {v4 as uuidv4} from "uuid"; 4 | 5 | export interface AuthState { 6 | userId: string; 7 | password: string; 8 | fingerprint: string; 9 | } 10 | 11 | const initialState: AuthState = { 12 | userId: "", 13 | password: "", 14 | fingerprint: uuidv4().replace(/-/g, ""), 15 | }; 16 | 17 | export const defaultAuth = initialState; 18 | 19 | export const authSlice = createSlice({ 20 | name: "auth", 21 | initialState, 22 | reducers: { 23 | login: ( 24 | state, 25 | { 26 | payload, 27 | }: PayloadAction<{ 28 | userId: string; 29 | password: string; 30 | }>, 31 | ) => { 32 | state.userId = payload.userId; 33 | state.password = payload.password; 34 | }, 35 | logout: (state) => { 36 | state.userId = ""; 37 | state.password = ""; 38 | }, 39 | }, 40 | }); 41 | 42 | export const {login, logout} = authSlice.actions; 43 | 44 | export const authReducer = authSlice.reducer; 45 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/redux/slices/campusCard.ts: -------------------------------------------------------------------------------- 1 | import {createSlice} from "@reduxjs/toolkit"; 2 | import type {PayloadAction} from "@reduxjs/toolkit"; 3 | 4 | export interface CampusCardState { 5 | balance: number; 6 | updatedAt: number; 7 | paymentMethod: string; 8 | todayRechargeAmount: number; 9 | lastRechargeDate: string; 10 | } 11 | 12 | const initialState: CampusCardState = { 13 | balance: 0, 14 | updatedAt: 0, 15 | paymentMethod: "bank", 16 | todayRechargeAmount: 0, 17 | lastRechargeDate: "", 18 | }; 19 | 20 | export const defaultCampusCard = initialState; 21 | 22 | export const campusCardSlice = createSlice({ 23 | name: "campusCard", 24 | initialState, 25 | reducers: { 26 | setBalance: (state, {payload}: PayloadAction) => { 27 | state.balance = payload; 28 | state.updatedAt = Date.now(); 29 | }, 30 | setPaymentMethod: (state, {payload}: PayloadAction) => { 31 | state.paymentMethod = payload; 32 | }, 33 | updateRechargeAmount: ( 34 | state, 35 | {payload}: PayloadAction<{amount: number; date: string}>, 36 | ) => { 37 | if (state.lastRechargeDate === payload.date) { 38 | state.todayRechargeAmount += payload.amount; 39 | } else { 40 | state.todayRechargeAmount = payload.amount; 41 | state.lastRechargeDate = payload.date; 42 | } 43 | }, 44 | }, 45 | }); 46 | 47 | export const {setBalance, setPaymentMethod, updateRechargeAmount} = 48 | campusCardSlice.actions; 49 | 50 | export const campusCardReducer = campusCardSlice.reducer; 51 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/redux/slices/credentials.ts: -------------------------------------------------------------------------------- 1 | import {createSlice} from "@reduxjs/toolkit"; 2 | import type {PayloadAction} from "@reduxjs/toolkit"; 3 | 4 | export interface CredentialsState { 5 | dormPassword: string; 6 | appSecret: string | undefined; 7 | } 8 | 9 | const initialState: CredentialsState = { 10 | dormPassword: "", 11 | appSecret: undefined, 12 | }; 13 | 14 | export const credentialsSlice = createSlice({ 15 | name: "credentials", 16 | initialState, 17 | reducers: { 18 | setDormPassword: (state, {payload}: PayloadAction) => { 19 | state.dormPassword = payload; 20 | }, 21 | setAppSecret: (state, {payload}: PayloadAction) => { 22 | state.appSecret = payload; 23 | }, 24 | }, 25 | }); 26 | 27 | export const {setDormPassword, setAppSecret} = credentialsSlice.actions; 28 | 29 | export const credentialsReducer = credentialsSlice.reducer; 30 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/redux/slices/deepseek.ts: -------------------------------------------------------------------------------- 1 | import {createSlice} from "@reduxjs/toolkit"; 2 | import type {PayloadAction} from "@reduxjs/toolkit"; 3 | import type {Conversation} from "../../ui/home/deepseek.tsx"; 4 | 5 | export interface DeepseekState { 6 | history: Conversation[]; 7 | } 8 | 9 | const initialState: DeepseekState = { 10 | history: [], 11 | }; 12 | 13 | export const defaultDeepseek = initialState; 14 | 15 | export const deepseekSlice = createSlice({ 16 | name: "deepseek", 17 | initialState, 18 | reducers: { 19 | deepseekUpdateHistory: ( 20 | state, 21 | {payload}: PayloadAction, 22 | ) => { 23 | const index = state.history.findIndex( 24 | (conversation) => conversation.id === payload.id, 25 | ); 26 | if (index >= 0) { 27 | state.history[index] = payload; 28 | } else { 29 | state.history.splice(0, 0, payload); 30 | } 31 | }, 32 | deepseekDeleteConversation: ( 33 | state, 34 | {payload}: PayloadAction, 35 | ) => { 36 | const index = state.history.findIndex( 37 | (conversation) => conversation.id === payload.id, 38 | ); 39 | if (index >= 0) { 40 | state.history.splice(index, 1); 41 | } 42 | }, 43 | deepseekClear: (state: DeepseekState) => { 44 | state.history = []; 45 | }, 46 | }, 47 | }); 48 | 49 | export const {deepseekUpdateHistory, deepseekClear, deepseekDeleteConversation} = deepseekSlice.actions; 50 | 51 | export const deepseekReducer = deepseekSlice.reducer; 52 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/redux/slices/reservation.ts: -------------------------------------------------------------------------------- 1 | import {createSlice} from "@reduxjs/toolkit"; 2 | import type {PayloadAction} from "@reduxjs/toolkit"; 3 | import {LibBookRecord} from "@thu-info/lib/src/models/home/library"; 4 | import {SportsReservationRecord} from "@thu-info/lib/src/models/home/sports"; 5 | 6 | export interface ReservationState { 7 | activeLibBookRecords: LibBookRecord[]; 8 | activeSportsReservationRecords: SportsReservationRecord[]; 9 | } 10 | 11 | const initialState: ReservationState = { 12 | activeLibBookRecords: [], 13 | activeSportsReservationRecords: [], 14 | }; 15 | 16 | export const defaultReservation = initialState; 17 | 18 | export const reservationSlice = createSlice({ 19 | name: "reservation", 20 | initialState, 21 | reducers: { 22 | setActiveLibBookRecord: ( 23 | state, 24 | {payload}: PayloadAction, 25 | ) => { 26 | state.activeLibBookRecords = payload.filter( 27 | ({status}) => 28 | status === "预约成功" || 29 | status === "使用中" || 30 | status === "预约开始提醒", 31 | ); 32 | }, 33 | setActiveSportsReservationRecord: ( 34 | state, 35 | {payload}: PayloadAction, 36 | ) => { 37 | state.activeSportsReservationRecords = payload; 38 | }, 39 | }, 40 | }); 41 | 42 | export const {setActiveLibBookRecord, setActiveSportsReservationRecord} = 43 | reservationSlice.actions; 44 | 45 | export const reservationReducer = reservationSlice.reducer; 46 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/redux/slices/timetable.ts: -------------------------------------------------------------------------------- 1 | import {createSlice} from "@reduxjs/toolkit"; 2 | import type {PayloadAction} from "@reduxjs/toolkit"; 3 | import {CrTimetable} from "@thu-info/lib/src/models/cr/cr"; 4 | 5 | export interface TimetableState { 6 | crTimetable: CrTimetable[]; 7 | } 8 | 9 | const initialState: TimetableState = { 10 | crTimetable: [], 11 | }; 12 | 13 | export const defaultTimetable = initialState; 14 | 15 | export const timetableSlice = createSlice({ 16 | name: "timetable", 17 | initialState, 18 | reducers: { 19 | setCrTimetable: (state, {payload}: PayloadAction) => { 20 | state.crTimetable = payload; 21 | }, 22 | }, 23 | }); 24 | 25 | export const {setCrTimetable} = timetableSlice.actions; 26 | 27 | export const timetableReducer = timetableSlice.reducer; 28 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/redux/slices/top5.ts: -------------------------------------------------------------------------------- 1 | import {createSlice} from "@reduxjs/toolkit"; 2 | import type {PayloadAction} from "@reduxjs/toolkit"; 3 | 4 | export interface Top5State { 5 | top5Functions: string[]; 6 | } 7 | const initialState: Top5State = { 8 | top5Functions: [], 9 | }; 10 | 11 | export const defaultTop5 = initialState; 12 | 13 | export const top5Slice = createSlice({ 14 | name: "top5", 15 | initialState, 16 | reducers: { 17 | top5Update: (state, {payload}: PayloadAction) => { 18 | state.top5Functions = state.top5Functions.filter((x) => x !== payload); 19 | state.top5Functions.unshift(payload); 20 | state.top5Functions = state.top5Functions.slice(0, 5); 21 | }, 22 | top5Set: (state, {payload}: PayloadAction) => { 23 | state.top5Functions = payload.slice(0, 5); 24 | }, 25 | }, 26 | }); 27 | 28 | export const {top5Update, top5Set} = top5Slice.actions; 29 | 30 | export const top5Reducer = top5Slice.reducer; 31 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/ui/home/dormScore.tsx: -------------------------------------------------------------------------------- 1 | import {View, useColorScheme} from "react-native"; 2 | import {useEffect, useState} from "react"; 3 | import {NetworkRetry} from "../../components/easySnackbars"; 4 | import ImageViewer from "react-native-image-zoom-viewer"; 5 | import {helper, State} from "../../redux/store"; 6 | import {DormAuthError} from "@thu-info/lib/src/utils/error"; 7 | import {RootNav} from "../../components/Root"; 8 | import {useSelector} from "react-redux"; 9 | import themes from "../../assets/themes/themes"; 10 | 11 | export const DormScoreScreen = ({navigation}: {navigation: RootNav}) => { 12 | const [base64, setBase64] = useState(); 13 | const dormPassword = useSelector((s: State) => s.credentials.dormPassword); 14 | const themeName = useColorScheme(); 15 | const {colors} = themes(themeName); 16 | useEffect(() => { 17 | helper 18 | .getDormScore(dormPassword) 19 | .then(setBase64) 20 | .catch((e) => { 21 | if (e instanceof DormAuthError) { 22 | navigation.navigate("MyhomeLogin"); 23 | } else { 24 | NetworkRetry(); 25 | } 26 | }); 27 | // eslint-disable-next-line react-hooks/exhaustive-deps 28 | }, [dormPassword]); 29 | return ( 30 | 31 | {base64 && ( 32 | } 37 | /> 38 | )} 39 | 40 | ); 41 | }; 42 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/ui/home/eleRecord.tsx: -------------------------------------------------------------------------------- 1 | import {Text, View} from "react-native"; 2 | import {roundedRefreshListScreen} from "../../components/settings/simpleRefreshListScreen"; 3 | import {helper} from "../../redux/store"; 4 | 5 | export const EleRecordScreen = roundedRefreshListScreen( 6 | helper.getElePayRecord, 7 | ( 8 | [_name, _id, time, _channel, value, status], 9 | _, 10 | __, 11 | {colors}, 12 | index, 13 | total, 14 | ) => { 15 | return ( 16 | 23 | 24 | 25 | {status} 26 | 27 | {time} 28 | 29 | 30 | {value} 31 | 32 | 33 | ); 34 | }, 35 | (item) => item[1], 36 | ); 37 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/ui/home/invoicePDF.tsx: -------------------------------------------------------------------------------- 1 | import {RootStackParamList} from "../../components/Root"; 2 | import {Dimensions, useColorScheme, View} from "react-native"; 3 | import Pdf from "react-native-pdf"; 4 | import {RouteProp} from "@react-navigation/native"; 5 | import themedStyles from "../../utils/themedStyles"; 6 | 7 | export const InvoicePDFScreen = ({ 8 | route: { 9 | params: {base64}, 10 | }, 11 | }: { 12 | route: RouteProp; 13 | }) => { 14 | const themeName = useColorScheme(); 15 | const style = styles(themeName); 16 | return ( 17 | 18 | 22 | 23 | ); 24 | }; 25 | 26 | const styles = themedStyles((theme) => ({ 27 | container: { 28 | flex: 1, 29 | justifyContent: "flex-start", 30 | alignItems: "center", 31 | marginTop: 25, 32 | }, 33 | pdf: { 34 | flex: 1, 35 | backgroundColor: theme.colors.themeBackground, 36 | width: Dimensions.get("window").width, 37 | height: Dimensions.get("window").height, 38 | }, 39 | })); 40 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/ui/home/libraryFloor.tsx: -------------------------------------------------------------------------------- 1 | import {LibraryFloor} from "@thu-info/lib/src/models/home/library"; 2 | import {libraryRefreshListScreen} from "../../components/home/libraryRefreshListScreen"; 3 | import {helper} from "../../redux/store"; 4 | 5 | export const LibraryFloorScreen = libraryRefreshListScreen< 6 | LibraryFloor, 7 | "LibraryFloor" 8 | >( 9 | (props, dateChoice) => 10 | helper.getLibraryFloorList(props.route.params.library, dateChoice), 11 | (props, item, choice) => () => { 12 | if (!helper.mocked()) { 13 | props.navigation.navigate("LibrarySection", { 14 | floor: item, 15 | dateChoice: choice, 16 | }); 17 | } 18 | }, 19 | undefined, 20 | !helper.mocked(), 21 | ); 22 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/ui/home/librarySection.tsx: -------------------------------------------------------------------------------- 1 | import {libraryRefreshListScreen} from "../../components/home/libraryRefreshListScreen"; 2 | import {helper} from "../../redux/store"; 3 | import {LibrarySection} from "@thu-info/lib/src/models/home/library"; 4 | 5 | export const LibrarySectionScreen = libraryRefreshListScreen< 6 | LibrarySection, 7 | "LibrarySection" 8 | >( 9 | (props, dateChoice: 0 | 1) => 10 | helper.getLibrarySectionList(props.route.params.floor, dateChoice), 11 | (props, item, choice) => () => 12 | props.navigation.navigate("LibrarySeat", { 13 | section: item, 14 | dateChoice: choice, 15 | }), 16 | ); 17 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/ui/home/network.tsx: -------------------------------------------------------------------------------- 1 | import {useColorScheme, View} from "react-native"; 2 | import {RootNav} from "../../components/Root"; 3 | import {currState} from "../../redux/store"; 4 | import {SecondaryItem, styles} from "../../components/home/secondaryItems"; 5 | import {addUsageStat, FunctionType} from "../../utils/webApi"; 6 | import IconNetworkDetail from "../../assets/icons/IconNetworkDetail"; 7 | import IconNetworkOnlineDevices from "../../assets/icons/IconNetworkOnlineDevices"; 8 | 9 | export const NetworkScreen = ({navigation}: {navigation: RootNav}) => { 10 | const themeName = useColorScheme(); 11 | const style = styles(themeName); 12 | const disabledFunction = currState().config.homeFunctionDisabled; 13 | return ( 14 | 15 | 16 | {!disabledFunction.includes("networkDetail") && ( 17 | } 21 | onPress={() => { 22 | addUsageStat(FunctionType.NetworkDetail); 23 | navigation.navigate("NetworkDetail"); 24 | }} 25 | /> 26 | )} 27 | {!disabledFunction.includes("onlineDevices") && ( 28 | } 32 | onPress={() => { 33 | addUsageStat(FunctionType.OnlineDevices); 34 | navigation.navigate("OnlineDevices"); 35 | }} 36 | /> 37 | )} 38 | 39 | 40 | ); 41 | }; 42 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/ui/home/physicalExam.tsx: -------------------------------------------------------------------------------- 1 | import {Text, View} from "react-native"; 2 | import {roundedRefreshListScreen} from "../../components/settings/simpleRefreshListScreen"; 3 | import {helper} from "../../redux/store"; 4 | 5 | export const PhysicalExamScreen = roundedRefreshListScreen( 6 | helper.getPhysicalExamResult, 7 | ([key, value], _, __, {colors}, index, total) => ( 8 | 16 | 21 | {key} 22 | 23 | 28 | {value} 29 | 30 | 31 | ), 32 | ([x]) => x, 33 | ); 34 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/ui/settings/darkMode.tsx: -------------------------------------------------------------------------------- 1 | import {getStr} from "../../utils/i18n"; 2 | import {State} from "../../redux/store"; 3 | import {Text, TouchableOpacity, useColorScheme, View} from "react-native"; 4 | import {RoundedView} from "../../components/views"; 5 | import {useDispatch, useSelector} from "react-redux"; 6 | import {styles} from "./settings"; 7 | import IconCheck from "../../assets/icons/IconCheck"; 8 | import {configSet} from "../../redux/slices/config"; 9 | 10 | export const DarkModeScreen = () => { 11 | const themeName = useColorScheme(); 12 | const style = styles(themeName); 13 | 14 | const darkMode = useSelector((s: State) => s.config.darkMode); 15 | const dispatch = useDispatch(); 16 | 17 | return ( 18 | 19 | 20 | { 23 | dispatch(configSet({key: "darkMode", value: false})); 24 | }}> 25 | {getStr("autoFollow")} 26 | {darkMode !== true && } 27 | 28 | 29 | { 32 | dispatch(configSet({key: "darkMode", value: true})); 33 | }}> 34 | {getStr("enableDarkMode")} 35 | {darkMode === true && } 36 | 37 | 38 | 39 | ); 40 | }; 41 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/ui/settings/popi.tsx: -------------------------------------------------------------------------------- 1 | import {Text, View} from "react-native"; 2 | import {simpleRefreshListScreen} from "../../components/settings/simpleRefreshListScreen"; 3 | import {helper} from "../../redux/store"; 4 | import {Feedback} from "@thu-info/lib/src/models/app/feedback"; 5 | 6 | export const PopiScreen = simpleRefreshListScreen( 7 | async () => await helper.getFeedbackReplies(), 8 | ({content, reply}, _, __, {colors}) => ( 9 | 10 | 18 | {"Q: " + content} 19 | 20 | 21 | 22 | {"A: " + reply} 23 | 24 | 25 | ), 26 | ({content}) => content, 27 | ); 28 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/utils/alipay.ts: -------------------------------------------------------------------------------- 1 | import {Linking} from "react-native"; 2 | 3 | export const hasAlipay = () => 4 | Linking.canOpenURL("alipayqr://").then((support) => { 5 | if (!support) { 6 | throw new Error("Alipay not found."); 7 | } 8 | }); 9 | 10 | export const doAlipay = (payCode: string) => 11 | Linking.openURL( 12 | "alipayqr://platformapi/startapp?saId=10000007&qrcode=https%3A%2F%2Fqr.alipay.com%2F" + 13 | payCode, 14 | ); 15 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/utils/easterEgg.ts: -------------------------------------------------------------------------------- 1 | import dayjs from "dayjs"; 2 | 3 | export const enableEasterEgg = () => { 4 | const today = dayjs(); 5 | return today.month() === 3 && today.date() === 1; 6 | }; 7 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/utils/extensions.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | 3 | // eslint-disable-next-line no-extend-native 4 | Date.prototype.format = function () { 5 | return `${this.getFullYear()}-${this.getMonth() + 1}-${this.getDate()}`; 6 | }; 7 | 8 | // eslint-disable-next-line no-extend-native 9 | String.prototype.format = function () { 10 | var args = arguments; 11 | return this.replace(/{(\d+)}/g, function (match, number) { 12 | return typeof args[number] !== "undefined" ? args[number] : match; 13 | }); 14 | }; 15 | 16 | if (global.FileReader) { 17 | FileReader.prototype.readAsArrayBuffer = function (blob) { 18 | if (this.readyState === this.LOADING) { 19 | throw new Error("InvalidStateError"); 20 | } 21 | // @ts-ignore 22 | this._setReadyState(this.LOADING); 23 | // @ts-ignore 24 | this._result = null; 25 | // @ts-ignore 26 | this._error = null; 27 | const fr = new FileReader(); 28 | fr.onloadend = () => { 29 | const content = atob( 30 | // @ts-ignore 31 | fr.result.substr("data:application/octet-stream;base64,".length), 32 | ); 33 | const buffer = new ArrayBuffer(content.length); 34 | const view = new Uint8Array(buffer); 35 | view.set(Array.from(content).map((c) => c.charCodeAt(0))); 36 | // @ts-ignore 37 | this._result = buffer; 38 | // @ts-ignore 39 | this._setReadyState(this.DONE); 40 | }; 41 | fr.readAsDataURL(blob); 42 | }; 43 | } 44 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/utils/extensionsDeclaration.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | 3 | declare global { 4 | interface Date { 5 | format(): string; 6 | } 7 | 8 | interface String { 9 | format(...args: any[]): string; 10 | } 11 | } 12 | 13 | import type {Action, Reducer} from "redux"; 14 | import type {PersistConfig, PersistState} from "redux-persist"; 15 | 16 | declare module "redux-persist" { 17 | export function persistReducer( 18 | config: PersistConfig, 19 | baseReducer: Reducer, 20 | ): Reducer; 21 | } 22 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/utils/i18n.ts: -------------------------------------------------------------------------------- 1 | import {getLocales} from "react-native-localize"; 2 | import en from "../assets/translations/en"; 3 | import zh from "../assets/translations/zh"; 4 | import {currState} from "../redux/store"; 5 | 6 | export const getLocale = () => { 7 | const preferredLocales = getLocales(); 8 | const languageSettings = currState().config.language; 9 | if (languageSettings === "zh") { 10 | return zh; 11 | } else if (languageSettings === "en") { 12 | return en; 13 | } else { 14 | return preferredLocales[0].languageTag.startsWith("zh") ? zh : en; 15 | } 16 | }; 17 | 18 | const translations = getLocale() as typeof zh; 19 | 20 | export const langCode = translations === zh ? "zh" : "en"; 21 | 22 | export function getStr(key: K): string { 23 | if (!translations[key]) { 24 | console.warn(`Missing translation for key ${key}, language ${langCode}`); 25 | return key; 26 | } 27 | 28 | // @ts-ignore 29 | return translations[key]; 30 | } 31 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/utils/saveImg.ts: -------------------------------------------------------------------------------- 1 | import {Platform} from "react-native"; 2 | import {check, PERMISSIONS, request, RESULTS} from "react-native-permissions"; 3 | import {CameraRoll} from "@react-native-camera-roll/camera-roll"; 4 | import {getStr} from "./i18n"; 5 | import Snackbar from "react-native-snackbar"; 6 | 7 | export const saveImg = async (uri: string) => { 8 | const permission = 9 | Platform.OS === "android" && Platform.Version >= 33 10 | ? PERMISSIONS.ANDROID.READ_MEDIA_IMAGES 11 | : PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE; 12 | const checkPermissions = await check(permission); 13 | if (checkPermissions === RESULTS.DENIED) { 14 | const requestPermissions = await request(permission); 15 | if (requestPermissions !== RESULTS.GRANTED) { 16 | Snackbar.show({ 17 | text: getStr("permissionDenied"), 18 | duration: Snackbar.LENGTH_SHORT, 19 | }); 20 | return; 21 | } 22 | } 23 | if ( 24 | checkPermissions === RESULTS.BLOCKED || 25 | checkPermissions === RESULTS.LIMITED 26 | ) { 27 | Snackbar.show({ 28 | text: getStr("permissionDenied"), 29 | duration: Snackbar.LENGTH_SHORT, 30 | }); 31 | return; 32 | } 33 | CameraRoll.saveAsset(uri, {type: "photo"}) 34 | .then(() => 35 | Snackbar.show({ 36 | text: getStr("saveSucceed"), 37 | duration: Snackbar.LENGTH_SHORT, 38 | }), 39 | ) 40 | .catch(() => 41 | Snackbar.show({ 42 | text: getStr("saveFailRetry"), 43 | duration: Snackbar.LENGTH_SHORT, 44 | }), 45 | ); 46 | }; 47 | -------------------------------------------------------------------------------- /apps/thu-info-app/src/utils/themedStyles.ts: -------------------------------------------------------------------------------- 1 | import themes, {Theme} from "../assets/themes/themes"; 2 | import {ImageStyle, StyleSheet, TextStyle, ViewStyle} from "react-native"; 3 | 4 | type NamedStyles = {[P in keyof T]: ViewStyle | TextStyle | ImageStyle}; 5 | 6 | export default | NamedStyles>( 7 | styleCreator: (theme: Theme) => T | NamedStyles, 8 | ) => 9 | (theme: string | undefined | null): T => 10 | StyleSheet.create(styleCreator(themes(theme))); 11 | -------------------------------------------------------------------------------- /apps/thu-info-app/test/i18n.test.ts: -------------------------------------------------------------------------------- 1 | import {expect, test} from "@jest/globals"; 2 | import zh from "../src/assets/translations/zh"; 3 | import en from "../src/assets/translations/en"; 4 | 5 | test("Translations objects should have the same keys.", () => { 6 | expect(Object.keys(zh).sort()).toEqual(Object.keys(en).sort()); 7 | }); 8 | -------------------------------------------------------------------------------- /apps/thu-info-app/test/render.test.tsx: -------------------------------------------------------------------------------- 1 | import {expect, it, jest} from "@jest/globals"; 2 | import "react-native"; 3 | import "react-native-get-random-values"; 4 | import React from "react"; 5 | import {App} from "../src/App"; 6 | import {render, screen, userEvent} from "@testing-library/react-native"; 7 | 8 | jest.setTimeout(90000); 9 | 10 | it("renders correctly", async () => { 11 | // Render the app 12 | const user = userEvent.setup(); 13 | render(); 14 | 15 | // Test top5 16 | const top5Recently = screen.getByTestId("homeFunctions-recentlyUsedFunction").children[0]; 17 | const top5All = screen.getByTestId("homeFunctions-allFunction").children[0]; 18 | expect(typeof top5Recently === "string").toBeFalsy(); 19 | expect(typeof top5All === "string").toBeFalsy(); 20 | if (typeof top5Recently === "string" || typeof top5All === "string") { 21 | return; 22 | } 23 | expect(top5Recently.children.length).toEqual(1); 24 | expect(top5All.children.length).toBeGreaterThan(0); 25 | 26 | // Press a home page function 27 | await user.press(screen.getByTestId("HomeIcon-classroomState")); 28 | 29 | // Perform login 30 | await user.type(screen.getByTestId("loginUserId"), "8888"); 31 | await user.type(screen.getByTestId("loginPassword"), "8888"); 32 | await user.press(screen.getByTestId("loginButton")); 33 | 34 | /* const top5RecentlyNew = screen.getByTestId("homeFunctions-recentlyUsedFunction").children[0]; 35 | expect(typeof top5RecentlyNew === "string").toBeFalsy(); 36 | if (typeof top5RecentlyNew === "string") { 37 | return; 38 | } 39 | expect(top5RecentlyNew.children.length).toEqual(1); */ 40 | }); 41 | -------------------------------------------------------------------------------- /apps/thu-info-app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@react-native/typescript-config/tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "node_modules/lerna/schemas/lerna-schema.json", 3 | "version": "3.13.1", 4 | "npmClient": "yarn", 5 | "command": { 6 | "version": { 7 | "message": "Release: %v" 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "thu-info", 3 | "version": "0.0.1", 4 | "private": true, 5 | "workspaces": [ 6 | "apps/*", 7 | "packages/*" 8 | ], 9 | "scripts": { 10 | "android": "yarn workspace @thu-info/app android", 11 | "ios": "yarn workspace @thu-info/app ios", 12 | "start": "yarn workspace @thu-info/app start", 13 | "build": "yarn workspace @thu-info/lib build", 14 | "test": "yarn workspaces run test", 15 | "lint": "yarn workspaces run lint", 16 | "fix": "yarn workspaces run fix", 17 | "prepare": "husky", 18 | "preversion": "git pull --rebase && node -e \"require('editor')('release-notes.md')\" && git add release-notes.md" 19 | }, 20 | "dependencies": { 21 | "editor": "1.0.0", 22 | "husky": "9.1.7", 23 | "lerna": "8.2.2" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/RTNNetworkUtils/index.ts: -------------------------------------------------------------------------------- 1 | import NativeNetworkUtils from "./src/specs/v2/NativeNetworkUtils"; 2 | 3 | export const RTNNetworkUtils = NativeNetworkUtils; 4 | -------------------------------------------------------------------------------- /packages/RTNNetworkUtils/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rtn-network-utils", 3 | "version": "3.13.0", 4 | "description": "", 5 | "main": "index.ts", 6 | "harmony": { 7 | "alias": "rtn-network-utils", 8 | "codegenConfig": [ 9 | { 10 | "version": 1, 11 | "specPaths": [ 12 | "./src/specs/v1" 13 | ] 14 | }, 15 | { 16 | "version": 2, 17 | "specPaths": [ 18 | "./src/specs/v2" 19 | ] 20 | } 21 | ] 22 | }, 23 | "files": [ 24 | "index.ts", 25 | "src/*", 26 | "harmony.tar.gz" 27 | ], 28 | "scripts": { 29 | "lint": "exit 0" 30 | }, 31 | "peerDependencies": { 32 | "react": "*", 33 | "react-native": "*" 34 | }, 35 | "private": true 36 | } 37 | -------------------------------------------------------------------------------- /packages/RTNNetworkUtils/src/specs/v1/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thu-info-community/thu-info-app/a6cf45e1f61ca888c5e9445d74f5b83985253442/packages/RTNNetworkUtils/src/specs/v1/.gitkeep -------------------------------------------------------------------------------- /packages/RTNNetworkUtils/src/specs/v2/NativeNetworkUtils.ts: -------------------------------------------------------------------------------- 1 | import type {TurboModule} from 'react-native/Libraries/TurboModule/RCTExport'; 2 | import {TurboModuleRegistry} from 'react-native'; 3 | 4 | export interface Spec extends TurboModule { 5 | getRedirectLocation(url: string): Promise; 6 | } 7 | 8 | export default TurboModuleRegistry.get( 9 | 'RTNNativeNetworkUtils', 10 | ) as Spec | null; 11 | -------------------------------------------------------------------------------- /packages/thu-info-lib/.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | /.env 3 | /.vscode 4 | /node_modules 5 | /demo/index.js 6 | /dist 7 | yarn-error.log 8 | secrets.json 9 | demo.zip 10 | *.jpg 11 | .DS_Store 12 | /demo 13 | -------------------------------------------------------------------------------- /packages/thu-info-lib/__tests__/auth.ts: -------------------------------------------------------------------------------- 1 | import {expect, it} from "@jest/globals"; 2 | import {InfoHelper} from "../src"; 3 | import dayjs from "dayjs"; 4 | 5 | let userId = ""; 6 | let password = ""; 7 | 8 | try { 9 | // eslint-disable-next-line @typescript-eslint/no-var-requires 10 | const secrets = require("../secrets.json"); 11 | userId = secrets.userId; 12 | password = secrets.password; 13 | } catch (e) { 14 | userId = process.env.INFO_USER_ID!; 15 | password = process.env.INFO_PASSWORD!; 16 | } 17 | 18 | it("should enter mocked account", async () => { 19 | const helper = new InfoHelper(); 20 | await helper.login({userId: "8888", password: "8888"}); 21 | expect(helper.mocked()).toEqual(true); 22 | await helper.logout(); 23 | }, 60000); 24 | 25 | it("should login successfully.", async () => { 26 | const helper = new InfoHelper(); 27 | await helper.login({userId, password}); 28 | const {firstDay, weekCount} = await helper.getCalendar(); 29 | expect(weekCount % 3).toEqual(0); 30 | expect(dayjs(firstDay).day()).toEqual(1); 31 | expect((await helper.getCrTimetable()).length).toBeGreaterThan(0); 32 | expect((await helper.getCampusCardInfo()).balance).toBeGreaterThanOrEqual(0); 33 | // const semester = (await helper.getCrAvailableSemesters())[0].id; 34 | // console.log(await helper.getCrCoursePlan(semester)); 35 | await helper.logout(); 36 | expect(helper.mocked()).toEqual(false); 37 | }, 60000); 38 | -------------------------------------------------------------------------------- /packages/thu-info-lib/__tests__/schedule.ts: -------------------------------------------------------------------------------- 1 | import {expect, it} from "@jest/globals"; 2 | import {ScheduleTime, scheduleTimeAdd} from "../src/models/schedule/schedule"; 3 | 4 | it("Test schedule time add", () => { 5 | const base: ScheduleTime = {base: [{ 6 | dayOfWeek: 1, 7 | begin: 1, 8 | end: 3, 9 | activeWeeks: [1, 2, 3] 10 | }]}; 11 | scheduleTimeAdd(base, { 12 | dayOfWeek: 3, 13 | begin: 1, 14 | end: 3, 15 | activeWeeks: [1, 2, 3] 16 | }); 17 | console.log(base); 18 | expect(base.base.length).toEqual(2); 19 | }); -------------------------------------------------------------------------------- /packages/thu-info-lib/__tests__/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2018", 4 | "module": "CommonJS", 5 | "moduleResolution": "node", 6 | "declaration": true, 7 | "strict": true, 8 | "allowSyntheticDefaultImports": true, 9 | "esModuleInterop": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/thu-info-lib/demo/index.ts: -------------------------------------------------------------------------------- 1 | import {InfoHelper} from "../src"; 2 | 3 | // @ts-ignore 4 | // browser.browserAction.onClicked.addListener(() => { 5 | // // @ts-ignore 6 | // browser.tabs.create({ 7 | // url: "index.html", 8 | // }); 9 | // }); 10 | 11 | (window as any).InfoHelper = {InfoHelper}; 12 | -------------------------------------------------------------------------------- /packages/thu-info-lib/demo/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "thu-info-lib-test", 3 | "description":"THUInfo网页版测试", 4 | "version":"0.0.1", 5 | "manifest_version" : 3, 6 | 7 | "content_scripts":[ 8 | { 9 | "matches": [ 10 | "https://webvpn.tsinghua.edu.cn/*", 11 | "https://card.tsinghua.edu.cn/*", 12 | "https://oauth.tsinghua.edu.cn/*", 13 | "https://id.tsinghua.edu.cn/*" 14 | ], 15 | "js": [ 16 | "index.js", 17 | "browser-polyfill.min.js" 18 | ] 19 | } 20 | ], 21 | "action": { 22 | "default_popup": "index.html" 23 | }, 24 | "permissions" : [ 25 | "storage" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /packages/thu-info-lib/openssl.cnf: -------------------------------------------------------------------------------- 1 | nodejs_conf = openssl_init 2 | 3 | [openssl_init] 4 | ssl_conf = ssl_sect 5 | 6 | [ssl_sect] 7 | system_default = system_default_sect 8 | 9 | [system_default_sect] 10 | Options = UnsafeLegacyRenegotiation 11 | -------------------------------------------------------------------------------- /packages/thu-info-lib/src/lib/thos.ts: -------------------------------------------------------------------------------- 1 | import {roamingWrapperWithMocks} from "./core"; 2 | import {InfoHelper} from "../index"; 3 | import {uFetch} from "../utils/network"; 4 | import {THOS_SELECT_ONE_URL} from "../constants/strings"; 5 | import {LibError} from "../utils/error"; 6 | import {CourseScore} from "../models/home/thos"; 7 | import {MOCK_COURSE_SCORE} from "../mocks/thos"; 8 | 9 | export const getScoreByCourseId = (helper: InfoHelper, courseId: string): Promise => 10 | roamingWrapperWithMocks( 11 | helper, 12 | "default", 13 | "56B13DDF68BB3DEA13D98E1E3E776D3E", 14 | async () => { 15 | const result = await uFetch(THOS_SELECT_ONE_URL, JSON.stringify({ 16 | presetKey:"103765749452800", 17 | param: {XH: helper.userId, KCH: courseId}, 18 | }) as never, 60000, "UTF-8", true, "application/json"); 19 | if (result.includes("您即将登录") || result.includes("清华大学WebVPN")) { 20 | throw new LibError(); 21 | } 22 | const o = JSON.parse(result); 23 | return { 24 | name: o.KCMC, 25 | credit: o.XF, 26 | grade: o.DJZCJ, 27 | }; 28 | }, 29 | MOCK_COURSE_SCORE, 30 | ); 31 | -------------------------------------------------------------------------------- /packages/thu-info-lib/src/mocks/app.ts: -------------------------------------------------------------------------------- 1 | import {Announcement} from "../models/app/announcement"; 2 | import {Version} from "../models/app/version"; 3 | import {Feedback} from "../models/app/feedback"; 4 | 5 | export const MOCK_LATEST_ANNOUNCEMENTS: Announcement[] = []; 6 | 7 | export const MOCK_LATEST_VERSION: Version = { 8 | versionName: "3.0.0", 9 | downloadUrl: "https://app.cs.tsinghua.edu.cn", 10 | releaseNote: "-", 11 | }; 12 | 13 | export const MOCK_FEEDBACK_REPLIES: Feedback[] = []; 14 | 15 | export const MOCK_QRCODE_URL = "https://weixin.qq.com/g/AwYAAEjQ7zlUoO63koFrk9iKxPWNtu8iusBrcHoVLhRJomKY74_1YlEr5A9jMIBV"; 16 | 17 | export const MOCK_APP_PRIVACY_URL = "https://app.cs.tsinghua.edu.cn/privacy"; 18 | -------------------------------------------------------------------------------- /packages/thu-info-lib/src/mocks/card.ts: -------------------------------------------------------------------------------- 1 | import {CardInfo} from "../models/card/info"; 2 | 3 | export const MOCK_CARD_INFO: CardInfo = { 4 | userId: "8888", 5 | userName: "8888", 6 | userNameEn:"8888", 7 | departmentName: "回笼觉学院", 8 | departmentNameEn: "回笼觉学院", 9 | departmentId: -1, 10 | photoFileName: "8888.jpg", 11 | phoneNumber: "8888", 12 | userGender: "1", 13 | effectiveTimestamp: new Date(), 14 | validTimestamp: new Date(), 15 | balance: 0, 16 | cardId: "114", 17 | cardStatus: "0", 18 | lastTransactionTimestamp: new Date(), 19 | maxDailyTransactionAmount: 200, 20 | maxOneTimeTransactionAmount: 50, 21 | }; 22 | -------------------------------------------------------------------------------- /packages/thu-info-lib/src/mocks/program.ts: -------------------------------------------------------------------------------- 1 | export const MOCK_PROGRAM = {}; -------------------------------------------------------------------------------- /packages/thu-info-lib/src/mocks/reserves-lib.ts: -------------------------------------------------------------------------------- 1 | import { SearchResult } from "../models/home/reserves-lib"; 2 | 3 | export const MOCK_RESERVES_LIB_SEARCH = { 4 | bookCount: 0, 5 | pageCount: 0, 6 | data: [], 7 | } as SearchResult; -------------------------------------------------------------------------------- /packages/thu-info-lib/src/mocks/thos.ts: -------------------------------------------------------------------------------- 1 | import {CourseScore} from "../models/home/thos"; 2 | 3 | export const MOCK_COURSE_SCORE: CourseScore = { 4 | name: "回笼觉设计与梦境工程", 5 | credit: 5, 6 | grade: "A+", 7 | }; 8 | -------------------------------------------------------------------------------- /packages/thu-info-lib/src/models/app/announcement.ts: -------------------------------------------------------------------------------- 1 | export interface Announcement { 2 | id: number, 3 | title: string, 4 | content: string, 5 | createdAt: number, 6 | visibleNotAfter: string, 7 | visibleExact: string, 8 | } 9 | -------------------------------------------------------------------------------- /packages/thu-info-lib/src/models/app/feedback.ts: -------------------------------------------------------------------------------- 1 | export interface Feedback { 2 | content: string; 3 | reply: string; 4 | replierName: string; 5 | repliedTime: string; 6 | } 7 | -------------------------------------------------------------------------------- /packages/thu-info-lib/src/models/app/version.ts: -------------------------------------------------------------------------------- 1 | export interface Version { 2 | versionName: string; 3 | releaseNote: string; 4 | downloadUrl: string; 5 | } 6 | -------------------------------------------------------------------------------- /packages/thu-info-lib/src/models/card/info.ts: -------------------------------------------------------------------------------- 1 | export interface CardInfo { 2 | userId: string; 3 | userName: string; 4 | userNameEn: string; 5 | departmentName: string; 6 | departmentNameEn: string; 7 | departmentId: number; 8 | photoFileName: string; 9 | phoneNumber: string; 10 | userGender: string; 11 | 12 | // You need to register each year to keep it effective 13 | effectiveTimestamp: Date; 14 | 15 | // The card remains valid until you leave the school 16 | validTimestamp: Date; 17 | 18 | balance: number; 19 | cardId: string; 20 | cardStatus: string; 21 | lastTransactionTimestamp: Date; 22 | maxDailyTransactionAmount: number; 23 | maxOneTimeTransactionAmount: number; 24 | } 25 | -------------------------------------------------------------------------------- /packages/thu-info-lib/src/models/card/recharge.ts: -------------------------------------------------------------------------------- 1 | export enum CardRechargeType { 2 | Bank, 3 | Alipay, 4 | Wechat, 5 | } 6 | -------------------------------------------------------------------------------- /packages/thu-info-lib/src/models/card/transaction.ts: -------------------------------------------------------------------------------- 1 | export interface CardTransaction { 2 | id: string; 3 | summary: string; 4 | timestamp: Date; 5 | balance: number; 6 | amount: number; 7 | address: string; 8 | name: string | undefined; 9 | txName: string; 10 | } 11 | 12 | export enum CardTransactionType { 13 | Any = -1, 14 | Consumption = 1, 15 | Recharge = 2, 16 | Subsidy = 3, 17 | } 18 | -------------------------------------------------------------------------------- /packages/thu-info-lib/src/models/home/bank.ts: -------------------------------------------------------------------------------- 1 | export interface BankPayment { 2 | department: string; // 代发部门 3 | project: string; // 代发项目 4 | usage: string; // 代发用途 5 | description: string; // 代发说明 6 | bank: string; // 开户银行 7 | time: string; // 计税时间 8 | total: string; // 应发金额 9 | deduction: string; // 扣税金额 10 | actual: string; // 实发金额 11 | deposit: string; // 存折金额 12 | cash: string; // 现金金额 13 | } 14 | 15 | export interface BankPaymentByMonth { 16 | month: string; // yyyy年MM月 17 | payment: BankPayment[]; 18 | } 19 | 20 | export interface GraduateIncome { 21 | id: string; 22 | year: string; 23 | month: string; 24 | date: string; 25 | ym: string; 26 | name: string; 27 | department: string; 28 | beforeTax: number; 29 | afterTax: number; 30 | tax: number; 31 | } 32 | -------------------------------------------------------------------------------- /packages/thu-info-lib/src/models/home/classroom.ts: -------------------------------------------------------------------------------- 1 | export interface Classroom { 2 | name: string; 3 | weekNumber: number; 4 | searchName: string; 5 | } 6 | 7 | export enum ClassroomStatus { 8 | TEACHING, 9 | EXAM, 10 | BORROWED, 11 | DISABLED, 12 | RESERVED_FOR_COMPAT, 13 | AVAILABLE, 14 | } 15 | 16 | export interface ClassroomState { 17 | name: string; 18 | status: ClassroomStatus[]; // an array of 42(=7*6) `ClassroomStatus`es (starting from Monday) 19 | } 20 | 21 | export interface ClassroomStateResult { 22 | validWeekNumbers: number[]; 23 | currentWeekNumber: number; 24 | datesOfCurrentWeek: [string, string, string, string, string, string, string]; 25 | classroomStates: ClassroomState[]; 26 | } 27 | -------------------------------------------------------------------------------- /packages/thu-info-lib/src/models/home/invoice.ts: -------------------------------------------------------------------------------- 1 | export interface Invoice { 2 | bill_amount: number, 3 | bmdm: string, 4 | bus_no: string, 5 | cust_email: string, 6 | cust_mob: string, 7 | cust_name: string, 8 | cust_tax_no: string, 9 | cust_ts_cardno: string, 10 | cust_type: string, 11 | file_name: string, 12 | financial_dept_name: string, 13 | financial_item_name: string, 14 | inv_amount: number, 15 | inv_code: string, 16 | inv_crc: string, 17 | inv_data_id: number, 18 | inv_date: string, 19 | inv_isred: string, 20 | inv_no: string, 21 | inv_note: string, 22 | inv_red_no: string, 23 | inv_type: string, 24 | inv_typeStr: string, 25 | is_allow_reimbursement: string, 26 | ists: string, 27 | payment_item_type_name: string, 28 | red_bus_no: string, 29 | tax_amount: number, 30 | } 31 | -------------------------------------------------------------------------------- /packages/thu-info-lib/src/models/home/report.ts: -------------------------------------------------------------------------------- 1 | export interface Course { 2 | name: string; 3 | credit: number; 4 | grade: string; 5 | point: number; 6 | semester: string; 7 | } 8 | -------------------------------------------------------------------------------- /packages/thu-info-lib/src/models/home/reserves-lib.ts: -------------------------------------------------------------------------------- 1 | export interface SearchResultItem { 2 | bookId: string; 3 | img: string; 4 | title: string; 5 | ISBN: string; 6 | author: string; 7 | publisher: string; 8 | } 9 | 10 | export interface SearchResult { 11 | bookCount: number; 12 | pageCount: number; 13 | data: SearchResultItem[]; 14 | } 15 | 16 | export interface BookChapter { 17 | title: string; 18 | href: string; 19 | } 20 | 21 | export interface BookDetail { 22 | img: string; 23 | title: string; 24 | author: string; 25 | publisher: string; 26 | ISBN: string; 27 | version: string; 28 | volume: string; 29 | chapters: BookChapter[]; 30 | } 31 | -------------------------------------------------------------------------------- /packages/thu-info-lib/src/models/home/thos.ts: -------------------------------------------------------------------------------- 1 | export interface CourseScore { 2 | name: string; 3 | credit: number; 4 | grade: string; 5 | } 6 | -------------------------------------------------------------------------------- /packages/thu-info-lib/src/models/network/account.ts: -------------------------------------------------------------------------------- 1 | export interface AccountInfo { 2 | username: string; 3 | contactEmail: string; 4 | contactPhone: string; 5 | contactLandline: string; 6 | realName: string; 7 | status: string; 8 | userGroup: string; 9 | location: string; 10 | allowedDevices: number; 11 | } 12 | -------------------------------------------------------------------------------- /packages/thu-info-lib/src/models/network/balance.ts: -------------------------------------------------------------------------------- 1 | export interface Balance { 2 | productName: string; 3 | usedBytes: string; 4 | usedSeconds: string; 5 | accountBalance: string; 6 | settlementDate: string; 7 | } 8 | -------------------------------------------------------------------------------- /packages/thu-info-lib/src/models/network/detail.ts: -------------------------------------------------------------------------------- 1 | export interface Usage { 2 | readonly in: string; 3 | readonly out: string; 4 | readonly total: string; 5 | readonly onlineTime: string; 6 | readonly loginCount: string; 7 | readonly currentCost: string; 8 | } 9 | 10 | export interface Detail { 11 | readonly year: number; 12 | readonly month: number; 13 | readonly wirelessUsage: Usage; 14 | readonly wiredUsage: Usage; 15 | readonly monthlyCost: string; 16 | } 17 | -------------------------------------------------------------------------------- /packages/thu-info-lib/src/models/network/device.ts: -------------------------------------------------------------------------------- 1 | export interface Device { 2 | readonly key: number; 3 | readonly ip4: string; 4 | readonly ip6: string; 5 | readonly loggedAt: string; 6 | readonly mac: string; 7 | readonly authPermission: string; 8 | } 9 | -------------------------------------------------------------------------------- /packages/thu-info-lib/src/models/news/news.ts: -------------------------------------------------------------------------------- 1 | export const channelTags = ["LM_BGTG", "LM_ZYGG", "LM_YQFKZT", "LM_JWGG", "LM_KYTZ", "LM_HB", "LM_XJ_XTWBGTZ", "LM_XSBGGG", "LM_TTGGG", "LM_JYGG", "LM_XJ_XSSQDT", "LM_BYJYXX", "LM_JYZPXX", "LM_XJ_GJZZSXRZ"] as const; 2 | 3 | export type ChannelTag = typeof channelTags[number]; 4 | 5 | export interface NewsSlice { 6 | readonly name: string; 7 | readonly xxid: string; 8 | readonly url: string; 9 | readonly date: string; 10 | readonly source: string; 11 | readonly topped: boolean; 12 | readonly channel: ChannelTag; 13 | readonly inFav: boolean; 14 | } 15 | 16 | export interface NewsSubscription { 17 | readonly channel?: string; 18 | readonly source?: string; 19 | readonly keyword?: string; 20 | readonly id: string; 21 | readonly title: string; 22 | readonly order: number; 23 | } 24 | -------------------------------------------------------------------------------- /packages/thu-info-lib/src/models/schedule/calendar.ts: -------------------------------------------------------------------------------- 1 | export interface Semester { 2 | firstDay: string; // yyyy-MM-dd 3 | semesterId: string; 4 | semesterName: string; 5 | weekCount: number; 6 | } 7 | export interface CalendarData extends Semester { 8 | nextSemesterList: Semester[]; 9 | } 10 | -------------------------------------------------------------------------------- /packages/thu-info-lib/src/utils/alipay.ts: -------------------------------------------------------------------------------- 1 | import {uFetch} from "./network"; 2 | import * as cheerio from "cheerio"; 3 | 4 | export const generalGetPayCode = async (paymentHtml: string) => { 5 | const $ = cheerio.load(paymentHtml); 6 | const url = $("form").attr()!.action; 7 | const form = $("[name=biz_content]").attr()!.value; 8 | 9 | // Get pay code 10 | return uFetch(url, {biz_content: form}).then((s) => { 11 | const qrCode = cheerio.load(s)("input[name=qrCode]").attr()!.value; 12 | return qrCode.substring(qrCode.lastIndexOf("/") + 1); 13 | }); 14 | }; 15 | -------------------------------------------------------------------------------- /packages/thu-info-lib/src/utils/cheerio.ts: -------------------------------------------------------------------------------- 1 | import * as cheerio from "cheerio"; 2 | import type {ElementType} from "domelementtype"; 3 | import type {DataNode, Element, Node} from "domhandler"; 4 | type Tag = Element & {type: ElementType.Tag}; 5 | 6 | // TODO: Merge two functions 7 | export const getCheerioText = (element: Node, index?: number) => 8 | index === undefined 9 | ? ((element as Tag).firstChild as DataNode)?.data?.trim() ?? "" 10 | : (((element as Tag).children[index] as Tag).firstChild as DataNode)?.data?.trim() ?? ""; 11 | 12 | export const getTrimmedData = (element: Element, indexChain: number[]) => { 13 | const tElement = cheerio.load(element)("td"); 14 | try { 15 | let res = tElement[indexChain[0]]; 16 | indexChain 17 | .slice(1) 18 | .forEach((val) => { 19 | res = (res as Tag).children[val] as Element; 20 | }); 21 | 22 | return (res as Node as DataNode).data?.trim() ?? ""; 23 | } catch { 24 | return ""; 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /packages/thu-info-lib/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2018", 4 | "module": "CommonJS", 5 | "moduleResolution": "node", 6 | "declaration": true, 7 | "outDir": "./dist", 8 | "strict": true, 9 | "allowSyntheticDefaultImports": true, 10 | "esModuleInterop": true, 11 | "sourceMap": true 12 | }, 13 | "include": [ 14 | "src" 15 | ], 16 | "exclude": [ 17 | "node_modules", 18 | "**/__tests__/*", 19 | "**/__mocks__/*" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /packages/thu-info-lib/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const NodePolyfillPlugin = require("node-polyfill-webpack-plugin"); 3 | 4 | module.exports = { 5 | entry: { 6 | index: "./demo/index.ts", 7 | }, 8 | output: { 9 | path: path.resolve("./demo"), 10 | filename: "[name].js", 11 | }, 12 | plugins: [ 13 | new NodePolyfillPlugin(), 14 | ], 15 | devServer: { 16 | contentBase: "./dist", 17 | headers: { 18 | "Access-Control-Allow-Origin": "*", 19 | }, 20 | }, 21 | module: { 22 | rules: [ 23 | { 24 | exclude: /node_modules/, 25 | test: /\.tsx?$/, 26 | use: "ts-loader", 27 | }, 28 | ], 29 | }, 30 | resolve: { 31 | extensions: [".ts", ".tsx", ".js"], 32 | }, 33 | externals: { 34 | "rtn-network-utils": "rtn-network-utils", 35 | }, 36 | mode: "development", 37 | devtool: "inline-source-map", 38 | }; 39 | -------------------------------------------------------------------------------- /release-notes.md: -------------------------------------------------------------------------------- 1 | ## @thu-info/app 2 | - 修复了登录失败的问题 3 | - 优化了信任设备超限处理逻辑 4 | - APP 指纹名现在会增加设备名 5 | - 优化网络登录页样式和UI逻辑 @SunnyCloudYang 6 | 7 | ## @thu-info/lib 8 | - 添加了信任设备超限回调函数和指纹名称回调函数 9 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "branchConcurrentLimit": 2, 3 | "extends": [ 4 | "config:recommended" 5 | ], 6 | "ignorePaths": [ 7 | "android" 8 | ], 9 | "packageRules": [ 10 | { 11 | "matchUpdateTypes": [ 12 | "minor", 13 | "patch", 14 | "pin", 15 | "digest" 16 | ], 17 | "automerge": true, 18 | "automergeType": "branch" 19 | }, 20 | { 21 | "matchDepTypes": [ 22 | "devDependencies" 23 | ], 24 | "automerge": true, 25 | "automergeType": "branch" 26 | } 27 | ], 28 | "postUpdateOptions": [ 29 | "yarnDedupeHighest" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /setup-harmony.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | rm package.json 6 | mv yarn.lock apps/thu-info-app/ 7 | cd apps/thu-info-app/ 8 | yarn add @react-native-oh-tpl/async-storage@1.21.0-0.2.1 \ 9 | @react-native-oh-tpl/blur@4.4.0-0.1.1 \ 10 | @react-native-oh-tpl/camera-roll@7.8.3-0.1.2 \ 11 | @react-native-oh-tpl/cookies@6.2.1-0.0.7 \ 12 | @react-native-oh-tpl/react-native-blob-util@0.19.6-0.0.13 \ 13 | @react-native-oh-tpl/react-native-device-info@11.1.0-0.0.5 \ 14 | @react-native-oh-tpl/react-native-gesture-handler@2.14.1-2.14.15 \ 15 | @react-native-oh-tpl/react-native-get-random-values@1.11.0-0.0.1 \ 16 | @react-native-oh-tpl/react-native-localize@3.1.0-0.0.1 \ 17 | @react-native-oh-tpl/react-native-safe-area-context@4.7.4-0.2.0 \ 18 | @react-native-oh-tpl/react-native-share@10.2.1-0.0.2 \ 19 | @react-native-oh-tpl/react-native-snackbar@2.7.1-0.0.2 \ 20 | @react-native-oh-tpl/react-native-svg@15.0.0-0.5.9 \ 21 | @react-native-oh-tpl/react-native-version-number@0.3.6-0.0.1 \ 22 | @react-native-oh-tpl/react-native-webview@13.10.2-0.2.32 \ 23 | @react-native-oh-tpl/slider@4.4.3-0.3.3 \ 24 | @thu-info/lib@../../packages/thu-info-lib \ 25 | rtn-network-utils@../../packages/RTNNetworkUtils \ 26 | react-native-svg@15.0.0 \ 27 | react-native-gesture-handler@2.14.1 \ 28 | react-native@0.72.17 29 | yarn patch-package 30 | --------------------------------------------------------------------------------