Skip to content

Commit 1ed7247

Browse files
authored
Merge pull request #44 from raj457036/v1.2.0
V1.2.2
2 parents 67775da + 015239d commit 1ed7247

File tree

440 files changed

+68639
-2146
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

440 files changed

+68639
-2146
lines changed

.github/copilot-instructions.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
## Architecture
2+
- `lib/main.dart` bootstraps the app: initializes platform services, calls `configureDependencies()`, and wires the `MultiBlocProvider` that wraps the UI; start here to understand startup side-effects.
3+
- `AppContent` (in `lib/main.dart`) drives theme/locale/window settings via `AppConfigCubit` and `StateInitializer`; changes to UI chrome should flow through this cubit rather than reaching into platform APIs directly.
4+
- Navigation lives in `lib/routes/routes.dart` using `go_router` with a `ShellRoute` for the main layout and modal `DynamicPage` wrappers for dialogs; add new pages there and expose dependencies through the surrounding `BlocProvider`s.
5+
- Desktop/mobile specific behavior is layered through widgets such as `EventBridge`, `WindowFocusManager`, and `TrayManager` in `lib/widgets`; hook platform-specific features by extending these wrappers instead of touching pages.
6+
7+
## Data & State
8+
- `lib/base` is layered: `db/` holds Isar collections, `domain/` declares interfaces and Freezed models, `data/` supplies `@LazySingleton` repositories/sources; mirror this structure for new features.
9+
- Clipboard items (`lib/base/db/clipboard_item/clipboard_item.dart`) manage encryption, file clean-up, and syncing; always call `copyWith(..)..applyId(original)` to preserve Isar IDs when mutating persisted items.
10+
- App-level preferences live in `lib/base/db/app_config/appconfig.dart` and are surfaced through `AppConfigCubit`; rely on its helpers (`changePausedTill`, theme setters) instead of writing to Isar manually.
11+
- Most async calls return `FailureOr<T>` (a `Future<Either<Failure, T>>` from `lib/common/failure.dart`); capture errors with `result.fold(...)` and construct new failures via `Failure.fromException` for consistency.
12+
13+
## Sync & Integrations
14+
- Supabase drives remote CRUD in `lib/base/data/sources/**/remote_source.dart` and real-time updates via `SBClipCrossSyncListener` / `SBCollectionCrossSyncListener`; when adding filters, respect the existing `deviceId` exclusion to avoid echoing local changes.
15+
- Local persistence (`lib/base/data/sources/clipboard/local_source.dart`) builds complex Isar queries for search, encryption filters, and pagination; reuse those builders rather than re-querying outside the source.
16+
- File attachments sync through Google Drive (`lib/base/data/services/google_drive_service.dart`); updates must set `driveFileId`, defer cleanup to `ClipboardItem.cleanUp`, and invoke `syncDone`/`cancelOperation` to release background workers.
17+
- Background services (hotkeys, Android clipboard listener, media kit) live under `lib/widgets/` and `packages/`; reuse these entry points instead of introducing new platform channels.
18+
19+
## Build & Tooling
20+
- Run `flutter pub run build_runner build --delete-conflicting-outputs` after editing anything annotated with `@freezed`, `@JsonSerializable`, `@injectable`, or Isar collections to regenerate `*.g.dart` files.
21+
- Localization is configured via `l10n.yaml`; regenerate translations with `flutter gen-l10n` (the `watch_locale.dart` helper can auto-run it, but double-check the working directory before use).
22+
- Use `flutter run --dart-define-from-file=local/prod.json` for feature testing so Supabase, RevenueCat, and Sentry keys resolve; release workflows are scripted under `scripts/build_*.sh` and expect the same defines plus obfuscation/split debug info.
23+
- Supabase functions can be tested locally with `supabase functions serve --env-file supabase/.env.local --no-verify-jwt` as documented in `supabase/scripts.txt`.
24+
25+
## Conventions & Tips
26+
- Register new services via `@LazySingleton`/`@Injectable` and access them through `sl()`; avoid manual `GetIt` lookups in widgets.
27+
- BLoC states/events use Freezed partials (`part 'xyz.freezed.dart'`); update state with `emit(state.copyWith(...))` and keep logic inside cubits rather than views.
28+
- UI code favors helpers from `lib/utils/common_extension.dart` and `lib/utils/utility.dart` (e.g., `context.colors`, `keyboardShortcut`); using them keeps desktop/mobile behavior aligned.
29+
- Follow `analysis_options.yaml` and never edit generated outputs under `**/*.g.dart` or `**/*.freezed.dart`; rerun generation instead if changes are needed.

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,6 @@ firebase.json
5757

