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