diff --git a/.env.example b/.env.example index d5a1612..c3e8201 100644 --- a/.env.example +++ b/.env.example @@ -1,7 +1,3 @@ -# Apple Development Team ID -# 用于 iOS 应用签名和打包 -APPLE_DEVELOPMENT_TEAM= - # Microsoft Clarity:复用 Cook 项目;显式留空可关闭统计 # 静态部署须在构建前设置;分叉项目请使用自己的项目 ID 和域名 NUXT_PUBLIC_CLARITY_PROJECT_ID=ks1ebw03i5 diff --git a/CLAUDE.md b/CLAUDE.md index fbdc1ef..69c9338 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Project Overview -Cook (食用手册) is a Chinese recipe web/mobile app for finding recipes based on available ingredients. Built with Nuxt 4 (Vue 3, CSR-only), Ionic UI, and Capacitor for native iOS/Android apps. The UI and content are in Chinese. +Cook (食用手册) is a Chinese recipe web app for finding recipes based on available ingredients. Built with Nuxt 4 (Vue 3, CSR-only) and Ionic UI, shipped as a Web app only (browser + YunLeFun container). The UI and content are in Chinese. ## Common Commands @@ -14,7 +14,7 @@ pnpm convert # Convert CSV recipe data → JSON (required before fi pnpm validate # Validate recipe.csv (ids, ingredient/tool dictionary, values, video ids) pnpm feedback:pull # Pull in-app feedback + search signals from CloudBase (needs .env) pnpm eval:search # Evaluate recommendation ranking against real search signals -pnpm fixtures # Regenerate shared Web/iOS recommendation fixtures (after data, alias or ranking changes) +pnpm fixtures # Regenerate shared recommendation fixtures (after data, alias or ranking changes) pnpm dev # Dev server on http://localhost:3333 pnpm lint # ESLint check (uses @antfu/eslint-config flat config) pnpm lint --fix # Auto-fix lint issues @@ -24,15 +24,6 @@ pnpm test -- --run # Run tests once without watch pnpm build # Full production build (convert + nuxt generate) ``` -### Mobile Development - -```bash -pnpm dev:ios # iOS with live reload (cap run ios -l) -pnpm dev:android # Android dev -pnpm ios # Open in Xcode -pnpm android # Open in Android Studio -``` - ## Architecture ### Data Pipeline @@ -43,14 +34,14 @@ Project decisions are recorded in `docs/decisions/` — read the relevant one be ### Monorepo Structure (pnpm workspaces) -Layout follows `docs/decisions/0003-native-ios-monorepo.md`; the plan is in `docs/dev/ios-roadmap.md`. +Layout follows `docs/decisions/0004-web-only.md`. -- **apps/web** — Nuxt app (main application). Root scripts (`pnpm dev`, `pnpm build`, `pnpm typecheck`) proxy to it; `pnpm build` copies `apps/web/dist` to the root `dist/` that deploy targets and Capacitor read -- **packages/data** — Data shared by Web and iOS: recipe CSV sources and the JSON generated from them (imported in the web app as `@cook/data/*`), the food dictionary (`food.json`), pantry defaults (`pantry.json`), ingredient aliases (`aliases.json`), and recommendation fixtures (`fixtures/recommend.json`, regenerate with `pnpm fixtures`) -- **packages/cook** — Types, recommendation/search logic (the TS core the iOS CookCore mirrors), and the CLI (`convert`, `search`) +- **apps/web** — Nuxt app (main application). Root scripts (`pnpm dev`, `pnpm build`, `pnpm typecheck`) proxy to it; `pnpm build` copies `apps/web/dist` to the root `dist/` that deploy targets read +- **packages/data** — Recipe CSV sources and the JSON generated from them (imported in the web app as `@cook/data/*`), the food dictionary (`food.json`), pantry defaults (`pantry.json`), ingredient aliases (`aliases.json`), and recommendation fixtures (`fixtures/recommend.json`, regenerate with `pnpm fixtures`) +- **packages/cook** — Types, recommendation/search logic, and the CLI (`convert`, `search`) - **docs** — VitePress documentation site - **scripts** — Build/utility scripts -- **Root** — Workspace tooling, tests (`test/`), Capacitor shell (`capacitor.config.ts`, `ios/`, `android/`), `cloudfunctions/` +- **Root** — Workspace tooling, tests (`test/`), `cloudfunctions/` ### App Source (`apps/web/app/`) @@ -84,13 +75,14 @@ pnpm test -- test/recipe.test.ts ## Code Style -Uses `@antfu/eslint-config` (flat config) with UnoCSS and formatters enabled. Pre-commit hook runs `lint-staged` via `simple-git-hooks`. Ignored paths include `packages/data/**/*.json`, `ios/`, `android/`, `dist/`. +Uses `@antfu/eslint-config` (flat config) with UnoCSS and formatters enabled. Pre-commit hook runs `lint-staged` via `simple-git-hooks`. Ignored paths include `packages/data/**/*.json`, `dist/`. ## Environment Variables See `.env.example`: -- `APPLE_DEVELOPMENT_TEAM` — iOS signing +- `NUXT_PUBLIC_CLARITY_PROJECT_ID` / `NUXT_PUBLIC_CLARITY_DOMAINS` — Microsoft Clarity statistics (leave the project ID empty to disable) +- `COOK_FEEDBACK_URL` / `COOK_FEEDBACK_TOKEN` — feedback export endpoint and its token (used by `pnpm feedback:pull`) ## Node/Package Manager diff --git a/README.md b/README.md index c2571b2..19db653 100644 --- a/README.md +++ b/README.md @@ -37,9 +37,8 @@ ### Features -~~本项目支持 PWA,使用浏览器打开时,可将其添加到主屏幕以获得近原生 APP 的体验。~~ - -我们正在开发新的 APP 版本,敬请期待。 +本项目只维护 Web 版本(浏览器 + 云乐坊 App 容器)。原生 iOS / Android 应用已随 +[0004 只保留 Web](/docs/decisions/0004-web-only) 移除,不再提供安装包。 ## 开发 @@ -73,10 +72,6 @@ pnpm search --stuff "鸡蛋,番茄" 更多 CLI 使用说明请查看 [Cook CLI 文档](https://cook.yunyoujun.cn/docs/dev/cli)。 -### 开发 APP - -> [Local Development](https://ionic.nuxtjs.org/cookbook/local-development) - ## 部署 ### 网站统计 diff --git a/android/.gitignore b/android/.gitignore deleted file mode 100644 index 2fdf46a..0000000 --- a/android/.gitignore +++ /dev/null @@ -1,102 +0,0 @@ -# Using Android gitignore template: https://github.com/github/gitignore/blob/HEAD/Android.gitignore - -# Built application files -*.apk -*.aar -*.ap_ -*.aab - -# Files for the ART/Dalvik VM -*.dex - -# Java class files -*.class - -# Generated files -bin/ -gen/ -out/ -# Uncomment the following line in case you need and you don't have the release build type files in your app -# release/ - -# Gradle files -.gradle/ -build/ - -# Local configuration file (sdk path, etc) -local.properties - -# Proguard folder generated by Eclipse -proguard/ - -# Log Files -*.log - -# Android Studio Navigation editor temp files -.navigation/ - -# Android Studio captures folder -captures/ - -# IntelliJ -*.iml -.idea/workspace.xml -.idea/tasks.xml -.idea/gradle.xml -.idea/assetWizardSettings.xml -.idea/dictionaries -.idea/libraries -# Android Studio 3 in .gitignore file. -.idea/caches -.idea/modules.xml -# Comment next line if keeping position of elements in Navigation Editor is relevant for you -.idea/navEditor.xml - -# Keystore files -*.jks -*.keystore -key.properties -keystore.properties - -# External native build folder generated in Android Studio 2.2 and later -.externalNativeBuild -.cxx/ - -# Google Services (e.g. APIs or Firebase) -# google-services.json - -# Freeline -freeline.py -freeline/ -freeline_project_description.json - -# fastlane -fastlane/report.xml -fastlane/Preview.html -fastlane/screenshots -fastlane/test_output -fastlane/readme.md - -# Version control -vcs.xml - -# lint -lint/intermediates/ -lint/generated/ -lint/outputs/ -lint/tmp/ -# lint/reports/ - -# Android Profiling -*.hprof - -# Cordova plugins for Capacitor -capacitor-cordova-android-plugins - -# Copied web assets -app/src/main/assets/public - -# Generated Config files -app/src/main/assets/capacitor.config.json -app/src/main/assets/capacitor.plugins.json -app/src/main/res/xml/config.xml diff --git a/android/app/.gitignore b/android/app/.gitignore deleted file mode 100644 index 043df80..0000000 --- a/android/app/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/build/* -!/build/.npmkeep diff --git a/android/app/build.gradle b/android/app/build.gradle deleted file mode 100644 index c9be30a..0000000 --- a/android/app/build.gradle +++ /dev/null @@ -1,54 +0,0 @@ -apply plugin: 'com.android.application' - -android { - namespace = "cn.yunyoujun.cook" - compileSdk = rootProject.ext.compileSdkVersion - defaultConfig { - applicationId = "cn.yunyoujun.cook" - minSdk = rootProject.ext.minSdkVersion - targetSdk = rootProject.ext.targetSdkVersion - versionCode = 2 - versionName = "1.0.1" - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - aaptOptions { - // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps. - // Default: https://android.googlesource.com/platform/frameworks/base/+/282e181b58cf72b6ca770dc7ca5f91f135444502/tools/aapt/AaptAssets.cpp#61 - ignoreAssetsPattern = '!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~' - } - } - buildTypes { - release { - minifyEnabled = false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - } -} - -repositories { - flatDir{ - dirs '../capacitor-cordova-android-plugins/src/main/libs', 'libs' - } -} - -dependencies { - implementation fileTree(include: ['*.jar'], dir: 'libs') - implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion" - implementation "androidx.coordinatorlayout:coordinatorlayout:$androidxCoordinatorLayoutVersion" - implementation "androidx.core:core-splashscreen:$coreSplashScreenVersion" - implementation project(':capacitor-android') - testImplementation "junit:junit:$junitVersion" - androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion" - androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion" - implementation project(':capacitor-cordova-android-plugins') -} - -apply from: 'capacitor.build.gradle' - -try { - def servicesJSON = file('google-services.json') - if (servicesJSON.text) { - apply plugin: 'com.google.gms.google-services' - } -} catch(Exception e) { - logger.info("google-services.json not found, google-services plugin not applied. Push Notifications won't work") -} diff --git a/android/app/capacitor.build.gradle b/android/app/capacitor.build.gradle deleted file mode 100644 index e5ade1d..0000000 --- a/android/app/capacitor.build.gradle +++ /dev/null @@ -1,25 +0,0 @@ -// DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN - -android { - compileOptions { - sourceCompatibility JavaVersion.VERSION_21 - targetCompatibility JavaVersion.VERSION_21 - } -} - -apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle" -dependencies { - implementation project(':capacitor-app') - implementation project(':capacitor-browser') - implementation project(':capacitor-dialog') - implementation project(':capacitor-haptics') - implementation project(':capacitor-keyboard') - implementation project(':capacitor-preferences') - implementation project(':capacitor-status-bar') - -} - - -if (hasProperty('postBuildExtras')) { - postBuildExtras() -} diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro deleted file mode 100644 index f1b4245..0000000 --- a/android/app/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile diff --git a/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java b/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java deleted file mode 100644 index f2c2217..0000000 --- a/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.getcapacitor.myapp; - -import static org.junit.Assert.*; - -import android.content.Context; -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.platform.app.InstrumentationRegistry; -import org.junit.Test; -import org.junit.runner.RunWith; - -/** - * Instrumented test, which will execute on an Android device. - * - * @see Testing documentation - */ -@RunWith(AndroidJUnit4.class) -public class ExampleInstrumentedTest { - - @Test - public void useAppContext() throws Exception { - // Context of the app under test. - Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); - - assertEquals("com.getcapacitor.app", appContext.getPackageName()); - } -} diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml deleted file mode 100644 index 0a3549e..0000000 --- a/android/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/android/app/src/main/java/cn/yunyoujun/cook/MainActivity.java b/android/app/src/main/java/cn/yunyoujun/cook/MainActivity.java deleted file mode 100644 index d5895da..0000000 --- a/android/app/src/main/java/cn/yunyoujun/cook/MainActivity.java +++ /dev/null @@ -1,5 +0,0 @@ -package cn.yunyoujun.cook; - -import com.getcapacitor.BridgeActivity; - -public class MainActivity extends BridgeActivity {} diff --git a/android/app/src/main/res/drawable-land-hdpi/splash.png b/android/app/src/main/res/drawable-land-hdpi/splash.png deleted file mode 100644 index e31573b..0000000 Binary files a/android/app/src/main/res/drawable-land-hdpi/splash.png and /dev/null differ diff --git a/android/app/src/main/res/drawable-land-mdpi/splash.png b/android/app/src/main/res/drawable-land-mdpi/splash.png deleted file mode 100644 index f7a6492..0000000 Binary files a/android/app/src/main/res/drawable-land-mdpi/splash.png and /dev/null differ diff --git a/android/app/src/main/res/drawable-land-xhdpi/splash.png b/android/app/src/main/res/drawable-land-xhdpi/splash.png deleted file mode 100644 index 8077255..0000000 Binary files a/android/app/src/main/res/drawable-land-xhdpi/splash.png and /dev/null differ diff --git a/android/app/src/main/res/drawable-land-xxhdpi/splash.png b/android/app/src/main/res/drawable-land-xxhdpi/splash.png deleted file mode 100644 index 14c6c8f..0000000 Binary files a/android/app/src/main/res/drawable-land-xxhdpi/splash.png and /dev/null differ diff --git a/android/app/src/main/res/drawable-land-xxxhdpi/splash.png b/android/app/src/main/res/drawable-land-xxxhdpi/splash.png deleted file mode 100644 index 244ca25..0000000 Binary files a/android/app/src/main/res/drawable-land-xxxhdpi/splash.png and /dev/null differ diff --git a/android/app/src/main/res/drawable-port-hdpi/splash.png b/android/app/src/main/res/drawable-port-hdpi/splash.png deleted file mode 100644 index 74faaa5..0000000 Binary files a/android/app/src/main/res/drawable-port-hdpi/splash.png and /dev/null differ diff --git a/android/app/src/main/res/drawable-port-mdpi/splash.png b/android/app/src/main/res/drawable-port-mdpi/splash.png deleted file mode 100644 index e944f4a..0000000 Binary files a/android/app/src/main/res/drawable-port-mdpi/splash.png and /dev/null differ diff --git a/android/app/src/main/res/drawable-port-xhdpi/splash.png b/android/app/src/main/res/drawable-port-xhdpi/splash.png deleted file mode 100644 index 564a82f..0000000 Binary files a/android/app/src/main/res/drawable-port-xhdpi/splash.png and /dev/null differ diff --git a/android/app/src/main/res/drawable-port-xxhdpi/splash.png b/android/app/src/main/res/drawable-port-xxhdpi/splash.png deleted file mode 100644 index bfabe68..0000000 Binary files a/android/app/src/main/res/drawable-port-xxhdpi/splash.png and /dev/null differ diff --git a/android/app/src/main/res/drawable-port-xxxhdpi/splash.png b/android/app/src/main/res/drawable-port-xxxhdpi/splash.png deleted file mode 100644 index 6929071..0000000 Binary files a/android/app/src/main/res/drawable-port-xxxhdpi/splash.png and /dev/null differ diff --git a/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml deleted file mode 100644 index c7bd21d..0000000 --- a/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - diff --git a/android/app/src/main/res/drawable/ic_launcher_background.xml b/android/app/src/main/res/drawable/ic_launcher_background.xml deleted file mode 100644 index d5fccc5..0000000 --- a/android/app/src/main/res/drawable/ic_launcher_background.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/android/app/src/main/res/drawable/splash.png b/android/app/src/main/res/drawable/splash.png deleted file mode 100644 index f7a6492..0000000 Binary files a/android/app/src/main/res/drawable/splash.png and /dev/null differ diff --git a/android/app/src/main/res/layout/activity_main.xml b/android/app/src/main/res/layout/activity_main.xml deleted file mode 100644 index b5ad138..0000000 --- a/android/app/src/main/res/layout/activity_main.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml deleted file mode 100644 index 036d09b..0000000 --- a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml deleted file mode 100644 index 036d09b..0000000 --- a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index cb3fd1b..0000000 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png deleted file mode 100644 index 4ce0249..0000000 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png deleted file mode 100644 index cb3fd1b..0000000 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index e5af8f0..0000000 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png deleted file mode 100644 index 56f644d..0000000 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png deleted file mode 100644 index e5af8f0..0000000 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index 376e845..0000000 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png deleted file mode 100644 index 8e9d672..0000000 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png deleted file mode 100644 index 376e845..0000000 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index b005fd3..0000000 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png deleted file mode 100644 index 66bbc8f..0000000 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png deleted file mode 100644 index b005fd3..0000000 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 7c8c750..0000000 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png deleted file mode 100644 index 8471f18..0000000 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png deleted file mode 100644 index 7c8c750..0000000 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/app/src/main/res/values/ic_launcher_background.xml b/android/app/src/main/res/values/ic_launcher_background.xml deleted file mode 100644 index c31f02d..0000000 --- a/android/app/src/main/res/values/ic_launcher_background.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - #07855F - diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml deleted file mode 100644 index a254c16..0000000 --- a/android/app/src/main/res/values/strings.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - 食用手册 - 食用手册 - cn.yunyoujun.cook - cn.yunyoujun.cook - diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml deleted file mode 100644 index be874e5..0000000 --- a/android/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/android/app/src/main/res/xml/file_paths.xml b/android/app/src/main/res/xml/file_paths.xml deleted file mode 100644 index bd0c4d8..0000000 --- a/android/app/src/main/res/xml/file_paths.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java b/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java deleted file mode 100644 index 0297327..0000000 --- a/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.getcapacitor.myapp; - -import static org.junit.Assert.*; - -import org.junit.Test; - -/** - * Example local unit test, which will execute on the development machine (host). - * - * @see Testing documentation - */ -public class ExampleUnitTest { - - @Test - public void addition_isCorrect() throws Exception { - assertEquals(4, 2 + 2); - } -} diff --git a/android/build.gradle b/android/build.gradle deleted file mode 100644 index f8f0e43..0000000 --- a/android/build.gradle +++ /dev/null @@ -1,29 +0,0 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. - -buildscript { - - repositories { - google() - mavenCentral() - } - dependencies { - classpath 'com.android.tools.build:gradle:8.13.0' - classpath 'com.google.gms:google-services:4.4.4' - - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files - } -} - -apply from: "variables.gradle" - -allprojects { - repositories { - google() - mavenCentral() - } -} - -task clean(type: Delete) { - delete rootProject.buildDir -} diff --git a/android/capacitor.settings.gradle b/android/capacitor.settings.gradle deleted file mode 100644 index 0bfba64..0000000 --- a/android/capacitor.settings.gradle +++ /dev/null @@ -1,24 +0,0 @@ -// DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN -include ':capacitor-android' -project(':capacitor-android').projectDir = new File('../node_modules/.pnpm/@capacitor+android@8.5.0_@capacitor+core@8.5.0/node_modules/@capacitor/android/capacitor') - -include ':capacitor-app' -project(':capacitor-app').projectDir = new File('../node_modules/.pnpm/@capacitor+app@8.1.1_@capacitor+core@8.5.0/node_modules/@capacitor/app/android') - -include ':capacitor-browser' -project(':capacitor-browser').projectDir = new File('../node_modules/.pnpm/@capacitor+browser@8.0.4_@capacitor+core@8.5.0/node_modules/@capacitor/browser/android') - -include ':capacitor-dialog' -project(':capacitor-dialog').projectDir = new File('../node_modules/.pnpm/@capacitor+dialog@8.0.1_@capacitor+core@8.5.0/node_modules/@capacitor/dialog/android') - -include ':capacitor-haptics' -project(':capacitor-haptics').projectDir = new File('../node_modules/.pnpm/@capacitor+haptics@8.0.2_@capacitor+core@8.5.0/node_modules/@capacitor/haptics/android') - -include ':capacitor-keyboard' -project(':capacitor-keyboard').projectDir = new File('../node_modules/.pnpm/@capacitor+keyboard@8.0.5_@capacitor+core@8.5.0/node_modules/@capacitor/keyboard/android') - -include ':capacitor-preferences' -project(':capacitor-preferences').projectDir = new File('../node_modules/.pnpm/@capacitor+preferences@8.0.1_@capacitor+core@8.5.0/node_modules/@capacitor/preferences/android') - -include ':capacitor-status-bar' -project(':capacitor-status-bar').projectDir = new File('../node_modules/.pnpm/@capacitor+status-bar@8.0.3_@capacitor+core@8.5.0/node_modules/@capacitor/status-bar/android') diff --git a/android/gradle.properties b/android/gradle.properties deleted file mode 100644 index 2e87c52..0000000 --- a/android/gradle.properties +++ /dev/null @@ -1,22 +0,0 @@ -# Project-wide Gradle settings. - -# IDE (e.g. Android Studio) users: -# Gradle settings configured through the IDE *will override* -# any settings specified in this file. - -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html - -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx1536m - -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true - -# AndroidX package structure to make it clearer which packages are bundled with the -# Android operating system, and which are packaged with your app's APK -# https://developer.android.com/topic/libraries/support-library/androidx-rn -android.useAndroidX=true diff --git a/android/gradle/wrapper/gradle-wrapper.jar b/android/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index a4b76b9..0000000 Binary files a/android/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 7705927..0000000 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,7 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-all.zip -networkTimeout=10000 -validateDistributionUrl=true -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/android/gradlew b/android/gradlew deleted file mode 100644 index f5feea6..0000000 --- a/android/gradlew +++ /dev/null @@ -1,252 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# SPDX-License-Identifier: Apache-2.0 -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s -' "$PWD" ) || exit - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - if ! command -v java >/dev/null 2>&1 - then - die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, -# and any embedded shellness will be escaped. -# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be -# treated as '${Hostname}' itself on the command line. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/android/gradlew.bat b/android/gradlew.bat deleted file mode 100644 index 9d21a21..0000000 --- a/android/gradlew.bat +++ /dev/null @@ -1,94 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem -@rem SPDX-License-Identifier: Apache-2.0 -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/android/settings.gradle b/android/settings.gradle deleted file mode 100644 index 3b4431d..0000000 --- a/android/settings.gradle +++ /dev/null @@ -1,5 +0,0 @@ -include ':app' -include ':capacitor-cordova-android-plugins' -project(':capacitor-cordova-android-plugins').projectDir = new File('./capacitor-cordova-android-plugins/') - -apply from: 'capacitor.settings.gradle' \ No newline at end of file diff --git a/android/variables.gradle b/android/variables.gradle deleted file mode 100644 index e14d745..0000000 --- a/android/variables.gradle +++ /dev/null @@ -1,16 +0,0 @@ -ext { - minSdkVersion = 24 - compileSdkVersion = 36 - targetSdkVersion = 36 - androidxActivityVersion = '1.11.0' - androidxAppCompatVersion = '1.7.1' - androidxCoordinatorLayoutVersion = '1.3.0' - androidxCoreVersion = '1.17.0' - androidxFragmentVersion = '1.8.9' - coreSplashScreenVersion = '1.2.0' - androidxWebkitVersion = '1.14.0' - junitVersion = '4.13.2' - androidxJunitVersion = '1.3.0' - androidxEspressoCoreVersion = '3.7.0' - cordovaAndroidVersion = '14.0.1' -} diff --git a/apps/web/app/adapters/yunlefunAuth.ts b/apps/web/app/adapters/yunlefunAuth.ts index ffda998..89af55d 100644 --- a/apps/web/app/adapters/yunlefunAuth.ts +++ b/apps/web/app/adapters/yunlefunAuth.ts @@ -2,23 +2,15 @@ import type { AcquisitionContext, SsoAuthorizationResult, } from '@yunlefun/sso' -import type { - NativeSsoTransaction, - NativeSsoTransactionStore, -} from '~/utils/nativeSso' import type { YunlefunAccount, YunlefunAuthorizationAdapter, - YunlefunAuthorizationResult, YunlefunIdentityAdapter, } from '~/utils/yunlefunAuth' import type { YunlefunSsoConfig } from '~/utils/yunlefunSsoConfig' -import { Browser } from '@capacitor/browser' -import { Preferences } from '@capacitor/preferences' import { adoptSsoCode, consumeSsoRedirect, - sanitizeAcquisitionContext, startSsoRedirect, } from '@yunlefun/sso' import { @@ -26,13 +18,6 @@ import { SsoIdentityAdoptionError, } from '@yunlefun/sso/browser' import { readCookAcquisition } from '~/utils/acquisition' -import { - consumeNativeSsoCallback, - isNativeSsoCallbackUrl, - openNativeSsoRedirect, -} from '~/utils/nativeSso' - -const NATIVE_TRANSACTION_KEY = 'cook:sso:v3:native-transaction' interface CloudbaseUser { avatar_url?: string @@ -94,11 +79,6 @@ interface CloudbaseModule { }) => CloudbaseApp } -export interface NativeYunlefunAuthorizationAdapter extends YunlefunAuthorizationAdapter { - cancel: () => Promise - consumeUrl: (url: string) => Promise -} - export interface CloudbaseIdentityDependencies { getAuth?: (env: string) => Promise } @@ -151,43 +131,6 @@ export function createWebYunlefunAuthorizationAdapter( } } -export function createNativeYunlefunAuthorizationAdapter( - config: YunlefunSsoConfig, - initialUrl: () => Promise, - readAcquisition: () => AcquisitionContext | null = readCookAcquisition, -): NativeYunlefunAuthorizationAdapter { - const store = createNativeTransactionStore() - - async function consumeUrl(url: string): Promise { - if (!isNativeSsoCallbackUrl(url, config.redirect.redirectUri)) - return null - - const result = await consumeNativeSsoCallback(url, store) - await Browser.close().catch(() => undefined) - return result - } - - return { - cancel: async () => store.clear(), - consumeInitial: async () => { - const url = await initialUrl() - return url ? consumeUrl(url) : null - }, - consumeUrl, - start: async () => { - const acquisition = readAcquisition() - await openNativeSsoRedirect({ - ...config.redirect, - prompt: 'consent', - ...(acquisition ? { acquisition } : {}), - }, store, async (url) => { - await Browser.open({ url }) - }) - return null - }, - } -} - export function createCloudbaseIdentityAdapter( config: YunlefunSsoConfig, dependencies: CloudbaseIdentityDependencies = {}, @@ -212,32 +155,6 @@ export function createCloudbaseIdentityAdapter( } } -function createNativeTransactionStore(): NativeSsoTransactionStore { - return { - clear: async () => { - await Preferences.remove({ key: NATIVE_TRANSACTION_KEY }) - }, - load: async () => { - const { value } = await Preferences.get({ key: NATIVE_TRANSACTION_KEY }) - if (!value) - return null - - try { - return readNativeTransaction(JSON.parse(value) as unknown) - } - catch { - return null - } - }, - save: async (transaction) => { - await Preferences.set({ - key: NATIVE_TRANSACTION_KEY, - value: JSON.stringify(transaction), - }) - }, - } -} - function getCloudbaseApp(env: string): Promise { if (cachedCloudbaseApp) { if (cachedCloudbaseEnv !== env) @@ -339,33 +256,3 @@ function normalizeAccount(user: CloudbaseUser | null | undefined): YunlefunAccou function firstString(...values: unknown[]): string | undefined { return values.find(value => typeof value === 'string' && value.trim())?.toString().trim() } - -function readNativeTransaction(value: unknown): NativeSsoTransaction | null { - if (!isRecord(value) - || typeof value.clientId !== 'string' - || typeof value.codeVerifier !== 'string' - || typeof value.createdAt !== 'number' - || typeof value.issuer !== 'string' - || typeof value.nonce !== 'string' - || typeof value.redirectUri !== 'string' - || !Array.isArray(value.scope) - || !value.scope.every(scope => typeof scope === 'string')) { - return null - } - - const acquisition = sanitizeAcquisitionContext(value.acquisition) - return { - clientId: value.clientId, - codeVerifier: value.codeVerifier, - createdAt: value.createdAt, - issuer: value.issuer, - nonce: value.nonce, - redirectUri: value.redirectUri, - scope: value.scope, - ...(acquisition ? { acquisition } : {}), - } -} - -function isRecord(value: unknown): value is Record { - return value !== null && typeof value === 'object' && !Array.isArray(value) -} diff --git a/apps/web/app/composables/dark.ts b/apps/web/app/composables/dark.ts index 7eb9779..acbd857 100644 --- a/apps/web/app/composables/dark.ts +++ b/apps/web/app/composables/dark.ts @@ -1,5 +1,3 @@ -import { Capacitor } from '@capacitor/core' -import { StatusBar, Style } from '@capacitor/status-bar' import { ionDarkClass } from '~/constants' /** @@ -13,24 +11,14 @@ export const useDarkMode = createSharedComposable(() => { const color = useColorMode() const isDark = computed(() => color.value === 'dark') - async function setLightMode() { + function setLightMode() { document.documentElement.classList.remove(ionDarkClass) syncThemeColor('#f2f2f6') - - if (Capacitor.isNativePlatform()) { - await StatusBar.setStyle({ style: Style.Light }) - await StatusBar.setBackgroundColor({ color: '#f2f2f6ff' }) - } } - async function setDarkMode() { + function setDarkMode() { document.documentElement.classList.add(ionDarkClass) syncThemeColor('#000000') - - if (Capacitor.isNativePlatform()) { - await StatusBar.setStyle({ style: Style.Dark }) - await StatusBar.setBackgroundColor({ color: '#ff000000' }) - } } return { @@ -39,7 +27,7 @@ export const useDarkMode = createSharedComposable(() => { setLightMode, setDarkMode, - async toggleDark() { + toggleDark() { const targetMode = color.value === 'dark' ? 'light' : 'dark' color.preference = targetMode diff --git a/apps/web/app/composables/useYunlefunAuth.ts b/apps/web/app/composables/useYunlefunAuth.ts index d1b2732..dd0807f 100644 --- a/apps/web/app/composables/useYunlefunAuth.ts +++ b/apps/web/app/composables/useYunlefunAuth.ts @@ -1,18 +1,12 @@ -import type { NativeYunlefunAuthorizationAdapter } from '~/adapters/yunlefunAuth' import type { YunlefunAuthController, YunlefunAuthSnapshot, } from '~/utils/yunlefunAuth' -import { App } from '@capacitor/app' -import { Browser } from '@capacitor/browser' -import { Capacitor } from '@capacitor/core' import { callCloudbaseFunction, createCloudbaseIdentityAdapter, - createNativeYunlefunAuthorizationAdapter, createWebYunlefunAuthorizationAdapter, } from '~/adapters/yunlefunAuth' -import { stripNativeSsoCallbackHash } from '~/utils/nativeSso' import { createYunlefunAuthController } from '~/utils/yunlefunAuth' import { resolveYunlefunSsoConfig } from '~/utils/yunlefunSsoConfig' @@ -21,8 +15,6 @@ interface YunlefunRuntimeConfig { yunlefunCloudbaseEnv?: string yunlefunSsoClientId?: string yunlefunSsoExchangeUrl?: string - yunlefunSsoNativeClientId?: string - yunlefunSsoNativeRedirectUri?: string yunlefunSsoOrigin?: string yunlefunSsoRedirectUri?: string yunlefunSsoRedirectUris?: string @@ -32,10 +24,7 @@ interface YunlefunRuntimeConfig { let controller: YunlefunAuthController | undefined let cloudbaseEnv = '' -let nativeAdapter: NativeYunlefunAuthorizationAdapter | undefined let initialization: Promise | undefined -let nativeUrlListenerInstalled = false -let handlingNativeCallback = false export function useYunlefunAuth() { const runtimeConfig = useRuntimeConfig() as unknown as YunlefunRuntimeConfig @@ -98,35 +87,16 @@ async function initializeOnce( if (!import.meta.client) return - const platform = Capacitor.isNativePlatform() ? 'native' : 'web' - if (platform === 'web' - && window.location.pathname === '/auth/callback' - && new URLSearchParams(window.location.search).get('platform') === 'native') { - const sanitizedPath = stripNativeSsoCallbackHash(window.location.href) - if (sanitizedPath) - window.history.replaceState(window.history.state, '', sanitizedPath) - configurationMessage.value = '未能自动返回 Cook,请确认已安装最新版应用后重新授权' - snapshot.value = { - account: null, - errorMessage: '', - status: 'signed-out', - } - return - } - const result = resolveYunlefunSsoConfig({ clientId: runtimeConfig.public.yunlefunSsoClientId, cloudbaseEnv: runtimeConfig.public.yunlefunCloudbaseEnv, exchangeUrl: runtimeConfig.public.yunlefunSsoExchangeUrl, - nativeClientId: runtimeConfig.public.yunlefunSsoNativeClientId, - nativeRedirectUri: runtimeConfig.public.yunlefunSsoNativeRedirectUri, redirectUri: runtimeConfig.public.yunlefunSsoRedirectUri, redirectUris: runtimeConfig.public.yunlefunSsoRedirectUris, scope: runtimeConfig.public.yunlefunSsoScope, ssoOrigin: runtimeConfig.public.yunlefunSsoOrigin, }, { currentOrigin: window.location.origin, - platform, }) if (!result.ok) { @@ -140,59 +110,14 @@ async function initializeOnce( } cloudbaseEnv = result.config.cloudbaseEnv - const web = createWebYunlefunAuthorizationAdapter(result.config) - nativeAdapter = createNativeYunlefunAuthorizationAdapter(result.config, async () => { - const launch = await App.getLaunchUrl() - return launch?.url ?? null - }) controller = createYunlefunAuthController({ identity: createCloudbaseIdentityAdapter(result.config), - native: nativeAdapter, - platform, - web, + web: createWebYunlefunAuthorizationAdapter(result.config), }) - if (platform === 'native' && !nativeUrlListenerInstalled) { - nativeUrlListenerInstalled = true - await App.addListener('appUrlOpen', async ({ url }) => { - if (!controller || !nativeAdapter) - return - - handlingNativeCallback = true - try { - const authorization = await nativeAdapter.consumeUrl(url) - if (!authorization) - return - - await controller.handleAuthorization(authorization) - publishSnapshot(snapshot) - if (controller.snapshot().status === 'signed-in') - await navigateTo('/my', { replace: true }) - } - finally { - handlingNativeCallback = false - } - }) - await Browser.addListener('browserFinished', async () => { - if (!controller - || handlingNativeCallback - || controller.snapshot().status !== 'signing-in') { - return - } - - await nativeAdapter?.cancel().catch(() => undefined) - await controller.handleAuthorization({ - ok: false, - reason: 'access_denied', - }) - publishSnapshot(snapshot) - }) - } - await controller.initialize() publishSnapshot(snapshot) - if (platform === 'web' - && window.location.pathname === '/auth/callback' + if (window.location.pathname === '/auth/callback' && controller.snapshot().status === 'signed-in') { await navigateTo('/my', { replace: true }) } diff --git a/apps/web/app/constants/acknowledgements.ts b/apps/web/app/constants/acknowledgements.ts index 989c448..b545698 100644 --- a/apps/web/app/constants/acknowledgements.ts +++ b/apps/web/app/constants/acknowledgements.ts @@ -101,12 +101,6 @@ export const acknowledgements: Acknowledgement[] = [ href: 'https://ionicframework.com', target: '_blank', }, - { - type: 'website', - label: 'Capacitor', - href: 'https://capacitorjs.com', - target: '_blank', - }, { type: 'website', label: 'VueUse', diff --git a/apps/web/app/constants/index.ts b/apps/web/app/constants/index.ts index e07d669..f2a9c1b 100644 --- a/apps/web/app/constants/index.ts +++ b/apps/web/app/constants/index.ts @@ -2,7 +2,7 @@ export const appName = '食用手册' export const appDescription = '好的,今天我们来做菜!' export const namespace = 'cook' -export const lastDbUpdated = '2026-10-20 11:02:43' +export const lastDbUpdated = '2026-10-21 12:26:30' export const icp = '苏ICP备17038157号' diff --git a/apps/web/app/pages/tabs.vue b/apps/web/app/pages/tabs.vue index 2db39fa..ac34cd0 100644 --- a/apps/web/app/pages/tabs.vue +++ b/apps/web/app/pages/tabs.vue @@ -1,7 +1,4 @@