openuispec 0.2.10 → 0.2.11
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/cli/index.ts +4 -2
- package/cli/init.ts +23 -8
- package/docs/cli.md +13 -8
- package/drift/index.ts +41 -15
- package/mcp-server/index.ts +155 -116
- package/mcp-server/screenshot.ts +19 -4
- package/package.json +5 -2
- package/prepare/index.ts +16 -0
- package/scripts/take-all-screenshots.ts +507 -0
- package/status/index.ts +2 -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,124 +0,0 @@
|
|
|
1
|
-
<!-- openuispec-rules-start -->
|
|
2
|
-
<!-- openuispec-rules-version: 0.2.4 -->
|
|
3
|
-
# OpenUISpec — AI Assistant Rules
|
|
4
|
-
# ================================
|
|
5
|
-
# This project uses OpenUISpec to define UI as a semantic spec.
|
|
6
|
-
# Spec files are the single source of truth for all UI across platforms.
|
|
7
|
-
# Targets: "ios", "android", "web"
|
|
8
|
-
|
|
9
|
-
## MANDATORY — UI work requires OpenUISpec tools
|
|
10
|
-
|
|
11
|
-
When the user's request involves UI — screens, navigation, layout, tokens, flows, localization,
|
|
12
|
-
or any visual/structural change — you MUST use the OpenUISpec tools before writing any code.
|
|
13
|
-
|
|
14
|
-
### MCP Tools (use these when available)
|
|
15
|
-
|
|
16
|
-
Call these MCP tools directly. They return structured JSON with everything you need.
|
|
17
|
-
|
|
18
|
-
**Pre-generation:**
|
|
19
|
-
1. Call `openuispec_prepare` with the target platform — returns spec context, platform config, constraints.
|
|
20
|
-
2. Call `openuispec_read_specs` to load spec file contents. Use these as the AUTHORITATIVE source.
|
|
21
|
-
3. If spec changes are needed, update spec files FIRST, then call `openuispec_check`.
|
|
22
|
-
4. Generate or update the platform UI code based on the spec contents.
|
|
23
|
-
|
|
24
|
-
**Post-generation (EVERY TIME after writing UI code):**
|
|
25
|
-
5. Call `openuispec_check` to validate spec integrity.
|
|
26
|
-
6. Call `openuispec_read_specs` for the screens/contracts you just generated code for.
|
|
27
|
-
7. Audit your generated code against the spec. For each screen, verify:
|
|
28
|
-
- Every field/action in the spec has a corresponding UI element
|
|
29
|
-
- Token values (colors, spacing, radii) match exactly — no approximations
|
|
30
|
-
- Contract `must_handle` states are all implemented (loading, error, empty, etc.)
|
|
31
|
-
- Adaptive breakpoints match the spec's `size_classes`
|
|
32
|
-
- Locale keys match `$t:` references
|
|
33
|
-
- Navigation targets match flow definitions
|
|
34
|
-
8. Report any real gaps found and fix them before finishing.
|
|
35
|
-
|
|
36
|
-
**Creating new spec files:**
|
|
37
|
-
- Call `openuispec_spec_types` to discover available spec types.
|
|
38
|
-
- Call `openuispec_spec_schema` with the specific type to get the full JSON schema.
|
|
39
|
-
- Write the spec file following the schema exactly.
|
|
40
|
-
|
|
41
|
-
**Focused getters (prefer these for incremental edits over `read_specs`):**
|
|
42
|
-
- `openuispec_get_screen(name)` — single screen spec
|
|
43
|
-
- `openuispec_get_contract(name, variant?)` — single contract, optionally one variant
|
|
44
|
-
- `openuispec_get_tokens(category)` — single token category (color, typography, spacing, etc.)
|
|
45
|
-
- `openuispec_get_locale(locale, keys?)` — single locale file, optionally filtered keys
|
|
46
|
-
- `openuispec_check(target, screens?, contracts?)` — scoped audit for specific screens/contracts
|
|
47
|
-
|
|
48
|
-
Use `read_specs` for full-project generation; use focused getters when editing one screen or contract.
|
|
49
|
-
|
|
50
|
-
**Other tools:**
|
|
51
|
-
- `openuispec_status` — cross-target summary, good starting point
|
|
52
|
-
- `openuispec_drift` with `explain: true` — property-level spec changes
|
|
53
|
-
- `openuispec_validate` — schema-only validation by group
|
|
54
|
-
|
|
55
|
-
### CLI fallback (when MCP is not available)
|
|
56
|
-
|
|
57
|
-
If MCP tools are not available, use these CLI commands with `--json` flag:
|
|
58
|
-
- `openuispec prepare --target <t> --json` — build AI-ready work bundle
|
|
59
|
-
- `openuispec check --target <t> --json` — composite validation
|
|
60
|
-
- `openuispec status --json` — cross-target status
|
|
61
|
-
- `openuispec drift --target <t> --explain --json` — semantic drift
|
|
62
|
-
- `openuispec validate [group...] --json` — schema validation
|
|
63
|
-
- `openuispec read-specs [paths...]` — read spec file contents
|
|
64
|
-
- `openuispec get-screen <name>` — get a single screen spec
|
|
65
|
-
- `openuispec get-contract <name> [--variant v]` — get a contract spec
|
|
66
|
-
- `openuispec get-tokens <category>` — get tokens for a category
|
|
67
|
-
- `openuispec get-locale <locale> [--keys k1,k2]` — get a locale file
|
|
68
|
-
- `openuispec spec-types` — list available spec types
|
|
69
|
-
- `openuispec spec-schema <type>` — get JSON schema for a spec type
|
|
70
|
-
- `openuispec screenshot --route /path` — screenshot the web app
|
|
71
|
-
- `openuispec screenshot-android [--project-dir path]` — screenshot Android app
|
|
72
|
-
- `openuispec screenshot-ios [--project-dir path]` — screenshot iOS app
|
|
73
|
-
|
|
74
|
-
### Other CLI commands
|
|
75
|
-
- `openuispec init` — scaffold a new spec project
|
|
76
|
-
- `openuispec drift --snapshot --target <t>` — snapshot current state (only after UI code is updated)
|
|
77
|
-
- `openuispec configure-target <t>` — configure target platform stack
|
|
78
|
-
- `openuispec update-rules` — update AI rules to match installed package version
|
|
79
|
-
|
|
80
|
-
## Spec format reference
|
|
81
|
-
|
|
82
|
-
The spec format, schemas, and generation rules are in the installed `openuispec` package.
|
|
83
|
-
You MUST read the reference files before creating or editing spec files — do NOT guess the format.
|
|
84
|
-
|
|
85
|
-
**Find the package:** `node_modules/openuispec/` or run `npm root -g` → `<prefix>/openuispec/`.
|
|
86
|
-
**Online fallback:** `https://openuispec.rsteam.uz/llms-full.txt`
|
|
87
|
-
|
|
88
|
-
**Reference files (read in order):**
|
|
89
|
-
1. `README.md` — schema tables, file format, root wrapper keys
|
|
90
|
-
2. `spec/openuispec-v0.1.md` — full specification
|
|
91
|
-
3. `examples/taskflow/openuispec/` — complete working example
|
|
92
|
-
4. `schema/` — JSON Schemas for every file type
|
|
93
|
-
|
|
94
|
-
## Spec location
|
|
95
|
-
- Spec root: `openuispec/` — read `openuispec/openuispec.yaml` first for actual paths.
|
|
96
|
-
- Default dirs: tokens/, screens/, flows/, contracts/, platform/, locales/
|
|
97
|
-
|
|
98
|
-
## When to start from spec vs platform code
|
|
99
|
-
|
|
100
|
-
**Spec-first** (use `openuispec_prepare` or `openuispec prepare`):
|
|
101
|
-
- Screen structure, navigation, fields, actions, validation, data binding changes
|
|
102
|
-
- Token, variant, contract, flow, or localization changes
|
|
103
|
-
- Changes affecting multiple platforms
|
|
104
|
-
- Requests in product/UI terms
|
|
105
|
-
|
|
106
|
-
**Platform-first** (skip spec tools):
|
|
107
|
-
- Platform-specific polish (iOS-only, Android-only, web-only)
|
|
108
|
-
- Local bug fixes that don't alter shared semantic behavior
|
|
109
|
-
|
|
110
|
-
## If spec directories are empty (first-time setup)
|
|
111
|
-
|
|
112
|
-
Read `spec/openuispec-v0.1.md` from the package first, then:
|
|
113
|
-
1. Scan codebase for UI screens → create `openuispec/screens/<name>.yaml` as `status: stub`
|
|
114
|
-
2. Extract tokens (colors, fonts, spacing) → `openuispec/tokens/`
|
|
115
|
-
3. Create contract extensions → `openuispec/contracts/`
|
|
116
|
-
4. Create locale files → `openuispec/locales/<locale>.json`
|
|
117
|
-
5. Fill in `data_model`, `api.endpoints` in `openuispec/openuispec.yaml`
|
|
118
|
-
|
|
119
|
-
## Rules
|
|
120
|
-
- Do not snapshot drift unless the UI code has also been updated.
|
|
121
|
-
- Do not modify generated UI without checking whether the spec must change first.
|
|
122
|
-
- Do not use `configure-target --defaults` as silent approval — ask the user to confirm.
|
|
123
|
-
- Always read spec format from the installed package, not from cached/memorized content.
|
|
124
|
-
<!-- openuispec-rules-end -->
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
plugins {
|
|
2
|
-
id("app.cash.paparazzi")
|
|
3
|
-
alias(libs.plugins.android.application)
|
|
4
|
-
alias(libs.plugins.compose.compiler)
|
|
5
|
-
kotlin("plugin.serialization")
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
android {
|
|
9
|
-
namespace = "com.social.app"
|
|
10
|
-
compileSdk = 36
|
|
11
|
-
|
|
12
|
-
defaultConfig {
|
|
13
|
-
applicationId = "com.social.app"
|
|
14
|
-
minSdk = 26
|
|
15
|
-
targetSdk = 36
|
|
16
|
-
versionCode = 1
|
|
17
|
-
versionName = "1.0"
|
|
18
|
-
|
|
19
|
-
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
|
20
|
-
vectorDrawables {
|
|
21
|
-
useSupportLibrary = true
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
buildTypes {
|
|
26
|
-
release {
|
|
27
|
-
isMinifyEnabled = false
|
|
28
|
-
proguardFiles(
|
|
29
|
-
getDefaultProguardFile("proguard-android-optimize.txt"),
|
|
30
|
-
"proguard-rules.pro"
|
|
31
|
-
)
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
compileOptions {
|
|
35
|
-
sourceCompatibility = JavaVersion.VERSION_11
|
|
36
|
-
targetCompatibility = JavaVersion.VERSION_11
|
|
37
|
-
}
|
|
38
|
-
kotlin {
|
|
39
|
-
compilerOptions {
|
|
40
|
-
jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11)
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
buildFeatures {
|
|
44
|
-
compose = true
|
|
45
|
-
}
|
|
46
|
-
packaging {
|
|
47
|
-
resources {
|
|
48
|
-
excludes += "/META-INF/{AL2.0,LGPL2.1}"
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
dependencies {
|
|
54
|
-
implementation(libs.androidx.core.ktx)
|
|
55
|
-
implementation(libs.androidx.lifecycle.runtime.ktx)
|
|
56
|
-
implementation(libs.androidx.activity.compose)
|
|
57
|
-
implementation(platform(libs.androidx.compose.bom))
|
|
58
|
-
implementation(libs.androidx.ui)
|
|
59
|
-
implementation(libs.androidx.ui.graphics)
|
|
60
|
-
implementation(libs.androidx.ui.tooling.preview)
|
|
61
|
-
implementation(libs.androidx.material3)
|
|
62
|
-
implementation(libs.androidx.material.icons.extended)
|
|
63
|
-
implementation(libs.google.material)
|
|
64
|
-
implementation(libs.coil.compose)
|
|
65
|
-
implementation(libs.coil.network)
|
|
66
|
-
|
|
67
|
-
// Decompose
|
|
68
|
-
implementation(libs.decompose)
|
|
69
|
-
implementation(libs.decompose.extensions.compose)
|
|
70
|
-
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")
|
|
71
|
-
|
|
72
|
-
// MVIKotlin
|
|
73
|
-
implementation(libs.mvikotlin)
|
|
74
|
-
implementation(libs.mvikotlin.main)
|
|
75
|
-
implementation(libs.mvikotlin.logging)
|
|
76
|
-
implementation("com.arkivanov.mvikotlin:mvikotlin-extensions-coroutines:4.3.0")
|
|
77
|
-
|
|
78
|
-
// Essenty
|
|
79
|
-
implementation(libs.essenty.lifecycle)
|
|
80
|
-
implementation(libs.essenty.instancekeeper)
|
|
81
|
-
|
|
82
|
-
// DataStore
|
|
83
|
-
implementation(libs.androidx.datastore.preferences)
|
|
84
|
-
implementation(libs.androidx.datastore.core)
|
|
85
|
-
|
|
86
|
-
testImplementation("junit:junit:4.13.2")
|
|
87
|
-
androidTestImplementation("androidx.test.ext:junit:1.2.1")
|
|
88
|
-
androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
|
|
89
|
-
androidTestImplementation(platform(libs.androidx.compose.bom))
|
|
90
|
-
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
|
|
91
|
-
debugImplementation(libs.androidx.ui.tooling)
|
|
92
|
-
debugImplementation("androidx.compose.ui:ui-test-manifest")
|
|
93
|
-
|
|
94
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
-
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
|
3
|
-
|
|
4
|
-
<uses-permission android:name="android.permission.INTERNET" />
|
|
5
|
-
|
|
6
|
-
<application
|
|
7
|
-
android:name=".SocialAppApplication"
|
|
8
|
-
android:allowBackup="true"
|
|
9
|
-
android:icon="@mipmap/ic_launcher"
|
|
10
|
-
android:label="@string/nav_home"
|
|
11
|
-
android:roundIcon="@mipmap/ic_launcher_round"
|
|
12
|
-
android:supportsRtl="true"
|
|
13
|
-
android:theme="@style/Theme.SocialApp">
|
|
14
|
-
<activity
|
|
15
|
-
android:name=".MainActivity"
|
|
16
|
-
android:exported="true"
|
|
17
|
-
android:label="@string/nav_home"
|
|
18
|
-
android:theme="@style/Theme.SocialApp">
|
|
19
|
-
<intent-filter>
|
|
20
|
-
<action android:name="android.intent.action.MAIN" />
|
|
21
|
-
<category android:name="android.intent.category.LAUNCHER" />
|
|
22
|
-
</intent-filter>
|
|
23
|
-
</activity>
|
|
24
|
-
</application>
|
|
25
|
-
|
|
26
|
-
</manifest>
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
package com.social.app
|
|
2
|
-
|
|
3
|
-
import android.content.Context
|
|
4
|
-
import com.arkivanov.decompose.ComponentContext
|
|
5
|
-
import com.arkivanov.mvikotlin.core.store.StoreFactory
|
|
6
|
-
import com.social.app.data.preferences.DataStorePreferencesRepository
|
|
7
|
-
import com.social.app.data.preferences.PreferencesRepository
|
|
8
|
-
import com.social.app.ui.navigation.DefaultRootComponent
|
|
9
|
-
import com.social.app.ui.navigation.RootComponent
|
|
10
|
-
import com.arkivanov.mvikotlin.main.store.DefaultStoreFactory
|
|
11
|
-
import com.arkivanov.mvikotlin.logging.store.LoggingStoreFactory
|
|
12
|
-
|
|
13
|
-
class AppContainer(
|
|
14
|
-
context: Context,
|
|
15
|
-
) {
|
|
16
|
-
val preferencesRepository: PreferencesRepository = DataStorePreferencesRepository(context.applicationContext)
|
|
17
|
-
val storeFactory: StoreFactory = LoggingStoreFactory(DefaultStoreFactory())
|
|
18
|
-
|
|
19
|
-
fun createRootComponent(componentContext: ComponentContext): RootComponent = DefaultRootComponent(componentContext)
|
|
20
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
package com.social.app
|
|
2
|
-
|
|
3
|
-
import android.os.Bundle
|
|
4
|
-
import androidx.activity.ComponentActivity
|
|
5
|
-
import androidx.activity.compose.setContent
|
|
6
|
-
import androidx.activity.enableEdgeToEdge
|
|
7
|
-
import androidx.compose.runtime.collectAsState
|
|
8
|
-
import androidx.compose.runtime.getValue
|
|
9
|
-
import com.arkivanov.decompose.defaultComponentContext
|
|
10
|
-
import com.social.app.data.preferences.AppPreferences
|
|
11
|
-
import com.social.app.ui.MainShell
|
|
12
|
-
import com.social.app.ui.theme.SocialAppTheme
|
|
13
|
-
|
|
14
|
-
class MainActivity : ComponentActivity() {
|
|
15
|
-
override fun onCreate(savedInstanceState: Bundle?) {
|
|
16
|
-
super.onCreate(savedInstanceState)
|
|
17
|
-
val appContainer = (application as SocialAppApplication).appContainer
|
|
18
|
-
val root = appContainer.createRootComponent(defaultComponentContext())
|
|
19
|
-
|
|
20
|
-
enableEdgeToEdge()
|
|
21
|
-
setContent {
|
|
22
|
-
val preferences by appContainer.preferencesRepository.preferences.collectAsState(initial = AppPreferences())
|
|
23
|
-
|
|
24
|
-
SocialAppTheme(
|
|
25
|
-
themeMode = preferences.themeMode,
|
|
26
|
-
) {
|
|
27
|
-
MainShell(
|
|
28
|
-
root = root,
|
|
29
|
-
preferencesRepository = appContainer.preferencesRepository,
|
|
30
|
-
storeFactory = appContainer.storeFactory,
|
|
31
|
-
)
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
package com.social.app
|
|
2
|
-
|
|
3
|
-
import android.app.Application
|
|
4
|
-
|
|
5
|
-
class SocialAppApplication : Application() {
|
|
6
|
-
lateinit var appContainer: AppContainer
|
|
7
|
-
private set
|
|
8
|
-
|
|
9
|
-
override fun onCreate() {
|
|
10
|
-
super.onCreate()
|
|
11
|
-
appContainer = AppContainer(this)
|
|
12
|
-
}
|
|
13
|
-
}
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
package com.social.app.data
|
|
2
|
-
|
|
3
|
-
import com.social.app.model.*
|
|
4
|
-
|
|
5
|
-
object MockData {
|
|
6
|
-
val users = listOf(
|
|
7
|
-
User(
|
|
8
|
-
id = "user_me",
|
|
9
|
-
handle = "rustam",
|
|
10
|
-
displayName = "Rustam Abdurahmonov",
|
|
11
|
-
avatarUrl = "https://images.unsplash.com/photo-1500648767791-00dcc994a43e?auto=format&fit=crop&w=320&q=80",
|
|
12
|
-
bio = "Designing interface systems that feel editorial, human, and alive.",
|
|
13
|
-
followers = 1240,
|
|
14
|
-
following = 184
|
|
15
|
-
),
|
|
16
|
-
User(
|
|
17
|
-
id = "u_9921",
|
|
18
|
-
handle = "elara_vox",
|
|
19
|
-
displayName = "Elara Vance",
|
|
20
|
-
avatarUrl = "https://images.unsplash.com/photo-1534528741775-53994a69daeb?auto=format&fit=crop&w=256&q=80",
|
|
21
|
-
bio = "Digital Architect | Exploring the intersection of AR and urban spaces 🏙️",
|
|
22
|
-
followers = 12400,
|
|
23
|
-
following = 842,
|
|
24
|
-
isFollowed = true
|
|
25
|
-
),
|
|
26
|
-
User(
|
|
27
|
-
id = "u_4432",
|
|
28
|
-
handle = "kai_zen",
|
|
29
|
-
displayName = "Kai Nakamura",
|
|
30
|
-
avatarUrl = "https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?auto=format&fit=crop&w=256&q=80",
|
|
31
|
-
bio = "Sustainable tech & minimalist living. 🌿 Tokyo -> Berlin",
|
|
32
|
-
followers = 3100,
|
|
33
|
-
following = 1100
|
|
34
|
-
)
|
|
35
|
-
)
|
|
36
|
-
|
|
37
|
-
val posts = listOf(
|
|
38
|
-
Post(
|
|
39
|
-
id = "p_77102",
|
|
40
|
-
authorId = "u_9921",
|
|
41
|
-
authorName = "Elara Vance",
|
|
42
|
-
authorHandle = "elara_vox",
|
|
43
|
-
authorAvatar = "https://images.unsplash.com/photo-1534528741775-53994a69daeb?auto=format&fit=crop&w=256&q=80",
|
|
44
|
-
body = "The new Neo-Tokyo district looks incredible in the morning light. The AR overlays are finally syncing perfectly with the physical architecture. #FutureCity #DigitalTwin #2026",
|
|
45
|
-
mediaUrl = "https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?auto=format&fit=crop&w=1080&q=80",
|
|
46
|
-
likeCount = 1432,
|
|
47
|
-
commentCount = 42,
|
|
48
|
-
timestamp = "4 hours ago",
|
|
49
|
-
liked = true
|
|
50
|
-
),
|
|
51
|
-
Post(
|
|
52
|
-
id = "p_77103",
|
|
53
|
-
authorId = "u_4432",
|
|
54
|
-
authorName = "Kai Nakamura",
|
|
55
|
-
authorHandle = "kai_zen",
|
|
56
|
-
authorAvatar = "https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?auto=format&fit=crop&w=256&q=80",
|
|
57
|
-
body = "Workspace evolution. Keeping it clean and focused this year.",
|
|
58
|
-
mediaUrl = "https://images.unsplash.com/photo-1497366216548-37526070297c?auto=format&fit=crop&w=1080&q=80",
|
|
59
|
-
likeCount = 890,
|
|
60
|
-
commentCount = 15,
|
|
61
|
-
timestamp = "9 hours ago"
|
|
62
|
-
),
|
|
63
|
-
Post(
|
|
64
|
-
id = "p_1",
|
|
65
|
-
authorId = "user_me",
|
|
66
|
-
authorName = "Rustam Abdurahmonov",
|
|
67
|
-
authorHandle = "rustam",
|
|
68
|
-
authorAvatar = "https://images.unsplash.com/photo-1500648767791-00dcc994a43e?auto=format&fit=crop&w=320&q=80",
|
|
69
|
-
body = "Spent the morning photographing a cafe before it opened. The cups were already warm, the chairs still slightly crooked. Those in-between moments always feel the most honest.",
|
|
70
|
-
mediaUrl = "https://images.unsplash.com/photo-1495474472287-4d71bcdd2085?auto=format&fit=crop&w=1200&q=80",
|
|
71
|
-
likeCount = 243,
|
|
72
|
-
commentCount = 12,
|
|
73
|
-
timestamp = "1 day ago"
|
|
74
|
-
)
|
|
75
|
-
)
|
|
76
|
-
|
|
77
|
-
val stories = listOf(
|
|
78
|
-
Story(id = "s_1", authorId = "u_9921", authorName = "Elara Vance", previewUrl = "https://images.unsplash.com/photo-1550745165-9bc0b252726f?auto=format&fit=crop&w=720&q=80"),
|
|
79
|
-
Story(id = "s_2", authorId = "u_4432", authorName = "Kai Nakamura", previewUrl = "https://images.unsplash.com/photo-1511467687858-23d96c32e4ae?auto=format&fit=crop&w=720&q=80"),
|
|
80
|
-
Story(id = "s_3", authorId = "user_me", authorName = "Rustam", previewUrl = "https://images.unsplash.com/photo-1500648767791-00dcc994a43e?auto=format&fit=crop&w=320&q=80")
|
|
81
|
-
)
|
|
82
|
-
|
|
83
|
-
val trends = listOf(
|
|
84
|
-
Trend(id = "t_1", label = "Editorial UI", postCount = 8420),
|
|
85
|
-
Trend(id = "t_2", label = "Warm Brutalism", postCount = 4135),
|
|
86
|
-
Trend(id = "t_3", label = "Motion Details", postCount = 2940),
|
|
87
|
-
Trend(id = "t_4", label = "Design Systems", postCount = 8677)
|
|
88
|
-
)
|
|
89
|
-
|
|
90
|
-
val notifications = listOf(
|
|
91
|
-
Notification(id = "n_1", type = "like", actorName = "Elara Vance", actorAvatar = "https://images.unsplash.com/photo-1534528741775-53994a69daeb?auto=format&fit=crop&w=256&q=80", message = "liked your post", timestamp = "34m ago"),
|
|
92
|
-
Notification(id = "n_2", type = "comment", actorName = "Kai Nakamura", actorAvatar = "https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?auto=format&fit=crop&w=256&q=80", message = "commented on your post", timestamp = "7h ago"),
|
|
93
|
-
Notification(id = "n_3", type = "follow", actorName = "Elara Vance", actorAvatar = "https://images.unsplash.com/photo-1534528741775-53994a69daeb?auto=format&fit=crop&w=256&q=80", message = "started following you", timestamp = "1d ago")
|
|
94
|
-
)
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
data class Trend(val id: String, val label: String, val postCount: Int)
|
|
98
|
-
data class Notification(val id: String, val type: String, val actorName: String, val actorAvatar: String?, val message: String, val timestamp: String)
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
package com.social.app.data.preferences
|
|
2
|
-
|
|
3
|
-
enum class ThemeMode(val storageValue: String) {
|
|
4
|
-
System("system"),
|
|
5
|
-
Light("light"),
|
|
6
|
-
Dark("dark");
|
|
7
|
-
|
|
8
|
-
companion object {
|
|
9
|
-
fun fromStorageValue(value: String?): ThemeMode =
|
|
10
|
-
entries.firstOrNull { it.storageValue == value } ?: System
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
data class AppPreferences(
|
|
15
|
-
val themeMode: ThemeMode = ThemeMode.System,
|
|
16
|
-
val pushNotifications: Boolean = true,
|
|
17
|
-
val messagePreviews: Boolean = true,
|
|
18
|
-
val autoTranslate: Boolean = false,
|
|
19
|
-
)
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
package com.social.app.data.preferences
|
|
2
|
-
|
|
3
|
-
import android.content.Context
|
|
4
|
-
import androidx.datastore.core.DataStore
|
|
5
|
-
import androidx.datastore.preferences.core.Preferences
|
|
6
|
-
import androidx.datastore.preferences.core.booleanPreferencesKey
|
|
7
|
-
import androidx.datastore.preferences.core.edit
|
|
8
|
-
import androidx.datastore.preferences.core.emptyPreferences
|
|
9
|
-
import androidx.datastore.preferences.core.stringPreferencesKey
|
|
10
|
-
import androidx.datastore.preferences.preferencesDataStore
|
|
11
|
-
import java.io.IOException
|
|
12
|
-
import kotlinx.coroutines.flow.Flow
|
|
13
|
-
import kotlinx.coroutines.flow.catch
|
|
14
|
-
import kotlinx.coroutines.flow.map
|
|
15
|
-
|
|
16
|
-
private val Context.socialAppDataStore: DataStore<Preferences> by preferencesDataStore(name = "social_app_preferences")
|
|
17
|
-
|
|
18
|
-
class DataStorePreferencesRepository(
|
|
19
|
-
private val context: Context,
|
|
20
|
-
) : PreferencesRepository {
|
|
21
|
-
override val preferences: Flow<AppPreferences> =
|
|
22
|
-
context.socialAppDataStore.data
|
|
23
|
-
.catch { exception ->
|
|
24
|
-
if (exception is IOException) {
|
|
25
|
-
emit(emptyPreferences())
|
|
26
|
-
} else {
|
|
27
|
-
throw exception
|
|
28
|
-
}
|
|
29
|
-
}.map { storedPreferences ->
|
|
30
|
-
AppPreferences(
|
|
31
|
-
themeMode = ThemeMode.fromStorageValue(storedPreferences[Keys.ThemeMode]),
|
|
32
|
-
pushNotifications = storedPreferences[Keys.PushNotifications] ?: true,
|
|
33
|
-
messagePreviews = storedPreferences[Keys.MessagePreviews] ?: true,
|
|
34
|
-
autoTranslate = storedPreferences[Keys.AutoTranslate] ?: false,
|
|
35
|
-
)
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
override suspend fun updateThemeMode(themeMode: ThemeMode) {
|
|
39
|
-
context.socialAppDataStore.edit { storedPreferences ->
|
|
40
|
-
storedPreferences[Keys.ThemeMode] = themeMode.storageValue
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
override suspend fun updatePushNotifications(enabled: Boolean) {
|
|
45
|
-
context.socialAppDataStore.edit { storedPreferences ->
|
|
46
|
-
storedPreferences[Keys.PushNotifications] = enabled
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
override suspend fun updateMessagePreviews(enabled: Boolean) {
|
|
51
|
-
context.socialAppDataStore.edit { storedPreferences ->
|
|
52
|
-
storedPreferences[Keys.MessagePreviews] = enabled
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
override suspend fun updateAutoTranslate(enabled: Boolean) {
|
|
57
|
-
context.socialAppDataStore.edit { storedPreferences ->
|
|
58
|
-
storedPreferences[Keys.AutoTranslate] = enabled
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
private object Keys {
|
|
63
|
-
val ThemeMode = stringPreferencesKey("theme_mode")
|
|
64
|
-
val PushNotifications = booleanPreferencesKey("push_notifications")
|
|
65
|
-
val MessagePreviews = booleanPreferencesKey("message_previews")
|
|
66
|
-
val AutoTranslate = booleanPreferencesKey("auto_translate")
|
|
67
|
-
}
|
|
68
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
package com.social.app.data.preferences
|
|
2
|
-
|
|
3
|
-
import kotlinx.coroutines.flow.Flow
|
|
4
|
-
|
|
5
|
-
interface PreferencesRepository {
|
|
6
|
-
val preferences: Flow<AppPreferences>
|
|
7
|
-
|
|
8
|
-
suspend fun updateThemeMode(themeMode: ThemeMode)
|
|
9
|
-
|
|
10
|
-
suspend fun updatePushNotifications(enabled: Boolean)
|
|
11
|
-
|
|
12
|
-
suspend fun updateMessagePreviews(enabled: Boolean)
|
|
13
|
-
|
|
14
|
-
suspend fun updateAutoTranslate(enabled: Boolean)
|
|
15
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
package com.social.app.model
|
|
2
|
-
|
|
3
|
-
data class User(
|
|
4
|
-
val id: String,
|
|
5
|
-
val handle: String,
|
|
6
|
-
val displayName: String,
|
|
7
|
-
val avatarUrl: String? = null,
|
|
8
|
-
val bio: String? = null,
|
|
9
|
-
val followers: Int = 0,
|
|
10
|
-
val following: Int = 0,
|
|
11
|
-
val isFollowed: Boolean = false
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
data class Post(
|
|
15
|
-
val id: String,
|
|
16
|
-
val authorId: String,
|
|
17
|
-
val authorName: String,
|
|
18
|
-
val authorHandle: String,
|
|
19
|
-
val authorAvatar: String? = null,
|
|
20
|
-
val body: String,
|
|
21
|
-
val mediaUrl: String? = null,
|
|
22
|
-
val likeCount: Int = 0,
|
|
23
|
-
val commentCount: Int = 0,
|
|
24
|
-
val timestamp: String,
|
|
25
|
-
val liked: Boolean = false
|
|
26
|
-
)
|
|
27
|
-
|
|
28
|
-
data class Story(
|
|
29
|
-
val id: String,
|
|
30
|
-
val authorId: String,
|
|
31
|
-
val authorName: String,
|
|
32
|
-
val authorAvatar: String? = null,
|
|
33
|
-
val previewUrl: String? = null
|
|
34
|
-
)
|