5858
**/secret/**
5959

60-
**/packages/emoji_picker_flutter
60+
**/packages/emoji_picker_flutter
61+
**/packages/installed_apps
62+
packages/android_background_clipboard/*.md

.gitmodules

Lines changed: 0 additions & 12 deletions
This file was deleted.

analysis_options.yaml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
include: package:flutter_lints/flutter.yaml
22

3+
# Additional information about this file can be found at
4+
# https://dart.dev/guides/language/analysis-options
5+
36
analyzer:
4-
errors:
5-
invalid_annotation_target: ignore
67
exclude:
8+
- "**/*.g.dart"
9+
- "**/*.freezed.dart"
710
- "**/generated/*.dart"
11+
errors:
12+
invalid_annotation_target: ignore
813

914
linter:
1015
rules:

android/app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ if (flutterVersionName == null) {
3131
android {
3232
namespace "com.entilitystudio.CopyCat"
3333
compileSdk flutter.compileSdkVersion
34-
ndkVersion flutter.ndkVersion
34+
ndkVersion "28.2.13676358"
3535

3636
compileOptions {
3737
sourceCompatibility JavaVersion.VERSION_1_8
@@ -52,7 +52,7 @@ android {
5252
// You can update the following values to match your application needs.
5353
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
5454
minSdkVersion 26
55-
targetSdkVersion 34
55+
targetSdkVersion 36
5656
versionCode flutterVersionCode.toInteger()
5757
versionName flutterVersionName
5858
}
Lines changed: 69 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,38 @@
1-
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
2-
<uses-permission android:name="android.permission.INTERNET"/>
3-
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
4-
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
1+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2+
xmlns:tools="http://schemas.android.com/tools">
3+
<uses-permission android:name="android.permission.INTERNET" />
4+
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
5+
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
56
<uses-permission android:name="com.google.android.gms.permission.AD_ID" />
6-
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
7+
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
78
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
89
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
10+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
911
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
1012
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
13+
<uses-permission android:name="com.android.vending.BILLING" />
1114

12-
<application
13-
android:label="CopyCat Clipboard"
14-
android:name="${applicationName}"
15+
<application
16+
android:label="CopyCat Clipboard"
17+
android:name="${applicationName}"
1518
android:icon="@mipmap/ic_launcher"
1619
android:allowBackup="false"
1720
android:fullBackupContent="false"
1821
>
1922
<service
2023
android:name="com.entilitystudio.android_background_clipboard.CopyCatClipboardService"
21-
android:foregroundServiceType="dataSync"
24+
android:foregroundServiceType="specialUse|dataSync"
2225
android:enabled="true"
2326
android:exported="false"
2427
android:permission="android.permission.SYSTEM_ALERT_WINDOW">
28+
<!-- Explanation for specialUse foreground service type (required for Android 14+) -->
29+
<property
30+
android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
31+
android:value="clipboard_monitoring" />
2532
</service>
2633

27-
<service android:name="com.entilitystudio.android_background_clipboard.CopyCatAccessibilityService"
34+
<service
35+
android:name="com.entilitystudio.android_background_clipboard.CopyCatAccessibilityService"
2836
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
2937
android:label="CopyCat Clipboard"
3038
android:exported="true">
@@ -36,56 +44,58 @@
3644
android:resource="@xml/accessibility_service_config" />
3745
</service>
3846

39-
<receiver android:name="com.entilitystudio.android_background_clipboard.NotificationDeleteReceiver" />
47+
<receiver
48+
android:name="com.entilitystudio.android_background_clipboard.NotificationDeleteReceiver" />
4049

41-
<activity
42-
android:name=".MainActivity"
50+
<activity
51+
android:name=".MainActivity"
4352
android:exported="true"
44-
android:launchMode="singleTask"
45-
android:theme="@style/LaunchTheme"
46-
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
47-
android:hardwareAccelerated="true"
53+
android:launchMode="singleTask"
54+
android:theme="@style/LaunchTheme"
55+
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
56+
android:hardwareAccelerated="true"
4857
android:windowSoftInputMode="adjustResize"
4958
android:resizeableActivity="true"
5059
>
5160
<layout
52-
android:defaultHeight="500dp"
53-
android:defaultWidth="600dp"
54-
android:gravity="top|end"
55-
android:minHeight="450dp"
56-
android:minWidth="300dp" />
61+
android:defaultHeight="500dp"
62+
android:defaultWidth="600dp"
63+
android:gravity="top|end"
64+
android:minHeight="450dp"
65+
android:minWidth="300dp" />
5766
<!-- Specifies an Android theme to apply to this Activity as soon as
5867
the Android process has started. This theme is visible to the user
5968
while the Flutter UI initializes. After that, this theme continues
6069
to determine the Window background behind the Flutter UI. -->
61-
<meta-data android:name="io.flutter.embedding.android.NormalTheme" android:resource="@style/NormalTheme"/>
70+
<meta-data android:name="io.flutter.embedding.android.NormalTheme"
71+
android:resource="@style/NormalTheme" />
6272
<meta-data android:name="flutter_deeplinking_enabled" android:value="false" />
6373
<intent-filter>
64-
<action android:name="android.intent.action.MAIN"/>
65-
<category android:name="android.intent.category.LAUNCHER"/>
74+
<action android:name="android.intent.action.MAIN" />
75+
<category android:name="android.intent.category.LAUNCHER" />
6676
</intent-filter>
6777

6878
<intent-filter android:autoVerify="true">
69-
<action android:name="android.intent.action.VIEW"/>
70-
<category android:name="android.intent.category.DEFAULT"/>
71-
<category android:name="android.intent.category.BROWSABLE"/>
79+
<action android:name="android.intent.action.VIEW" />
80+
<category android:name="android.intent.category.DEFAULT" />
81+
<category android:name="android.intent.category.BROWSABLE" />
7282
<!-- Accepts URIs that begin with YOUR_SCHEME://YOUR_HOST -->
73-
<data android:scheme="clipboard" android:host="drive-connect"/>
74-
<data android:scheme="clipboard" android:host="reset-password"/>
75-
<data android:scheme="clipboard" android:host="auth"/>
83+
<data android:scheme="clipboard" android:host="drive-connect" />
84+
<data android:scheme="clipboard" android:host="reset-password" />
85+
<data android:scheme="clipboard" android:host="auth" />
7686
</intent-filter>
7787

7888
<!-- Share intents -->
7989
<intent-filter>
80-
<action android:name="android.intent.action.SEND"/>
81-
<category android:name="android.intent.category.DEFAULT"/>
82-
<data android:mimeType="text/*"/>
90+
<action android:name="android.intent.action.SEND" />
91+
<category android:name="android.intent.category.DEFAULT" />
92+
<data android:mimeType="text/*" />
8393
</intent-filter>
8494
<!-- Images -->
8595
<intent-filter>
86-
<action android:name="android.intent.action.SEND"/>
87-
<category android:name="android.intent.category.DEFAULT"/>
88-
<data android:mimeType="image/*"/>
96+
<action android:name="android.intent.action.SEND" />
97+
<category android:name="android.intent.category.DEFAULT" />
98+
<data android:mimeType="image/*" />
8999
</intent-filter>
90100
<intent-filter>
91101
<action android:name="android.intent.action.SEND_MULTIPLE" />
@@ -94,11 +104,11 @@
94104
</intent-filter>
95105
<!-- End Images -->
96106

97-
<!-- Videos -->
107+
<!-- Videos -->
98108
<intent-filter>
99-
<action android:name="android.intent.action.SEND"/>
100-
<category android:name="android.intent.category.DEFAULT"/>
101-
<data android:mimeType="video/*"/>
109+
<action android:name="android.intent.action.SEND" />
110+
<category android:name="android.intent.category.DEFAULT" />
111+
<data android:mimeType="video/*" />
102112
</intent-filter>
103113
<intent-filter>
104114
<action android:name="android.intent.action.SEND_MULTIPLE" />
@@ -108,9 +118,9 @@
108118
<!-- End Videos -->
109119
<!-- Files -->
110120
<intent-filter>
111-
<action android:name="android.intent.action.SEND"/>
112-
<category android:name="android.intent.category.DEFAULT"/>
113-
<data android:mimeType="*/*"/>
121+
<action android:name="android.intent.action.SEND" />
122+
<category android:name="android.intent.category.DEFAULT" />
123+
<data android:mimeType="*/*" />
114124
</intent-filter>
115125
<intent-filter>
116126
<action android:name="android.intent.action.SEND_MULTIPLE" />
@@ -119,24 +129,28 @@
119129
</intent-filter>
120130
<!-- End Files -->
121131
</activity>
122-
132+
123133
<!-- support for samsung multiwindow -->
124134
<meta-data android:name="com.samsung.android.sdk.multiwindow.enable"
125-
android:value="true"/>
126-
135+
android:value="true" />
136+
127137
<!-- Don't delete the meta-data below.
128138
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
129-
<meta-data android:name="flutterEmbedding" android:value="2"/>
139+
<meta-data android:name="flutterEmbedding" android:value="2" />
130140
<provider
131141
android:name="com.superlist.super_native_extensions.DataProvider"
132142
android:authorities="com.entilitystudio.CopyCat.SuperClipboardDataProvider"
133143
android:exported="true"
134-
android:grantUriPermissions="true" >
144+
android:grantUriPermissions="true">
135145
</provider>
136-
<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileProvider" android:exported="false" android:grantUriPermissions="true" tools:replace="android:authorities">
137-
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/filepaths" tools:replace="android:resource"/>
146+
<provider android:name="androidx.core.content.FileProvider"
147+
android:authorities="${applicationId}.fileProvider" android:exported="false"
148+
android:grantUriPermissions="true" tools:replace="android:authorities">
149+
<meta-data android:name="android.support.FILE_PROVIDER_PATHS"
150+
android:resource="@xml/filepaths" tools:replace="android:resource" />
138151
</provider>
139-
<meta-data android:name="com.google.android.gms.ads.APPLICATION_ID" android:value="ca-app-pub-2217728188815563~9689168977"/>
152+
<meta-data android:name="com.google.android.gms.ads.APPLICATION_ID"
153+
android:value="ca-app-pub-2217728188815563~9689168977" />
140154
</application>
141155
<!-- Required to query activities that can process text, see:
142156
https://developer.android.com/training/package-visibility?hl=en and
@@ -145,8 +159,8 @@
145159
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
146160
<queries>
147161
<intent>
148-
<action android:name="android.intent.action.PROCESS_TEXT"/>
149-
<data android:mimeType="text/plain"/>
162+
<action android:name="android.intent.action.PROCESS_TEXT" />
163+
<data android:mimeType="text/plain" />
150164
</intent>
151165
</queries>
152-
</manifest>
166+
</manifest>

android/build.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
buildscript {
2-
ext.kotlin_version='1.9.23';
2+
ext.kotlin_version='2.2.10';
33

44
dependencies {}
55

@@ -28,8 +28,8 @@ subprojects {
2828
if (project.plugins.hasPlugin("com.android.application") ||
2929
project.plugins.hasPlugin("com.android.library")) {
3030
project.android {
31-
compileSdkVersion 34
32-
buildToolsVersion "34.0.0"
31+
compileSdkVersion 36
32+
buildToolsVersion "35.0.0"
3333
}
3434
}
3535
}

android/gradle.properties

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
org.gradle.jvmargs=-Xmx4G
22
android.useAndroidX=true
33
android.enableJetifier=true
4+
android.experimental.enablePageSizeKb=16
5+
org.gradle.caching=true
6+
org.gradle.daemon=true
7+
org.gradle.parallel=true
8+
org.gradle.caching.cleanup=true

android/gradle/wrapper/gradle-wrapper.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
33
zipStoreBase=GRADLE_USER_HOME
44
zipStorePath=wrapper/dists
5-
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip
5+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-all.zip

android/settings.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ pluginManagement {
1919

2020
plugins {
2121
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
22-
id "com.android.application" version "7.3.0" apply false
23-
id "org.jetbrains.kotlin.android" version "1.9.23" apply false
22+
id "com.android.application" version "8.12.0" apply false
23+
id "org.jetbrains.kotlin.android" version "2.2.10" apply false
2424
}
2525

2626
include ":app"

0 commit comments

Comments
 (0)