openuispec 0.2.10 → 0.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/check/index.ts +17 -0
- package/cli/index.ts +21 -3
- package/cli/init.ts +224 -10
- package/docs/cli.md +13 -8
- package/docs/file-formats.md +36 -0
- package/docs/implementation-notes.md +7 -0
- package/drift/index.ts +281 -40
- package/mcp-server/index.ts +179 -119
- package/mcp-server/screenshot.ts +19 -4
- package/package.json +5 -2
- package/prepare/index.ts +155 -18
- package/schema/openuispec.schema.json +59 -0
- package/schema/semantic-lint.ts +25 -1
- package/scripts/take-all-screenshots.ts +507 -0
- package/spec/openuispec-v0.1.md +13 -0
- package/status/index.ts +72 -2
- package/examples/social-app/.mcp.json +0 -10
- package/examples/social-app/AGENTS.md +0 -124
- package/examples/social-app/CLAUDE.md +0 -124
- package/examples/social-app/backend/.gitkeep +0 -1
- package/examples/social-app/generated/android/social-app/app/.paparazzi-hashes.json +0 -3
- package/examples/social-app/generated/android/social-app/app/build.gradle.kts +0 -94
- package/examples/social-app/generated/android/social-app/app/src/main/AndroidManifest.xml +0 -26
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/AppContainer.kt +0 -20
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/MainActivity.kt +0 -35
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/SocialAppApplication.kt +0 -13
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/data/MockData.kt +0 -98
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/data/preferences/AppPreferences.kt +0 -19
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/data/preferences/DataStorePreferencesRepository.kt +0 -68
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/data/preferences/PreferencesRepository.kt +0 -15
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/model/Models.kt +0 -34
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/MainShell.kt +0 -390
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/components/Components.kt +0 -234
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/components/ContractPrimitives.kt +0 -641
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/navigation/RootComponent.kt +0 -113
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/ChatDetailScreen.kt +0 -212
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/CreatePostScreen.kt +0 -113
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/DiscoverScreen.kt +0 -137
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/EditProfileScreen.kt +0 -180
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/HomeFeedScreen.kt +0 -169
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/MessagesInboxScreen.kt +0 -85
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/NotificationsScreen.kt +0 -74
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/PostDetailScreen.kt +0 -293
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/ProfileSelfScreen.kt +0 -116
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/SearchResultsScreen.kt +0 -161
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/SettingsScreen.kt +0 -164
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/SettingsStore.kt +0 -95
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/screens/UserProfileScreen.kt +0 -123
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/theme/Color.kt +0 -33
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/theme/Shape.kt +0 -41
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/theme/Spacing.kt +0 -20
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/theme/Theme.kt +0 -82
- package/examples/social-app/generated/android/social-app/app/src/main/java/com/social/app/ui/theme/Type.kt +0 -60
- package/examples/social-app/generated/android/social-app/app/src/main/res/drawable/ic_launcher_foreground.xml +0 -9
- package/examples/social-app/generated/android/social-app/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +0 -5
- package/examples/social-app/generated/android/social-app/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +0 -5
- package/examples/social-app/generated/android/social-app/app/src/main/res/values/strings.xml +0 -91
- package/examples/social-app/generated/android/social-app/app/src/main/res/values/themes.xml +0 -10
- package/examples/social-app/generated/android/social-app/app/src/main/res/values-ru/strings.xml +0 -79
- package/examples/social-app/generated/android/social-app/app/src/main/res/values-uz/strings.xml +0 -79
- package/examples/social-app/generated/android/social-app/app/src/main/xml/AndroidManifest.xml +0 -23
- package/examples/social-app/generated/android/social-app/app/src/test/kotlin/com/social/app/screenshots/HomeFeedScreenshotTest.kt +0 -34
- package/examples/social-app/generated/android/social-app/build.gradle.kts +0 -7
- package/examples/social-app/generated/android/social-app/gradle/libs.versions.toml +0 -50
- package/examples/social-app/generated/android/social-app/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/examples/social-app/generated/android/social-app/gradle/wrapper/gradle-wrapper.properties +0 -8
- package/examples/social-app/generated/android/social-app/gradle.properties +0 -11
- package/examples/social-app/generated/android/social-app/gradlew +0 -248
- package/examples/social-app/generated/android/social-app/settings.gradle.kts +0 -27
- package/examples/social-app/generated/web/social-app/index.html +0 -12
- package/examples/social-app/generated/web/social-app/package-lock.json +0 -2517
- package/examples/social-app/generated/web/social-app/package.json +0 -27
- package/examples/social-app/generated/web/social-app/src/app/App.tsx +0 -58
- package/examples/social-app/generated/web/social-app/src/components/Shell.tsx +0 -259
- package/examples/social-app/generated/web/social-app/src/components/cards.tsx +0 -317
- package/examples/social-app/generated/web/social-app/src/components/ui.tsx +0 -340
- package/examples/social-app/generated/web/social-app/src/flows/CreatePostFlow.tsx +0 -86
- package/examples/social-app/generated/web/social-app/src/i18n.tsx +0 -59
- package/examples/social-app/generated/web/social-app/src/lib/icons.tsx +0 -85
- package/examples/social-app/generated/web/social-app/src/lib/tokens.ts +0 -70
- package/examples/social-app/generated/web/social-app/src/lib/utils.ts +0 -97
- package/examples/social-app/generated/web/social-app/src/locales/en.json +0 -67
- package/examples/social-app/generated/web/social-app/src/locales/ru.json +0 -67
- package/examples/social-app/generated/web/social-app/src/locales/uz.json +0 -67
- package/examples/social-app/generated/web/social-app/src/main.tsx +0 -16
- package/examples/social-app/generated/web/social-app/src/screens/ChatDetailScreen.tsx +0 -90
- package/examples/social-app/generated/web/social-app/src/screens/DiscoverScreen.tsx +0 -86
- package/examples/social-app/generated/web/social-app/src/screens/EditProfileScreen.tsx +0 -57
- package/examples/social-app/generated/web/social-app/src/screens/HomeFeedScreen.tsx +0 -103
- package/examples/social-app/generated/web/social-app/src/screens/MessagesInboxScreen.tsx +0 -52
- package/examples/social-app/generated/web/social-app/src/screens/NotificationsScreen.tsx +0 -41
- package/examples/social-app/generated/web/social-app/src/screens/PostDetailScreen.tsx +0 -115
- package/examples/social-app/generated/web/social-app/src/screens/ProfileSelfScreen.tsx +0 -57
- package/examples/social-app/generated/web/social-app/src/screens/ProfileUserScreen.tsx +0 -76
- package/examples/social-app/generated/web/social-app/src/screens/SearchResultsScreen.tsx +0 -96
- package/examples/social-app/generated/web/social-app/src/screens/SettingsScreen.tsx +0 -79
- package/examples/social-app/generated/web/social-app/src/state/store.ts +0 -592
- package/examples/social-app/generated/web/social-app/src/styles.css +0 -125
- package/examples/social-app/generated/web/social-app/src/vite-env.d.ts +0 -1
- package/examples/social-app/generated/web/social-app/tsconfig.json +0 -22
- package/examples/social-app/generated/web/social-app/tsconfig.node.json +0 -13
- package/examples/social-app/generated/web/social-app/tsconfig.node.tsbuildinfo +0 -1
- package/examples/social-app/generated/web/social-app/tsconfig.tsbuildinfo +0 -1
- package/examples/social-app/generated/web/social-app/vite.config.d.ts +0 -2
- package/examples/social-app/generated/web/social-app/vite.config.js +0 -6
- package/examples/social-app/generated/web/social-app/vite.config.ts +0 -7
- package/examples/social-app/package.json +0 -13
- package/examples/social-app/take-web-screenshots.ts +0 -97
- package/examples/taskflow/.codex/config.toml +0 -4
- package/examples/taskflow/.mcp.json +0 -10
- package/examples/taskflow/AGENTS.md +0 -124
- package/examples/taskflow/CLAUDE.md +0 -124
- package/examples/taskflow/backend/.gitkeep +0 -1
- package/examples/taskflow/generated/android/TaskFlow/README.md +0 -43
- package/examples/taskflow/generated/android/TaskFlow/app/build.gradle.kts +0 -76
- package/examples/taskflow/generated/android/TaskFlow/app/proguard-rules.pro +0 -1
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/AndroidManifest.xml +0 -21
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/MainActivity.kt +0 -19
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/TaskFlowApp.kt +0 -283
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/model/DomainModels.kt +0 -106
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/model/SampleData.kt +0 -57
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/components/Common.kt +0 -109
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/screens/HomeScreen.kt +0 -112
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/screens/ProjectsScreen.kt +0 -61
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/screens/SettingsScreen.kt +0 -82
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/screens/TaskDetailScreen.kt +0 -111
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/sheets/Sheets.kt +0 -77
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/theme/Color.kt +0 -30
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/theme/Theme.kt +0 -86
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/theme/Type.kt +0 -57
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/res/values/strings.xml +0 -155
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/res/values/themes.xml +0 -4
- package/examples/taskflow/generated/android/TaskFlow/build.gradle.kts +0 -5
- package/examples/taskflow/generated/android/TaskFlow/gradle/gradle-daemon-jvm.properties +0 -12
- package/examples/taskflow/generated/android/TaskFlow/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/examples/taskflow/generated/android/TaskFlow/gradle/wrapper/gradle-wrapper.properties +0 -7
- package/examples/taskflow/generated/android/TaskFlow/gradle.properties +0 -4
- package/examples/taskflow/generated/android/TaskFlow/gradlew +0 -18
- package/examples/taskflow/generated/android/TaskFlow/gradlew.bat +0 -12
- package/examples/taskflow/generated/android/TaskFlow/settings.gradle.kts +0 -18
- package/examples/taskflow/generated/ios/TaskFlow/README.md +0 -21
- package/examples/taskflow/generated/ios/TaskFlow/Resources/en.lproj/Localizable.strings +0 -115
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/App/TaskFlowApp.swift +0 -24
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Components/AppChrome.swift +0 -150
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Flows/TaskEditorSheet.swift +0 -220
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Models/DomainModels.swift +0 -122
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Screens/CalendarView.swift +0 -21
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Screens/HomeView.swift +0 -201
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Screens/ProfileEditView.swift +0 -48
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Screens/ProjectDetailView.swift +0 -59
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Screens/ProjectsView.swift +0 -63
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Screens/SettingsView.swift +0 -85
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Screens/TaskDetailView.swift +0 -219
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Support/AppModel.swift +0 -320
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Support/AppSupport.swift +0 -41
- package/examples/taskflow/generated/ios/TaskFlow/project.yml +0 -31
- package/examples/taskflow/generated/web/TaskFlow/README.md +0 -19
- package/examples/taskflow/generated/web/TaskFlow/index.html +0 -12
- package/examples/taskflow/generated/web/TaskFlow/package-lock.json +0 -1908
- package/examples/taskflow/generated/web/TaskFlow/package.json +0 -24
- package/examples/taskflow/generated/web/TaskFlow/src/App.tsx +0 -58
- package/examples/taskflow/generated/web/TaskFlow/src/AppShell.tsx +0 -55
- package/examples/taskflow/generated/web/TaskFlow/src/components/Common.tsx +0 -82
- package/examples/taskflow/generated/web/TaskFlow/src/components/Modals.tsx +0 -191
- package/examples/taskflow/generated/web/TaskFlow/src/components/Nav.tsx +0 -41
- package/examples/taskflow/generated/web/TaskFlow/src/generated/messages.ts +0 -131
- package/examples/taskflow/generated/web/TaskFlow/src/hooks.ts +0 -25
- package/examples/taskflow/generated/web/TaskFlow/src/i18n.ts +0 -39
- package/examples/taskflow/generated/web/TaskFlow/src/locales.en.json +0 -111
- package/examples/taskflow/generated/web/TaskFlow/src/main.tsx +0 -13
- package/examples/taskflow/generated/web/TaskFlow/src/screens/HomeScreen.tsx +0 -111
- package/examples/taskflow/generated/web/TaskFlow/src/screens/ProjectsScreen.tsx +0 -82
- package/examples/taskflow/generated/web/TaskFlow/src/screens/SettingsScreens.tsx +0 -132
- package/examples/taskflow/generated/web/TaskFlow/src/screens/TaskDetail.tsx +0 -105
- package/examples/taskflow/generated/web/TaskFlow/src/store.ts +0 -216
- package/examples/taskflow/generated/web/TaskFlow/src/styles.css +0 -617
- package/examples/taskflow/generated/web/TaskFlow/src/types.ts +0 -64
- package/examples/taskflow/generated/web/TaskFlow/src/utils.ts +0 -78
- package/examples/taskflow/generated/web/TaskFlow/tsconfig.json +0 -21
- package/examples/taskflow/generated/web/TaskFlow/vite.config.ts +0 -6
- package/examples/todo-orbit/.codex/config.toml +0 -4
- package/examples/todo-orbit/.mcp.json +0 -10
- package/examples/todo-orbit/AGENTS.md +0 -124
- package/examples/todo-orbit/CLAUDE.md +0 -124
- package/examples/todo-orbit/backend/.gitkeep +0 -1
- package/examples/todo-orbit/generated/android/Todo Orbit/README.md +0 -14
- package/examples/todo-orbit/generated/android/Todo Orbit/app/build.gradle.kts +0 -58
- package/examples/todo-orbit/generated/android/Todo Orbit/app/proguard-rules.pro +0 -1
- package/examples/todo-orbit/generated/android/Todo Orbit/app/src/main/AndroidManifest.xml +0 -20
- package/examples/todo-orbit/generated/android/Todo Orbit/app/src/main/java/uz/rsteam/todoorbit/MainActivity.kt +0 -14
- package/examples/todo-orbit/generated/android/Todo Orbit/app/src/main/java/uz/rsteam/todoorbit/TodoOrbitApp.kt +0 -345
- package/examples/todo-orbit/generated/android/Todo Orbit/app/src/main/java/uz/rsteam/todoorbit/support/AppLogic.kt +0 -231
- package/examples/todo-orbit/generated/android/Todo Orbit/app/src/main/java/uz/rsteam/todoorbit/support/Models.kt +0 -169
- package/examples/todo-orbit/generated/android/Todo Orbit/app/src/main/java/uz/rsteam/todoorbit/support/Strings.kt +0 -8
- package/examples/todo-orbit/generated/android/Todo Orbit/app/src/main/java/uz/rsteam/todoorbit/ui/components/CommonComponents.kt +0 -236
- package/examples/todo-orbit/generated/android/Todo Orbit/app/src/main/java/uz/rsteam/todoorbit/ui/screens/AnalyticsScreen.kt +0 -193
- package/examples/todo-orbit/generated/android/Todo Orbit/app/src/main/java/uz/rsteam/todoorbit/ui/screens/SettingsScreen.kt +0 -102
- package/examples/todo-orbit/generated/android/Todo Orbit/app/src/main/java/uz/rsteam/todoorbit/ui/screens/TasksScreen.kt +0 -347
- package/examples/todo-orbit/generated/android/Todo Orbit/app/src/main/java/uz/rsteam/todoorbit/ui/sheets/EditorSheets.kt +0 -347
- package/examples/todo-orbit/generated/android/Todo Orbit/app/src/main/java/uz/rsteam/todoorbit/ui/theme/TodoOrbitTheme.kt +0 -59
- package/examples/todo-orbit/generated/android/Todo Orbit/app/src/main/res/values/strings.xml +0 -149
- package/examples/todo-orbit/generated/android/Todo Orbit/app/src/main/res/values-ru/strings.xml +0 -155
- package/examples/todo-orbit/generated/android/Todo Orbit/build.gradle.kts +0 -4
- package/examples/todo-orbit/generated/android/Todo Orbit/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/examples/todo-orbit/generated/android/Todo Orbit/gradle/wrapper/gradle-wrapper.properties +0 -7
- package/examples/todo-orbit/generated/android/Todo Orbit/gradle.properties +0 -4
- package/examples/todo-orbit/generated/android/Todo Orbit/gradlew +0 -248
- package/examples/todo-orbit/generated/android/Todo Orbit/gradlew.bat +0 -93
- package/examples/todo-orbit/generated/android/Todo Orbit/settings.gradle.kts +0 -18
- package/examples/todo-orbit/generated/ios/Todo Orbit/.screenshot-uitest/Sources/ScreenshotUITest.swift +0 -36
- package/examples/todo-orbit/generated/ios/Todo Orbit/README.md +0 -29
- package/examples/todo-orbit/generated/ios/Todo Orbit/Resources/en.lproj/Localizable.strings +0 -119
- package/examples/todo-orbit/generated/ios/Todo Orbit/Resources/ru.lproj/Localizable.strings +0 -119
- package/examples/todo-orbit/generated/ios/Todo Orbit/Sources/TodoOrbit/App/TodoOrbitApp.swift +0 -50
- package/examples/todo-orbit/generated/ios/Todo Orbit/Sources/TodoOrbit/Components/OrbitChrome.swift +0 -204
- package/examples/todo-orbit/generated/ios/Todo Orbit/Sources/TodoOrbit/Components/SchedulePreviewView.swift +0 -126
- package/examples/todo-orbit/generated/ios/Todo Orbit/Sources/TodoOrbit/Components/TrendChartView.swift +0 -70
- package/examples/todo-orbit/generated/ios/Todo Orbit/Sources/TodoOrbit/Flows/RecurringRuleSheet.swift +0 -126
- package/examples/todo-orbit/generated/ios/Todo Orbit/Sources/TodoOrbit/Flows/TaskEditorSheet.swift +0 -61
- package/examples/todo-orbit/generated/ios/Todo Orbit/Sources/TodoOrbit/Models/DomainModels.swift +0 -238
- package/examples/todo-orbit/generated/ios/Todo Orbit/Sources/TodoOrbit/Screens/AnalyticsView.swift +0 -94
- package/examples/todo-orbit/generated/ios/Todo Orbit/Sources/TodoOrbit/Screens/SettingsView.swift +0 -76
- package/examples/todo-orbit/generated/ios/Todo Orbit/Sources/TodoOrbit/Screens/TasksHomeView.swift +0 -364
- package/examples/todo-orbit/generated/ios/Todo Orbit/Sources/TodoOrbit/Support/AppModel.swift +0 -324
- package/examples/todo-orbit/generated/ios/Todo Orbit/TodoOrbit.xcodeproj/project.pbxproj +0 -439
- package/examples/todo-orbit/generated/ios/Todo Orbit/TodoOrbit.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
- package/examples/todo-orbit/generated/ios/Todo Orbit/TodoOrbit.xcodeproj/xcshareddata/xcschemes/TodoOrbit.xcscheme +0 -89
- package/examples/todo-orbit/generated/ios/Todo Orbit/project.yml +0 -32
- package/examples/todo-orbit/generated/web/Todo Orbit/index.html +0 -16
- package/examples/todo-orbit/generated/web/Todo Orbit/package-lock.json +0 -1087
- package/examples/todo-orbit/generated/web/Todo Orbit/package.json +0 -24
- package/examples/todo-orbit/generated/web/Todo Orbit/src/App.tsx +0 -2167
- package/examples/todo-orbit/generated/web/Todo Orbit/src/main.tsx +0 -13
- package/examples/todo-orbit/generated/web/Todo Orbit/src/styles.css +0 -926
- package/examples/todo-orbit/generated/web/Todo Orbit/tsconfig.json +0 -19
- package/examples/todo-orbit/generated/web/Todo Orbit/vite.config.ts +0 -6
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
"nav.tasks" = "Tasks";
|
|
2
|
-
"nav.analytics" = "Analytics";
|
|
3
|
-
"nav.settings" = "Settings";
|
|
4
|
-
"home.title" = "Today, organized";
|
|
5
|
-
"home.summary.done" = "Everything is done";
|
|
6
|
-
"home.summary.remaining" = "%d tasks left out of %d";
|
|
7
|
-
"home.search_placeholder" = "Search by title or notes";
|
|
8
|
-
"home.filter_all" = "All";
|
|
9
|
-
"home.filter_open" = "Open";
|
|
10
|
-
"home.filter_done" = "Done";
|
|
11
|
-
"home.new_task" = "New task";
|
|
12
|
-
"home.empty_title" = "Nothing to do";
|
|
13
|
-
"analytics.title" = "Task analytics";
|
|
14
|
-
"analytics.subtitle" = "Monitor throughput, overdue work, and completion trends.";
|
|
15
|
-
"analytics.period_week" = "Week";
|
|
16
|
-
"analytics.period_month" = "Month";
|
|
17
|
-
"analytics.period_quarter" = "Quarter";
|
|
18
|
-
"analytics.completed_today" = "Completed today";
|
|
19
|
-
"analytics.open_tasks" = "Open tasks";
|
|
20
|
-
"analytics.overdue_tasks" = "Overdue";
|
|
21
|
-
"analytics.completion_rate" = "Completion rate";
|
|
22
|
-
"analytics.trend_subtitle" = "Completion trend";
|
|
23
|
-
"analytics.legend_completed" = "Completed";
|
|
24
|
-
"analytics.legend_created" = "Created";
|
|
25
|
-
"analytics.empty_trend" = "No trend data yet.";
|
|
26
|
-
"analytics.overdue_section" = "Overdue review";
|
|
27
|
-
"analytics.overdue_subtitle" = "Tasks that need attention first.";
|
|
28
|
-
"analytics.empty_overdue_body" = "Everything important is on track.";
|
|
29
|
-
"task_detail.title" = "Task details";
|
|
30
|
-
"task_detail.status" = "Status";
|
|
31
|
-
"task_detail.priority" = "Priority";
|
|
32
|
-
"task_detail.notes" = "Notes";
|
|
33
|
-
"task_detail.due_date" = "Due date";
|
|
34
|
-
"task_detail.no_due_date" = "No deadline";
|
|
35
|
-
"task_detail.created" = "Created";
|
|
36
|
-
"task_detail.updated" = "Updated";
|
|
37
|
-
"task_detail.edit" = "Edit task";
|
|
38
|
-
"task_detail.toggle_status" = "Toggle status";
|
|
39
|
-
"task_detail.more_info" = "More info";
|
|
40
|
-
"task_detail.delete" = "Delete task";
|
|
41
|
-
"task_detail.delete_title" = "Delete this task?";
|
|
42
|
-
"task_detail.delete_message" = "This action cannot be undone.";
|
|
43
|
-
"task_detail.updated_feedback" = "Task updated";
|
|
44
|
-
"task_detail.deleted_feedback" = "Task deleted";
|
|
45
|
-
"settings.title" = "Preferences";
|
|
46
|
-
"settings.subtitle" = "Adjust language and theme for every platform target.";
|
|
47
|
-
"settings.language" = "Language";
|
|
48
|
-
"settings.language_en" = "English";
|
|
49
|
-
"settings.language_ru" = "Russian";
|
|
50
|
-
"settings.theme" = "Theme";
|
|
51
|
-
"settings.theme_light" = "Light";
|
|
52
|
-
"settings.theme_dark" = "Dark";
|
|
53
|
-
"settings.reminders" = "Due date reminders";
|
|
54
|
-
"settings.daily_summary" = "Daily summary";
|
|
55
|
-
"settings.automation_title" = "Automation";
|
|
56
|
-
"settings.automation_subtitle" = "Create recurring task rules to stress conditional forms and validation.";
|
|
57
|
-
"settings.automation_create_rule" = "Create recurring rule";
|
|
58
|
-
"settings.save" = "Save changes";
|
|
59
|
-
"settings.saved" = "Preferences updated";
|
|
60
|
-
"create_task.title" = "New task";
|
|
61
|
-
"create_task.field_title" = "Title";
|
|
62
|
-
"create_task.field_notes" = "Notes";
|
|
63
|
-
"create_task.field_priority" = "Priority";
|
|
64
|
-
"create_task.field_due_date" = "Due date";
|
|
65
|
-
"create_task.success" = "Task created";
|
|
66
|
-
"edit_task.title" = "Edit task";
|
|
67
|
-
"edit_task.field_title" = "Title";
|
|
68
|
-
"edit_task.field_notes" = "Notes";
|
|
69
|
-
"edit_task.field_priority" = "Priority";
|
|
70
|
-
"edit_task.field_due_date" = "Due date";
|
|
71
|
-
"edit_task.success" = "Task saved";
|
|
72
|
-
"recurring_rule.title" = "Recurring rule";
|
|
73
|
-
"recurring_rule.field_name" = "Rule name";
|
|
74
|
-
"recurring_rule.field_confirm_name" = "Confirm rule name";
|
|
75
|
-
"recurring_rule.field_cadence" = "Cadence";
|
|
76
|
-
"recurring_rule.cadence_daily" = "Daily";
|
|
77
|
-
"recurring_rule.cadence_weekly" = "Weekly";
|
|
78
|
-
"recurring_rule.cadence_monthly" = "Monthly";
|
|
79
|
-
"recurring_rule.field_interval" = "Repeat every";
|
|
80
|
-
"recurring_rule.field_weekday" = "Weekday";
|
|
81
|
-
"recurring_rule.field_month_day" = "Day of month";
|
|
82
|
-
"recurring_rule.field_start_date" = "Start date";
|
|
83
|
-
"recurring_rule.field_has_end_date" = "Set an end date";
|
|
84
|
-
"recurring_rule.field_end_date" = "End date";
|
|
85
|
-
"recurring_rule.field_remind_at" = "Reminder time";
|
|
86
|
-
"recurring_rule.field_enable_summary" = "Attach daily summary delivery";
|
|
87
|
-
"recurring_rule.field_summary_channel" = "Summary channel";
|
|
88
|
-
"recurring_rule.summary_push" = "Push notification";
|
|
89
|
-
"recurring_rule.summary_email" = "Email";
|
|
90
|
-
"recurring_rule.success" = "Recurring rule created";
|
|
91
|
-
"recurring_preview.title" = "Upcoming schedule preview";
|
|
92
|
-
"recurring_preview.invalid" = "Complete the cadence and date fields to preview the schedule.";
|
|
93
|
-
"recurring_preview.empty" = "No upcoming dates can be generated from this rule.";
|
|
94
|
-
"priority.low" = "Low";
|
|
95
|
-
"priority.medium" = "Medium";
|
|
96
|
-
"priority.high" = "High";
|
|
97
|
-
"status.open" = "Open";
|
|
98
|
-
"status.done" = "Done";
|
|
99
|
-
"weekday.mon" = "Monday";
|
|
100
|
-
"weekday.tue" = "Tuesday";
|
|
101
|
-
"weekday.wed" = "Wednesday";
|
|
102
|
-
"weekday.thu" = "Thursday";
|
|
103
|
-
"weekday.fri" = "Friday";
|
|
104
|
-
"weekday.sat" = "Saturday";
|
|
105
|
-
"weekday.sun" = "Sunday";
|
|
106
|
-
"validation.min_length" = "Must be at least %d characters";
|
|
107
|
-
"validation.min_value" = "Must be at least %d";
|
|
108
|
-
"validation.max_value" = "Must be no more than %d";
|
|
109
|
-
"validation.rule_name_min_length" = "Rule name must be at least %d characters";
|
|
110
|
-
"validation.rule_name_reserved" = "The default name is reserved. Choose a more specific label.";
|
|
111
|
-
"validation.rule_name_taken" = "A recurring rule with this name already exists.";
|
|
112
|
-
"validation.match_field" = "Fields do not match";
|
|
113
|
-
"validation.end_date_after_start" = "End date must be the same as or later than the start date.";
|
|
114
|
-
"validation.time_format" = "Use a 24-hour time like 09:00";
|
|
115
|
-
"validation.month_day_max" = "Choose a day between 1 and 28";
|
|
116
|
-
"validation.fix_errors" = "Fix the highlighted fields before saving.";
|
|
117
|
-
"validation.required" = "This field is required.";
|
|
118
|
-
"common.cancel" = "Cancel";
|
|
119
|
-
"common.delete" = "Delete";
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
"nav.tasks" = "Задачи";
|
|
2
|
-
"nav.analytics" = "Аналитика";
|
|
3
|
-
"nav.settings" = "Настройки";
|
|
4
|
-
"home.title" = "Сегодня все под контролем";
|
|
5
|
-
"home.summary.done" = "Все задачи закрыты";
|
|
6
|
-
"home.summary.remaining" = "Осталось %d из %d";
|
|
7
|
-
"home.search_placeholder" = "Искать по названию или заметкам";
|
|
8
|
-
"home.filter_all" = "Все";
|
|
9
|
-
"home.filter_open" = "Открытые";
|
|
10
|
-
"home.filter_done" = "Выполненные";
|
|
11
|
-
"home.new_task" = "Новая задача";
|
|
12
|
-
"home.empty_title" = "Список пуст";
|
|
13
|
-
"analytics.title" = "Аналитика задач";
|
|
14
|
-
"analytics.subtitle" = "Следите за выполнением, просроченными задачами и динамикой.";
|
|
15
|
-
"analytics.period_week" = "Неделя";
|
|
16
|
-
"analytics.period_month" = "Месяц";
|
|
17
|
-
"analytics.period_quarter" = "Квартал";
|
|
18
|
-
"analytics.completed_today" = "Выполнено сегодня";
|
|
19
|
-
"analytics.open_tasks" = "Открытые задачи";
|
|
20
|
-
"analytics.overdue_tasks" = "Просрочено";
|
|
21
|
-
"analytics.completion_rate" = "Процент выполнения";
|
|
22
|
-
"analytics.trend_subtitle" = "Динамика выполнения";
|
|
23
|
-
"analytics.legend_completed" = "Выполнено";
|
|
24
|
-
"analytics.legend_created" = "Создано";
|
|
25
|
-
"analytics.empty_trend" = "Данные тренда пока отсутствуют.";
|
|
26
|
-
"analytics.overdue_section" = "Просроченные задачи";
|
|
27
|
-
"analytics.overdue_subtitle" = "Задачи, которым нужно уделить внимание в первую очередь.";
|
|
28
|
-
"analytics.empty_overdue_body" = "Все важные задачи идут по плану.";
|
|
29
|
-
"task_detail.title" = "Детали задачи";
|
|
30
|
-
"task_detail.status" = "Статус";
|
|
31
|
-
"task_detail.priority" = "Приоритет";
|
|
32
|
-
"task_detail.notes" = "Заметки";
|
|
33
|
-
"task_detail.due_date" = "Срок";
|
|
34
|
-
"task_detail.no_due_date" = "Без срока";
|
|
35
|
-
"task_detail.created" = "Создано";
|
|
36
|
-
"task_detail.updated" = "Обновлено";
|
|
37
|
-
"task_detail.edit" = "Редактировать задачу";
|
|
38
|
-
"task_detail.toggle_status" = "Сменить статус";
|
|
39
|
-
"task_detail.more_info" = "Подробнее";
|
|
40
|
-
"task_detail.delete" = "Удалить задачу";
|
|
41
|
-
"task_detail.delete_title" = "Удалить эту задачу?";
|
|
42
|
-
"task_detail.delete_message" = "Это действие нельзя отменить.";
|
|
43
|
-
"task_detail.updated_feedback" = "Задача обновлена";
|
|
44
|
-
"task_detail.deleted_feedback" = "Задача удалена";
|
|
45
|
-
"settings.title" = "Параметры";
|
|
46
|
-
"settings.subtitle" = "Измените язык и тему для всех целевых платформ.";
|
|
47
|
-
"settings.language" = "Язык";
|
|
48
|
-
"settings.language_en" = "Английский";
|
|
49
|
-
"settings.language_ru" = "Русский";
|
|
50
|
-
"settings.theme" = "Тема";
|
|
51
|
-
"settings.theme_light" = "Светлая";
|
|
52
|
-
"settings.theme_dark" = "Тёмная";
|
|
53
|
-
"settings.reminders" = "Напоминания о сроках";
|
|
54
|
-
"settings.daily_summary" = "Ежедневная сводка";
|
|
55
|
-
"settings.automation_title" = "Автоматизация";
|
|
56
|
-
"settings.automation_subtitle" = "Создавайте повторяющиеся правила задач, чтобы проверить условные формы и валидацию.";
|
|
57
|
-
"settings.automation_create_rule" = "Создать правило";
|
|
58
|
-
"settings.save" = "Сохранить";
|
|
59
|
-
"settings.saved" = "Параметры обновлены";
|
|
60
|
-
"create_task.title" = "Новая задача";
|
|
61
|
-
"create_task.field_title" = "Название";
|
|
62
|
-
"create_task.field_notes" = "Заметки";
|
|
63
|
-
"create_task.field_priority" = "Приоритет";
|
|
64
|
-
"create_task.field_due_date" = "Срок";
|
|
65
|
-
"create_task.success" = "Задача создана";
|
|
66
|
-
"edit_task.title" = "Редактировать задачу";
|
|
67
|
-
"edit_task.field_title" = "Название";
|
|
68
|
-
"edit_task.field_notes" = "Заметки";
|
|
69
|
-
"edit_task.field_priority" = "Приоритет";
|
|
70
|
-
"edit_task.field_due_date" = "Срок";
|
|
71
|
-
"edit_task.success" = "Задача сохранена";
|
|
72
|
-
"recurring_rule.title" = "Повторяющееся правило";
|
|
73
|
-
"recurring_rule.field_name" = "Название правила";
|
|
74
|
-
"recurring_rule.field_confirm_name" = "Подтвердите название";
|
|
75
|
-
"recurring_rule.field_cadence" = "Периодичность";
|
|
76
|
-
"recurring_rule.cadence_daily" = "Ежедневно";
|
|
77
|
-
"recurring_rule.cadence_weekly" = "Еженедельно";
|
|
78
|
-
"recurring_rule.cadence_monthly" = "Ежемесячно";
|
|
79
|
-
"recurring_rule.field_interval" = "Повторять каждые";
|
|
80
|
-
"recurring_rule.field_weekday" = "День недели";
|
|
81
|
-
"recurring_rule.field_month_day" = "День месяца";
|
|
82
|
-
"recurring_rule.field_start_date" = "Дата начала";
|
|
83
|
-
"recurring_rule.field_has_end_date" = "Указать дату окончания";
|
|
84
|
-
"recurring_rule.field_end_date" = "Дата окончания";
|
|
85
|
-
"recurring_rule.field_remind_at" = "Время напоминания";
|
|
86
|
-
"recurring_rule.field_enable_summary" = "Добавить ежедневную сводку";
|
|
87
|
-
"recurring_rule.field_summary_channel" = "Канал сводки";
|
|
88
|
-
"recurring_rule.summary_push" = "Push-уведомление";
|
|
89
|
-
"recurring_rule.summary_email" = "Электронная почта";
|
|
90
|
-
"recurring_rule.success" = "Повторяющееся правило создано";
|
|
91
|
-
"recurring_preview.title" = "Предпросмотр расписания";
|
|
92
|
-
"recurring_preview.invalid" = "Заполните периодичность и даты, чтобы увидеть предпросмотр расписания.";
|
|
93
|
-
"recurring_preview.empty" = "Для этого правила не удаётся сформировать будущие даты.";
|
|
94
|
-
"priority.low" = "Низкий";
|
|
95
|
-
"priority.medium" = "Средний";
|
|
96
|
-
"priority.high" = "Высокий";
|
|
97
|
-
"status.open" = "Открыта";
|
|
98
|
-
"status.done" = "Выполнена";
|
|
99
|
-
"weekday.mon" = "Понедельник";
|
|
100
|
-
"weekday.tue" = "Вторник";
|
|
101
|
-
"weekday.wed" = "Среда";
|
|
102
|
-
"weekday.thu" = "Четверг";
|
|
103
|
-
"weekday.fri" = "Пятница";
|
|
104
|
-
"weekday.sat" = "Суббота";
|
|
105
|
-
"weekday.sun" = "Воскресенье";
|
|
106
|
-
"validation.min_length" = "Минимум %d символа(ов)";
|
|
107
|
-
"validation.min_value" = "Значение должно быть не меньше %d";
|
|
108
|
-
"validation.max_value" = "Значение должно быть не больше %d";
|
|
109
|
-
"validation.rule_name_min_length" = "Название правила должно содержать минимум %d символа(ов)";
|
|
110
|
-
"validation.rule_name_reserved" = "Название по умолчанию зарезервировано. Укажите более точную метку.";
|
|
111
|
-
"validation.rule_name_taken" = "Правило с таким названием уже существует.";
|
|
112
|
-
"validation.match_field" = "Поля не совпадают";
|
|
113
|
-
"validation.end_date_after_start" = "Дата окончания должна быть не раньше даты начала.";
|
|
114
|
-
"validation.time_format" = "Используйте 24-часовой формат, например 09:00";
|
|
115
|
-
"validation.month_day_max" = "Выберите день от 1 до 28";
|
|
116
|
-
"validation.fix_errors" = "Исправьте выделенные поля перед сохранением.";
|
|
117
|
-
"validation.required" = "Это поле обязательно.";
|
|
118
|
-
"common.cancel" = "Отмена";
|
|
119
|
-
"common.delete" = "Удалить";
|
package/examples/todo-orbit/generated/ios/Todo Orbit/Sources/TodoOrbit/App/TodoOrbitApp.swift
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import SwiftUI
|
|
2
|
-
|
|
3
|
-
@main
|
|
4
|
-
struct TodoOrbitApp: App {
|
|
5
|
-
@StateObject private var model = AppModel()
|
|
6
|
-
|
|
7
|
-
var body: some Scene {
|
|
8
|
-
WindowGroup {
|
|
9
|
-
RootView(model: model)
|
|
10
|
-
.preferredColorScheme(model.preferences.theme.colorScheme)
|
|
11
|
-
.environment(\.locale, model.locale)
|
|
12
|
-
.overlay(alignment: .bottom) {
|
|
13
|
-
if let toast = model.toast {
|
|
14
|
-
ToastOverlay(toast: toast)
|
|
15
|
-
.transition(.move(edge: .bottom).combined(with: .opacity))
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
private struct RootView: View {
|
|
23
|
-
@ObservedObject var model: AppModel
|
|
24
|
-
|
|
25
|
-
var body: some View {
|
|
26
|
-
TabView {
|
|
27
|
-
NavigationStack {
|
|
28
|
-
TasksHomeView(model: model)
|
|
29
|
-
}
|
|
30
|
-
.tabItem {
|
|
31
|
-
Label(model.string("nav.tasks"), systemImage: "checklist")
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
NavigationStack {
|
|
35
|
-
AnalyticsView(model: model)
|
|
36
|
-
}
|
|
37
|
-
.tabItem {
|
|
38
|
-
Label(model.string("nav.analytics"), systemImage: "chart.line.uptrend.xyaxis")
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
NavigationStack {
|
|
42
|
-
SettingsView(model: model)
|
|
43
|
-
}
|
|
44
|
-
.tabItem {
|
|
45
|
-
Label(model.string("nav.settings"), systemImage: "gear")
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
.tint(.teal)
|
|
49
|
-
}
|
|
50
|
-
}
|
package/examples/todo-orbit/generated/ios/Todo Orbit/Sources/TodoOrbit/Components/OrbitChrome.swift
DELETED
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
import SwiftUI
|
|
2
|
-
|
|
3
|
-
struct CutCornerShape: Shape {
|
|
4
|
-
var cut: CGFloat = 18
|
|
5
|
-
|
|
6
|
-
func path(in rect: CGRect) -> Path {
|
|
7
|
-
var path = Path()
|
|
8
|
-
path.move(to: CGPoint(x: cut, y: rect.minY))
|
|
9
|
-
path.addLine(to: CGPoint(x: rect.maxX, y: rect.minY))
|
|
10
|
-
path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY - cut))
|
|
11
|
-
path.addLine(to: CGPoint(x: rect.maxX - cut, y: rect.maxY))
|
|
12
|
-
path.addLine(to: CGPoint(x: rect.minX, y: rect.maxY))
|
|
13
|
-
path.addLine(to: CGPoint(x: rect.minX, y: rect.minY + cut))
|
|
14
|
-
path.closeSubpath()
|
|
15
|
-
return path
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
struct OrbitSurfaceModifier: ViewModifier {
|
|
20
|
-
let cut: CGFloat
|
|
21
|
-
let fill: Color
|
|
22
|
-
let stroke: Color
|
|
23
|
-
let lineWidth: CGFloat
|
|
24
|
-
let contentPadding: CGFloat
|
|
25
|
-
|
|
26
|
-
func body(content: Content) -> some View {
|
|
27
|
-
content
|
|
28
|
-
.padding(contentPadding)
|
|
29
|
-
.background(
|
|
30
|
-
CutCornerShape(cut: cut)
|
|
31
|
-
.fill(fill)
|
|
32
|
-
)
|
|
33
|
-
.overlay(
|
|
34
|
-
CutCornerShape(cut: cut)
|
|
35
|
-
.stroke(stroke, lineWidth: lineWidth)
|
|
36
|
-
)
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
extension View {
|
|
41
|
-
func orbitSurface(
|
|
42
|
-
cut: CGFloat = 16,
|
|
43
|
-
fill: Color = Color(uiColor: .secondarySystemBackground),
|
|
44
|
-
stroke: Color = Color.teal.opacity(0.24),
|
|
45
|
-
lineWidth: CGFloat = 1,
|
|
46
|
-
contentPadding: CGFloat = 20
|
|
47
|
-
) -> some View {
|
|
48
|
-
modifier(
|
|
49
|
-
OrbitSurfaceModifier(
|
|
50
|
-
cut: cut,
|
|
51
|
-
fill: fill,
|
|
52
|
-
stroke: stroke,
|
|
53
|
-
lineWidth: lineWidth,
|
|
54
|
-
contentPadding: contentPadding
|
|
55
|
-
)
|
|
56
|
-
)
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
func orbitCard(
|
|
60
|
-
fill: Color = Color(uiColor: .secondarySystemBackground),
|
|
61
|
-
stroke: Color = Color.teal.opacity(0.24),
|
|
62
|
-
lineWidth: CGFloat = 1
|
|
63
|
-
) -> some View {
|
|
64
|
-
orbitSurface(fill: fill, stroke: stroke, lineWidth: lineWidth)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
func orbitInputShell(
|
|
68
|
-
cut: CGFloat = 14,
|
|
69
|
-
fill: Color = Color(uiColor: .secondarySystemBackground),
|
|
70
|
-
stroke: Color = Color.teal.opacity(0.22),
|
|
71
|
-
lineWidth: CGFloat = 1.5,
|
|
72
|
-
contentPadding: CGFloat = 14
|
|
73
|
-
) -> some View {
|
|
74
|
-
orbitSurface(
|
|
75
|
-
cut: cut,
|
|
76
|
-
fill: fill,
|
|
77
|
-
stroke: stroke,
|
|
78
|
-
lineWidth: lineWidth,
|
|
79
|
-
contentPadding: contentPadding
|
|
80
|
-
)
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
struct OrbitPrimaryButtonStyle: ButtonStyle {
|
|
85
|
-
func makeBody(configuration: Configuration) -> some View {
|
|
86
|
-
configuration.label
|
|
87
|
-
.font(.headline.weight(.semibold))
|
|
88
|
-
.foregroundStyle(.white)
|
|
89
|
-
.padding(.horizontal, 18)
|
|
90
|
-
.padding(.vertical, 14)
|
|
91
|
-
.background(
|
|
92
|
-
CutCornerShape(cut: 14)
|
|
93
|
-
.fill(
|
|
94
|
-
LinearGradient(
|
|
95
|
-
colors: [Color.teal, Color(red: 0.07, green: 0.52, blue: 0.48)],
|
|
96
|
-
startPoint: .topLeading,
|
|
97
|
-
endPoint: .bottomTrailing
|
|
98
|
-
)
|
|
99
|
-
)
|
|
100
|
-
)
|
|
101
|
-
.scaleEffect(configuration.isPressed ? 0.98 : 1)
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
struct OrbitGhostButtonStyle: ButtonStyle {
|
|
106
|
-
func makeBody(configuration: Configuration) -> some View {
|
|
107
|
-
configuration.label
|
|
108
|
-
.font(.headline.weight(.semibold))
|
|
109
|
-
.foregroundStyle(Color.primary)
|
|
110
|
-
.padding(.horizontal, 16)
|
|
111
|
-
.padding(.vertical, 12)
|
|
112
|
-
.background(
|
|
113
|
-
CutCornerShape(cut: 14)
|
|
114
|
-
.fill(Color(uiColor: .secondarySystemBackground))
|
|
115
|
-
)
|
|
116
|
-
.overlay(
|
|
117
|
-
CutCornerShape(cut: 14)
|
|
118
|
-
.stroke(Color.teal.opacity(configuration.isPressed ? 0.34 : 0.18), lineWidth: 1.5)
|
|
119
|
-
)
|
|
120
|
-
.scaleEffect(configuration.isPressed ? 0.99 : 1)
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
struct OrbitChipButtonStyle: ButtonStyle {
|
|
125
|
-
let selected: Bool
|
|
126
|
-
|
|
127
|
-
func makeBody(configuration: Configuration) -> some View {
|
|
128
|
-
configuration.label
|
|
129
|
-
.font(.subheadline.weight(.semibold))
|
|
130
|
-
.foregroundStyle(selected ? Color.teal : Color.primary)
|
|
131
|
-
.padding(.horizontal, 16)
|
|
132
|
-
.padding(.vertical, 10)
|
|
133
|
-
.background(
|
|
134
|
-
CutCornerShape(cut: 12)
|
|
135
|
-
.fill(selected ? Color.teal.opacity(0.12) : Color(uiColor: .secondarySystemBackground))
|
|
136
|
-
)
|
|
137
|
-
.overlay(
|
|
138
|
-
CutCornerShape(cut: 12)
|
|
139
|
-
.stroke(
|
|
140
|
-
selected ? Color.teal.opacity(0.34) : Color(uiColor: .separator).opacity(0.45),
|
|
141
|
-
lineWidth: selected ? 1.5 : 1
|
|
142
|
-
)
|
|
143
|
-
)
|
|
144
|
-
.scaleEffect(configuration.isPressed ? 0.98 : 1)
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
struct OrbitFloatingActionButtonStyle: ButtonStyle {
|
|
149
|
-
func makeBody(configuration: Configuration) -> some View {
|
|
150
|
-
configuration.label
|
|
151
|
-
.font(.headline.weight(.semibold))
|
|
152
|
-
.foregroundStyle(.white)
|
|
153
|
-
.padding(.horizontal, 18)
|
|
154
|
-
.padding(.vertical, 14)
|
|
155
|
-
.background(
|
|
156
|
-
CutCornerShape(cut: 16)
|
|
157
|
-
.fill(
|
|
158
|
-
LinearGradient(
|
|
159
|
-
colors: [Color.teal, Color(red: 0.07, green: 0.52, blue: 0.48)],
|
|
160
|
-
startPoint: .topLeading,
|
|
161
|
-
endPoint: .bottomTrailing
|
|
162
|
-
)
|
|
163
|
-
)
|
|
164
|
-
)
|
|
165
|
-
.shadow(color: .black.opacity(configuration.isPressed ? 0.12 : 0.18), radius: 18, y: 8)
|
|
166
|
-
.scaleEffect(configuration.isPressed ? 0.98 : 1)
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
struct PriorityDot: View {
|
|
171
|
-
let priority: TaskPriority
|
|
172
|
-
|
|
173
|
-
var body: some View {
|
|
174
|
-
Circle()
|
|
175
|
-
.fill(priority.tint)
|
|
176
|
-
.frame(width: 12, height: 12)
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
struct ToastOverlay: View {
|
|
181
|
-
let toast: ToastMessage
|
|
182
|
-
|
|
183
|
-
var tint: Color {
|
|
184
|
-
switch toast.level {
|
|
185
|
-
case .success: .green
|
|
186
|
-
case .warning: .orange
|
|
187
|
-
case .error: .red
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
var body: some View {
|
|
192
|
-
Text(toast.text)
|
|
193
|
-
.font(.subheadline.weight(.semibold))
|
|
194
|
-
.foregroundStyle(.white)
|
|
195
|
-
.padding(.horizontal, 18)
|
|
196
|
-
.padding(.vertical, 14)
|
|
197
|
-
.background(
|
|
198
|
-
CutCornerShape(cut: 14)
|
|
199
|
-
.fill(tint)
|
|
200
|
-
)
|
|
201
|
-
.shadow(color: .black.opacity(0.18), radius: 22, y: 10)
|
|
202
|
-
.padding(.bottom, 18)
|
|
203
|
-
}
|
|
204
|
-
}
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
import SwiftUI
|
|
2
|
-
|
|
3
|
-
struct SchedulePreviewResult {
|
|
4
|
-
enum State {
|
|
5
|
-
case invalid
|
|
6
|
-
case empty
|
|
7
|
-
case ready
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
let state: State
|
|
11
|
-
let dates: [Date]
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
struct SchedulePreviewView: View {
|
|
15
|
-
let model: AppModel
|
|
16
|
-
let title: String
|
|
17
|
-
let result: SchedulePreviewResult
|
|
18
|
-
|
|
19
|
-
var body: some View {
|
|
20
|
-
VStack(alignment: .leading, spacing: 14) {
|
|
21
|
-
Text("x_schedule_preview.detail")
|
|
22
|
-
.font(.caption.weight(.bold))
|
|
23
|
-
.foregroundStyle(.secondary)
|
|
24
|
-
.textCase(.uppercase)
|
|
25
|
-
Text(title)
|
|
26
|
-
.font(.title3.weight(.semibold))
|
|
27
|
-
|
|
28
|
-
switch result.state {
|
|
29
|
-
case .invalid:
|
|
30
|
-
Text(model.string("recurring_preview.invalid"))
|
|
31
|
-
.font(.footnote.weight(.medium))
|
|
32
|
-
.foregroundStyle(.red)
|
|
33
|
-
.padding(14)
|
|
34
|
-
.frame(maxWidth: .infinity, alignment: .leading)
|
|
35
|
-
.background(Color.red.opacity(0.08), in: CutCornerShape(cut: 12))
|
|
36
|
-
case .empty:
|
|
37
|
-
Text(model.string("recurring_preview.empty"))
|
|
38
|
-
.foregroundStyle(.secondary)
|
|
39
|
-
case .ready:
|
|
40
|
-
VStack(spacing: 10) {
|
|
41
|
-
ForEach(Array(result.dates.enumerated()), id: \.offset) { index, date in
|
|
42
|
-
HStack {
|
|
43
|
-
Text(index == 0 ? "Next" : "+\(index)")
|
|
44
|
-
.font(.caption.weight(.bold))
|
|
45
|
-
.foregroundStyle(index == 0 ? .teal : .secondary)
|
|
46
|
-
Spacer()
|
|
47
|
-
Text(model.formatDate(date))
|
|
48
|
-
.font(.subheadline.weight(.semibold))
|
|
49
|
-
}
|
|
50
|
-
.padding(14)
|
|
51
|
-
.background(
|
|
52
|
-
CutCornerShape(cut: 12)
|
|
53
|
-
.fill(index == 0 ? Color.teal.opacity(0.08) : Color(uiColor: .secondarySystemBackground))
|
|
54
|
-
)
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
.orbitCard(fill: Color(uiColor: .systemBackground), stroke: Color.orange.opacity(0.22))
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
static func compute(from draft: RecurringRuleDraft) -> SchedulePreviewResult {
|
|
63
|
-
guard let cadence = draft.cadence, let interval = Int(draft.interval), interval >= 1 else {
|
|
64
|
-
return .init(state: .invalid, dates: [])
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if draft.hasEndDate, draft.endDate < draft.startDate {
|
|
68
|
-
return .init(state: .invalid, dates: [])
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if cadence == .weekly, draft.weekday == nil {
|
|
72
|
-
return .init(state: .invalid, dates: [])
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if cadence == .monthly {
|
|
76
|
-
guard let day = Int(draft.monthDay), (1...28).contains(day) else {
|
|
77
|
-
return .init(state: .invalid, dates: [])
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
let calendar = Calendar.current
|
|
82
|
-
var dates: [Date] = []
|
|
83
|
-
var cursor = draft.startDate
|
|
84
|
-
let endDate = draft.hasEndDate ? draft.endDate : nil
|
|
85
|
-
|
|
86
|
-
for _ in 0..<4 {
|
|
87
|
-
let next: Date?
|
|
88
|
-
switch cadence {
|
|
89
|
-
case .daily:
|
|
90
|
-
next = cursor
|
|
91
|
-
cursor = calendar.date(byAdding: .day, value: interval, to: cursor) ?? cursor
|
|
92
|
-
case .weekly:
|
|
93
|
-
next = nextWeeklyDate(startingAt: cursor, weekday: draft.weekday!, interval: interval)
|
|
94
|
-
cursor = calendar.date(byAdding: .day, value: interval * 7, to: next ?? cursor) ?? cursor
|
|
95
|
-
case .monthly:
|
|
96
|
-
next = nextMonthlyDate(startingAt: cursor, day: Int(draft.monthDay)!, interval: interval)
|
|
97
|
-
cursor = calendar.date(byAdding: .month, value: interval, to: next ?? cursor) ?? cursor
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
guard let next else { break }
|
|
101
|
-
if let endDate, next > endDate { break }
|
|
102
|
-
dates.append(next)
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
return dates.isEmpty ? .init(state: .empty, dates: []) : .init(state: .ready, dates: dates)
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
private static func nextWeeklyDate(startingAt start: Date, weekday: Weekday, interval: Int) -> Date? {
|
|
109
|
-
let calendar = Calendar.current
|
|
110
|
-
var next = start
|
|
111
|
-
while calendar.component(.weekday, from: next) != weekday.calendarIndex {
|
|
112
|
-
guard let candidate = calendar.date(byAdding: .day, value: 1, to: next) else { return nil }
|
|
113
|
-
next = candidate
|
|
114
|
-
}
|
|
115
|
-
return next
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
private static func nextMonthlyDate(startingAt start: Date, day: Int, interval: Int) -> Date? {
|
|
119
|
-
let calendar = Calendar.current
|
|
120
|
-
var components = calendar.dateComponents([.year, .month], from: start)
|
|
121
|
-
components.day = day
|
|
122
|
-
guard let initial = calendar.date(from: components) else { return nil }
|
|
123
|
-
if initial >= start { return initial }
|
|
124
|
-
return calendar.date(byAdding: .month, value: interval, to: initial)
|
|
125
|
-
}
|
|
126
|
-
}
|