Compare commits
237 Commits
v1.2.5
...
jf/android
Author | SHA1 | Date | |
---|---|---|---|
7747aa6b0e | |||
fda0b8ede5 | |||
bb51b3b0cb | |||
3ff8e82966 | |||
1dc1cce12b | |||
1c87d741cb | |||
d3b01b97fd | |||
f0413f99f0 | |||
2c213dee58 | |||
1652de4c2d | |||
df807a4a11 | |||
4f7a515490 | |||
341e04d645 | |||
872c4359d4 | |||
de1eac31da | |||
0dab102904 | |||
9c616eb734 | |||
691a0cb2ac | |||
6612227249 | |||
78e022f3cb | |||
677b9d4b7d | |||
cc55913022 | |||
08973bb829 | |||
fdce94f2e7 | |||
0897abf27e | |||
f07254dbd4 | |||
1408b7343a | |||
bedc3b66ec | |||
3e3941380d | |||
bbed4e0e75 | |||
a4ae6a20e1 | |||
3413b1686d | |||
c24670d5d8 | |||
a50c456390 | |||
915eb47ab6 | |||
c442a5d2e7 | |||
fbedf327ee | |||
45c684b774 | |||
b6015ae6ca | |||
b240dccc8e | |||
949562a34a | |||
9d8af331c7 | |||
031ff7519d | |||
62bab9d781 | |||
b9ff92a27b | |||
0332cd531d | |||
b76c5dd64c | |||
7325a08002 | |||
78bb1c6a6c | |||
c34ffe22da | |||
a621dc0291 | |||
88a12d3339 | |||
50d4cdfad9 | |||
366a461c96 | |||
3f1e9d0fff | |||
d09c10b3f8 | |||
fd5730e189 | |||
c9cc6a5df0 | |||
8d4b232097 | |||
8af643e584 | |||
70a56f4ade | |||
c685f33f99 | |||
518608893d | |||
856efa7c14 | |||
d1957ffb82 | |||
553a37961d | |||
bade5b4356 | |||
ab43d1a2c4 | |||
cf5c0b3263 | |||
d7295afa41 | |||
1ecddf9d5b | |||
479903ed77 | |||
1e4c10e819 | |||
473a65427a | |||
ad6ccc9376 | |||
995dfed85d | |||
0e74f88a8d | |||
c2e6d7ea98 | |||
e46432b86c | |||
9763a94e1d | |||
077fcbf9da | |||
9cdb6b7383 | |||
d01524020d | |||
fb2072676e | |||
162c7a2689 | |||
e218527953 | |||
3dddfa66cf | |||
3fd0a9a1ea | |||
7a35fe451d | |||
575ba8c2ef | |||
e82998bb32 | |||
3389e98861 | |||
92a743f2f0 | |||
4148240daf | |||
90ec117b4b | |||
9580e9b3e5 | |||
0afaa5a0aa | |||
fbce1dff73 | |||
b0d6561486 | |||
11639118c5 | |||
e54c893e6c | |||
8c57e5e323 | |||
b4ec7ec44e | |||
8b65256294 | |||
58f7bf14d7 | |||
d9aad3d34e | |||
ed48d95375 | |||
1eaded5694 | |||
70bb78afcb | |||
df2d2478d5 | |||
d5ae60327d | |||
615a092c1e | |||
5a7699d866 | |||
56a9bab3f2 | |||
e9bbf46b4f | |||
10f503a6c0 | |||
582f3156b2 | |||
90fb45146f | |||
c19c54e762 | |||
70e5a84b63 | |||
3a51fa83f2 | |||
cb90751330 | |||
835ed7e841 | |||
125ccd2dd1 | |||
5b991c4287 | |||
7dc3618afe | |||
eef4691814 | |||
9f71701845 | |||
d27203b041 | |||
4f280ec4c9 | |||
72cb2737ca | |||
215203bd16 | |||
3e320faece | |||
1049568246 | |||
71aa42118d | |||
4f21d3e6bd | |||
96d0fe9e5e | |||
69eee3e278 | |||
36bcd996c0 | |||
5fc39d8b8b | |||
5dce7787e1 | |||
8888dde792 | |||
6c8fc4cf87 | |||
ae9cc109db | |||
c8976ed17b | |||
ff7e115418 | |||
0310507c96 | |||
58c646e232 | |||
08328e2ca1 | |||
86b7228ffd | |||
e103c88ca6 | |||
94323a04e0 | |||
4776c375a1 | |||
1f4e6cf41c | |||
be6ed35888 | |||
b2ea50cea6 | |||
109b9287cf | |||
939d55ef0d | |||
3ee60e1a44 | |||
6fe567fa02 | |||
bc2d4f32c9 | |||
91290e9743 | |||
934f184b6f | |||
dbd48eae99 | |||
279007191b | |||
b3fdc20fc5 | |||
3fbf5d4eea | |||
332ffbb773 | |||
346a6c709e | |||
d4fe042245 | |||
b82c4a1777 | |||
7e0d1f0f1d | |||
f405a10c2e | |||
edbad79cd3 | |||
c9d8b2950a | |||
f2bc48f980 | |||
d56697c57c | |||
320ec41aae | |||
d85b3535d5 | |||
f8cd1cbba0 | |||
817ec208d6 | |||
554a165789 | |||
0c680370ef | |||
59541d2fcc | |||
32083c3564 | |||
258dbc4b8b | |||
6c8047ebac | |||
00a0135867 | |||
1db7be7a2c | |||
ff400f9c40 | |||
f03b45a98a | |||
cbe5bba986 | |||
268f4054a3 | |||
988c5d9881 | |||
e748e2f818 | |||
1b0a0dbda9 | |||
64d68389ba | |||
381c99b353 | |||
39ee3137f8 | |||
0d76be8634 | |||
9986f72e11 | |||
ef557e7b84 | |||
ec065c0122 | |||
2960c6e59e | |||
92dac6b932 | |||
20365393a3 | |||
8d238744c7 | |||
e33ff417fb | |||
d8922c2641 | |||
c6e0461857 | |||
30ca356dc8 | |||
7d11398e6d | |||
a4f52284ef | |||
c7d1a42d5a | |||
f83fd66bcc | |||
c2ec3647e2 | |||
ba63852b7d | |||
438041183c | |||
114540edd7 | |||
588b3e9508 | |||
2f0376f8f8 | |||
ab4051c018 | |||
c230c21218 | |||
c24e12237e | |||
e15dcba93b | |||
1362b93a74 | |||
ac18793f98 | |||
e52f65c773 | |||
06212a0d72 | |||
e77c0e3e73 | |||
cb6f41ec49 | |||
ab1e90ccad | |||
0ca3e96d91 | |||
d1c8eed3de | |||
aa6a2c684c | |||
d4778d9530 | |||
c702e08481 |
9
.github/workflows/commit_check.yml
vendored
@ -3,19 +3,22 @@ name: Commit Guard
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- "**"
|
|
||||||
- '!master'
|
- '!master'
|
||||||
|
pull_request:
|
||||||
|
# Run on any TARGET branches.
|
||||||
|
branches: [ '**' ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
releases:
|
commit_check:
|
||||||
name: Check commit
|
name: Check commit
|
||||||
runs-on: ubuntu-latest
|
runs-on: macos-latest
|
||||||
timeout-minutes: 30
|
timeout-minutes: 30
|
||||||
steps:
|
steps:
|
||||||
- name: checkout all the submodules
|
- name: checkout all the submodules
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
fetch-depth: 0
|
||||||
- run: submodules/flutter/bin/flutter doctor
|
- run: submodules/flutter/bin/flutter doctor
|
||||||
- run: submodules/flutter/bin/flutter pub get
|
- run: submodules/flutter/bin/flutter pub get
|
||||||
- run: submodules/flutter/bin/dart format --set-exit-if-changed lib test integration_test
|
- run: submodules/flutter/bin/dart format --set-exit-if-changed lib test integration_test
|
||||||
|
23
.github/workflows/parser_check.yml
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
name: Parser Check
|
||||||
|
|
||||||
|
on:
|
||||||
|
# Allow manual builds of this workflow.
|
||||||
|
workflow_dispatch: { }
|
||||||
|
# Run this job every hour.
|
||||||
|
schedule:
|
||||||
|
- cron: "0 * * * *"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
parser_check:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 0.5
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: dart-lang/setup-dart@v1
|
||||||
|
- name: Verify comment text parser
|
||||||
|
working-directory: ./scripts/bin
|
||||||
|
run: |
|
||||||
|
dart pub get
|
||||||
|
dart parser_verifier.dart -t ${{ secrets.GITHUB_TOKEN }}
|
17
.github/workflows/publish_ios.yml
vendored
@ -1,16 +1,21 @@
|
|||||||
name: Publish (iOS)
|
name: Publish (iOS)
|
||||||
|
|
||||||
on:
|
on:
|
||||||
# Allow manual builds of this workflow
|
# Allow manual builds of this workflow.
|
||||||
workflow_dispatch: {}
|
workflow_dispatch: {}
|
||||||
# Run the workflow whenever a new tag named 'v*' is pushed
|
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
|
# Only build when any of these directories has been modified.
|
||||||
|
paths:
|
||||||
|
- lib/**
|
||||||
|
- pubspec.lock
|
||||||
|
- pubspec.yaml
|
||||||
|
- submodules/**
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build_and_publish:
|
build_and_publish:
|
||||||
runs-on: macos-latest
|
runs-on: macos-15
|
||||||
timeout-minutes: 30
|
timeout-minutes: 30
|
||||||
|
|
||||||
env:
|
env:
|
||||||
@ -19,10 +24,16 @@ jobs:
|
|||||||
BUNDLE_GEMFILE: ${{ github.workspace }}/ios/Gemfile
|
BUNDLE_GEMFILE: ${{ github.workspace }}/ios/Gemfile
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
- name: Set XCode version
|
||||||
|
uses: maxim-lobanov/setup-xcode@v1
|
||||||
|
with:
|
||||||
|
xcode-version: '16.0'
|
||||||
|
|
||||||
- name: Check out from git
|
- name: Check out from git
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
fetch-depth: 0
|
||||||
- run: submodules/flutter/bin/flutter doctor
|
- run: submodules/flutter/bin/flutter doctor
|
||||||
- run: submodules/flutter/bin/flutter pub get
|
- run: submodules/flutter/bin/flutter pub get
|
||||||
- run: submodules/flutter/bin/dart format --set-exit-if-changed lib test integration_test
|
- run: submodules/flutter/bin/dart format --set-exit-if-changed lib test integration_test
|
||||||
|
1
.gitignore
vendored
@ -44,3 +44,4 @@ app.*.map.json
|
|||||||
/android/app/debug
|
/android/app/debug
|
||||||
/android/app/profile
|
/android/app/profile
|
||||||
/android/app/release
|
/android/app/release
|
||||||
|
/android/build/reports
|
||||||
|
@ -1 +1 @@
|
|||||||
2.7.5
|
3.3.0
|
||||||
|
33
README.md
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
# <img width="64" src="https://user-images.githubusercontent.com/7277662/167775086-0b234f28-dee4-44f6-aae4-14a28ed4bbb6.png"> Hacki for Hacker News
|
# <img width="64" src="https://user-images.githubusercontent.com/7277662/167775086-0b234f28-dee4-44f6-aae4-14a28ed4bbb6.png"> Hacki for Hacker News
|
||||||
|
|
||||||
A [Hacker News](https://news.ycombinator.com/) client made with Flutter that is just enough.
|
A [Hacker News](https://news.ycombinator.com/) client built with Flutter.
|
||||||
|
|
||||||
[](https://apps.apple.com/us/app/hacki/id1602043763?platform=iphone)
|
[](https://apps.apple.com/us/app/hacki/id1602043763?platform=iphone)
|
||||||
[](https://f-droid.org/en/packages/com.jiaqifeng.hacki/)
|
[](https://f-droid.org/en/packages/com.jiaqifeng.hacki/)
|
||||||
@ -29,27 +29,26 @@ Features:
|
|||||||
- Download stories and comments for offline reading.
|
- Download stories and comments for offline reading.
|
||||||
- Pick up where you left off.
|
- Pick up where you left off.
|
||||||
- Synced favorites and pins across devices. (iOS only)
|
- Synced favorites and pins across devices. (iOS only)
|
||||||
|
- Export or import your favorites.
|
||||||
- Launch from system share sheet.
|
- Launch from system share sheet.
|
||||||
- And more...
|
- And more...
|
||||||
|
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img width="200" alt="01" src="assets/screenshots/01.png">
|
<img width="400" alt="01" src="assets/screenshots/light-1.png">
|
||||||
<img width="200" alt="02" src="assets/screenshots/02.png">
|
<img width="400" alt="06" src="assets/screenshots/dark-1.png">
|
||||||
<img width="200" alt="03" src="assets/screenshots/03.png">
|
<img width="400" alt="02" src="assets/screenshots/light-2.png">
|
||||||
<img width="200" alt="04" src="assets/screenshots/04.png">
|
<img width="400" alt="07" src="assets/screenshots/dark-2.png">
|
||||||
<img width="200" alt="05" src="assets/screenshots/05.png">
|
<img width="400" alt="03" src="assets/screenshots/light-3.png">
|
||||||
<img width="200" alt="06" src="assets/screenshots/06.png">
|
<img width="400" alt="08" src="assets/screenshots/dark-3.png">
|
||||||
<img width="200" alt="07" src="assets/screenshots/07.png">
|
<img width="400" alt="04" src="assets/screenshots/light-4.png">
|
||||||
<img width="200" alt="08" src="assets/screenshots/08.png">
|
<img width="400" alt="09" src="assets/screenshots/dark-4.png">
|
||||||
<img width="200" alt="09" src="assets/screenshots/09.png">
|
<img width="400" alt="05" src="assets/screenshots/light-5.png">
|
||||||
<img width="200" alt="10" src="assets/screenshots/10.png">
|
<img width="400" alt="10" src="assets/screenshots/dark-5.png">
|
||||||
<img width="200" alt="11" src="assets/screenshots/11.png">
|
|
||||||
<img width="200" alt="12" src="assets/screenshots/12.png">
|
|
||||||
|
|
||||||
<img width="400" alt="ipad-01" src="assets/screenshots/ipad-01.png">
|
<img width="400" alt="ipad-01" src="assets/screenshots/tablet-light-1.png">
|
||||||
<img width="400" alt="ipad-02" src="assets/screenshots/ipad-02.png">
|
<img width="400" alt="ipad-02" src="assets/screenshots/tablet-dark-1.png">
|
||||||
<img width="400" alt="ipad-03" src="assets/screenshots/ipad-03.png">
|
<img width="400" alt="ipad-03" src="assets/screenshots/tablet-light-2.png">
|
||||||
<img width="400" alt="ipad-04" src="assets/screenshots/ipad-04.png">
|
<img width="400" alt="ipad-04" src="assets/screenshots/tablet-dark-2.png">
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
include: package:very_good_analysis/analysis_options.3.1.0.yaml
|
include: package:very_good_analysis/analysis_options.5.0.0.yaml
|
||||||
linter:
|
linter:
|
||||||
rules:
|
rules:
|
||||||
parameter_assignments: false
|
parameter_assignments: false
|
||||||
@ -11,3 +11,4 @@ linter:
|
|||||||
analyzer:
|
analyzer:
|
||||||
exclude:
|
exclude:
|
||||||
- "submodules/**"
|
- "submodules/**"
|
||||||
|
- "scripts/**"
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
plugins {
|
||||||
|
id "com.android.application"
|
||||||
|
id "kotlin-android"
|
||||||
|
id "dev.flutter.flutter-gradle-plugin"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def localProperties = new Properties()
|
def localProperties = new Properties()
|
||||||
def localPropertiesFile = rootProject.file('local.properties')
|
def localPropertiesFile = rootProject.file('local.properties')
|
||||||
if (localPropertiesFile.exists()) {
|
if (localPropertiesFile.exists()) {
|
||||||
@ -6,11 +13,6 @@ if (localPropertiesFile.exists()) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def flutterRoot = localProperties.getProperty('flutter.sdk')
|
|
||||||
if (flutterRoot == null) {
|
|
||||||
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
|
|
||||||
}
|
|
||||||
|
|
||||||
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
|
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
|
||||||
if (flutterVersionCode == null) {
|
if (flutterVersionCode == null) {
|
||||||
flutterVersionCode = '1'
|
flutterVersionCode = '1'
|
||||||
@ -21,10 +23,6 @@ if (flutterVersionName == null) {
|
|||||||
flutterVersionName = '1.0'
|
flutterVersionName = '1.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'com.android.application'
|
|
||||||
apply plugin: 'kotlin-android'
|
|
||||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
|
||||||
|
|
||||||
def keystoreProperties = new Properties()
|
def keystoreProperties = new Properties()
|
||||||
def keystorePropertiesFile = rootProject.file('key.properties')
|
def keystorePropertiesFile = rootProject.file('key.properties')
|
||||||
if (keystorePropertiesFile.exists()) {
|
if (keystorePropertiesFile.exists()) {
|
||||||
@ -33,11 +31,15 @@ if (keystorePropertiesFile.exists()) {
|
|||||||
|
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 33
|
namespace "com.jiaqifeng.hacki"
|
||||||
|
compileSdkVersion 35
|
||||||
|
ndkVersion = "27.0.12077973"
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
|
// Flag to enable support for the new language APIs
|
||||||
|
coreLibraryDesugaringEnabled true
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
@ -50,8 +52,8 @@ android {
|
|||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.jiaqifeng.hacki"
|
applicationId "com.jiaqifeng.hacki"
|
||||||
minSdkVersion 26
|
minSdkVersion 25
|
||||||
targetSdkVersion 33
|
targetSdkVersion 35
|
||||||
versionCode flutterVersionCode.toInteger()
|
versionCode flutterVersionCode.toInteger()
|
||||||
versionName flutterVersionName
|
versionName flutterVersionName
|
||||||
}
|
}
|
||||||
@ -64,12 +66,15 @@ android {
|
|||||||
storePassword keystoreProperties['storePassword']
|
storePassword keystoreProperties['storePassword']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
signingConfig signingConfigs.release
|
signingConfig signingConfigs.release
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
minifyEnabled true
|
||||||
|
shrinkResources true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
flutter {
|
flutter {
|
||||||
@ -77,7 +82,8 @@ flutter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.1.20"
|
||||||
|
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5'
|
||||||
}
|
}
|
||||||
|
|
||||||
ext.abiCodes = ["x86_64": 1, "armeabi-v7a": 2, "arm64-v8a": 3]
|
ext.abiCodes = ["x86_64": 1, "armeabi-v7a": 2, "arm64-v8a": 3]
|
||||||
|
@ -13,6 +13,9 @@
|
|||||||
<action android:name="android.intent.action.SEND" />
|
<action android:name="android.intent.action.SEND" />
|
||||||
<data android:mimeType="*/*" />
|
<data android:mimeType="*/*" />
|
||||||
</intent>
|
</intent>
|
||||||
|
<intent>
|
||||||
|
<action android:name="android.support.customtabs.action.CustomTabsService" />
|
||||||
|
</intent>
|
||||||
</queries>
|
</queries>
|
||||||
|
|
||||||
<application
|
<application
|
||||||
@ -20,7 +23,8 @@
|
|||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:fullBackupContent="@xml/backup_rules"
|
android:fullBackupContent="@xml/backup_rules"
|
||||||
android:usesCleartextTraffic="true">
|
android:usesCleartextTraffic="true"
|
||||||
|
android:enableOnBackInvokedCallback="true">
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:launchMode="singleTop"
|
android:launchMode="singleTop"
|
||||||
@ -37,15 +41,6 @@
|
|||||||
android:name="io.flutter.embedding.android.NormalTheme"
|
android:name="io.flutter.embedding.android.NormalTheme"
|
||||||
android:resource="@style/NormalTheme"
|
android:resource="@style/NormalTheme"
|
||||||
/>
|
/>
|
||||||
<!-- Displays an Android View that continues showing the launch screen
|
|
||||||
Drawable until Flutter paints its first frame, then this splash
|
|
||||||
screen fades out. A splash screen is useful to avoid any visual
|
|
||||||
gap between the end of Android's launch screen and the painting of
|
|
||||||
Flutter's first frame. -->
|
|
||||||
<meta-data
|
|
||||||
android:name="io.flutter.embedding.android.SplashScreenDrawable"
|
|
||||||
android:resource="@drawable/launch_background"
|
|
||||||
/>
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN"/>
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
<category android:name="android.intent.category.LAUNCHER"/>
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
BIN
android/app/src/main/res/drawable-night-v21/background.png
Normal file
After Width: | Height: | Size: 69 B |
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item>
|
||||||
|
<bitmap android:gravity="fill" android:src="@drawable/background"/>
|
||||||
|
</item>
|
||||||
|
</layer-list>
|
BIN
android/app/src/main/res/drawable-night/background.png
Normal file
After Width: | Height: | Size: 69 B |
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item>
|
||||||
|
<bitmap android:gravity="fill" android:src="@drawable/background"/>
|
||||||
|
</item>
|
||||||
|
</layer-list>
|
BIN
android/app/src/main/res/drawable-v21/background.png
Normal file
After Width: | Height: | Size: 69 B |
@ -1,12 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- Modify this file to customize your launch splash screen -->
|
|
||||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<item android:drawable="?android:colorBackground" />
|
<item>
|
||||||
|
<bitmap android:gravity="fill" android:src="@drawable/background"/>
|
||||||
<!-- You can insert your own image assets here -->
|
</item>
|
||||||
<!-- <item>
|
|
||||||
<bitmap
|
|
||||||
android:gravity="center"
|
|
||||||
android:src="@mipmap/launch_image" />
|
|
||||||
</item> -->
|
|
||||||
</layer-list>
|
</layer-list>
|
||||||
|
BIN
android/app/src/main/res/drawable/background.png
Normal file
After Width: | Height: | Size: 69 B |
@ -1,12 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- Modify this file to customize your launch splash screen -->
|
|
||||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<item android:drawable="@android:color/white" />
|
<item>
|
||||||
|
<bitmap android:gravity="fill" android:src="@drawable/background"/>
|
||||||
<!-- You can insert your own image assets here -->
|
</item>
|
||||||
<!-- <item>
|
|
||||||
<bitmap
|
|
||||||
android:gravity="center"
|
|
||||||
android:src="@mipmap/launch_image" />
|
|
||||||
</item> -->
|
|
||||||
</layer-list>
|
</layer-list>
|
||||||
|
@ -2,4 +2,5 @@
|
|||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<background android:drawable="@mipmap/ic_launcher_adaptive_back"/>
|
<background android:drawable="@mipmap/ic_launcher_adaptive_back"/>
|
||||||
<foreground android:drawable="@mipmap/ic_launcher_adaptive_fore"/>
|
<foreground android:drawable="@mipmap/ic_launcher_adaptive_fore"/>
|
||||||
|
<monochrome android:drawable="@mipmap/ic_launcher_monochrome"/>
|
||||||
</adaptive-icon>
|
</adaptive-icon>
|
BIN
android/app/src/main/res/mipmap-hdpi/ic_launcher_monochrome.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
android/app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.png
Normal file
After Width: | Height: | Size: 940 B |
BIN
android/app/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 5.4 KiB |
19
android/app/src/main/res/values-night-v31/styles.xml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
|
||||||
|
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||||
|
<item name="android:forceDarkAllowed">false</item>
|
||||||
|
<item name="android:windowFullscreen">false</item>
|
||||||
|
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
|
||||||
|
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
|
||||||
|
</style>
|
||||||
|
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||||
|
This theme determines the color of the Android Window while your
|
||||||
|
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||||
|
running.
|
||||||
|
|
||||||
|
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||||
|
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||||
|
<item name="android:windowBackground">?android:colorBackground</item>
|
||||||
|
</style>
|
||||||
|
</resources>
|
@ -5,6 +5,10 @@
|
|||||||
<!-- Show a splash screen on the activity. Automatically removed when
|
<!-- Show a splash screen on the activity. Automatically removed when
|
||||||
Flutter draws its first frame -->
|
Flutter draws its first frame -->
|
||||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||||
|
<item name="android:forceDarkAllowed">false</item>
|
||||||
|
<item name="android:windowFullscreen">false</item>
|
||||||
|
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
|
||||||
|
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
|
||||||
</style>
|
</style>
|
||||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||||
This theme determines the color of the Android Window while your
|
This theme determines the color of the Android Window while your
|
||||||
|
19
android/app/src/main/res/values-v31/styles.xml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
|
||||||
|
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||||
|
<item name="android:forceDarkAllowed">false</item>
|
||||||
|
<item name="android:windowFullscreen">false</item>
|
||||||
|
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
|
||||||
|
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
|
||||||
|
</style>
|
||||||
|
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||||
|
This theme determines the color of the Android Window while your
|
||||||
|
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||||
|
running.
|
||||||
|
|
||||||
|
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||||
|
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||||
|
<item name="android:windowBackground">?android:colorBackground</item>
|
||||||
|
</style>
|
||||||
|
</resources>
|
@ -5,6 +5,10 @@
|
|||||||
<!-- Show a splash screen on the activity. Automatically removed when
|
<!-- Show a splash screen on the activity. Automatically removed when
|
||||||
Flutter draws its first frame -->
|
Flutter draws its first frame -->
|
||||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||||
|
<item name="android:forceDarkAllowed">false</item>
|
||||||
|
<item name="android:windowFullscreen">false</item>
|
||||||
|
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
|
||||||
|
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
|
||||||
</style>
|
</style>
|
||||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||||
This theme determines the color of the Android Window while your
|
This theme determines the color of the Android Window while your
|
||||||
|
@ -1,16 +1,3 @@
|
|||||||
buildscript {
|
|
||||||
ext.kotlin_version = '1.7.0'
|
|
||||||
repositories {
|
|
||||||
google()
|
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
classpath 'com.android.tools.build:gradle:7.1.3'
|
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
@ -24,6 +11,6 @@ subprojects {
|
|||||||
project.evaluationDependsOn(':app')
|
project.evaluationDependsOn(':app')
|
||||||
}
|
}
|
||||||
|
|
||||||
task clean(type: Delete) {
|
tasks.register("clean", Delete) {
|
||||||
delete rootProject.buildDir
|
delete rootProject.buildDir
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
org.gradle.jvmargs=-Xmx1536M
|
org.gradle.jvmargs=-Xmx1536M
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
|
kotlin.jvm.target.validation.mode = IGNORE
|
@ -1,6 +1,7 @@
|
|||||||
#Fri Jun 23 08:50:38 CEST 2017
|
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
|
||||||
|
networkTimeout=10000
|
||||||
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip
|
|
||||||
|
@ -1,11 +1,25 @@
|
|||||||
include ':app'
|
pluginManagement {
|
||||||
|
def flutterSdkPath = {
|
||||||
|
def properties = new Properties()
|
||||||
|
file("local.properties").withInputStream { properties.load(it) }
|
||||||
|
def flutterSdkPath = properties.getProperty("flutter.sdk")
|
||||||
|
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
|
||||||
|
return flutterSdkPath
|
||||||
|
}()
|
||||||
|
|
||||||
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
|
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
|
||||||
def properties = new Properties()
|
|
||||||
|
|
||||||
assert localPropertiesFile.exists()
|
repositories {
|
||||||
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
|
google()
|
||||||
|
mavenCentral()
|
||||||
|
gradlePluginPortal()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def flutterSdkPath = properties.getProperty("flutter.sdk")
|
plugins {
|
||||||
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
|
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
|
||||||
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
|
id "com.android.application" version "8.11.0" apply false
|
||||||
|
id "org.jetbrains.kotlin.android" version "2.2.0" apply false
|
||||||
|
}
|
||||||
|
|
||||||
|
include ":app"
|
BIN
assets/fonts/atkinson_hyperlegible/AtkinsonHyperlegible-Bold.ttf
Normal file
BIN
assets/fonts/exo_2/Exo2-Bold.ttf
Normal file
BIN
assets/fonts/exo_2/Exo2-Regular.ttf
Normal file
BIN
assets/fonts/noto_serif/NotoSerif-Bold.ttf
Normal file
BIN
assets/fonts/noto_serif/NotoSerif-Regular.ttf
Normal file
BIN
assets/hacki-github.png
Normal file
After Width: | Height: | Size: 419 KiB |
BIN
assets/hacki-github.xcf
Normal file
BIN
assets/hacki.xcf
Normal file
Before Width: | Height: | Size: 548 KiB After Width: | Height: | Size: 333 KiB |
Before Width: | Height: | Size: 571 KiB After Width: | Height: | Size: 341 KiB |
Before Width: | Height: | Size: 592 KiB After Width: | Height: | Size: 359 KiB |
15
assets/remote-config-dev.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"athingComtrSelector": "#hnmain > tbody > tr > td > table > tbody > .athing.comtr",
|
||||||
|
"commentTextSelector": "td > table > tbody > tr > td.default > div.comment > div.commtext",
|
||||||
|
"commentHeadSelector": "td > table > tbody > tr > td.default > div > span > a",
|
||||||
|
"commentAgeSelector": "td > table > tbody > tr > td.default > div > span > span.age",
|
||||||
|
"commentIndentSelector": "td > table > tbody > tr > td.ind",
|
||||||
|
"storySelector": "#hnmain > tbody > tr > td > table > tbody > .athing",
|
||||||
|
"subtextSelector": "#hnmain > tbody > tr > td > table > tbody > tr > .subtext",
|
||||||
|
"titlelineSelector": ".title > .titleline > a",
|
||||||
|
"pointSelector": ".subline > .score",
|
||||||
|
"userSelector": ".subline > .hnuser",
|
||||||
|
"ageSelector": ".subline > .age",
|
||||||
|
"cmtCountSelector": ".subline > a",
|
||||||
|
"moreLinkSelector": "#hnmain > tbody > tr:nth-child(3) > td > table > tbody > tr > td.title > a"
|
||||||
|
}
|
15
assets/remote-config.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"athingComtrSelector": "#hnmain > tbody > tr > td > table > tbody > .athing.comtr",
|
||||||
|
"commentTextSelector": "td > table > tbody > tr > td.default > div.comment > div.commtext",
|
||||||
|
"commentHeadSelector": "td > table > tbody > tr > td.default > div > span > a",
|
||||||
|
"commentAgeSelector": "td > table > tbody > tr > td.default > div > span > span.age",
|
||||||
|
"commentIndentSelector": "td > table > tbody > tr > td.ind",
|
||||||
|
"storySelector": "#hnmain > tbody > tr > td > table > tbody > .athing",
|
||||||
|
"subtextSelector": "#hnmain > tbody > tr > td > table > tbody > tr > .subtext",
|
||||||
|
"titlelineSelector": ".title > .titleline > a",
|
||||||
|
"pointSelector": ".subline > .score",
|
||||||
|
"userSelector": ".subline > .hnuser",
|
||||||
|
"ageSelector": ".subline > .age",
|
||||||
|
"cmtCountSelector": ".subline > a",
|
||||||
|
"moreLinkSelector": "#hnmain > tbody > tr:nth-child(3) > td > table > tbody > tr > td.title > a"
|
||||||
|
}
|
BIN
assets/screenshots/dark-1.png
Normal file
After Width: | Height: | Size: 1003 KiB |
BIN
assets/screenshots/dark-2.png
Normal file
After Width: | Height: | Size: 912 KiB |
BIN
assets/screenshots/dark-3.png
Normal file
After Width: | Height: | Size: 252 KiB |
BIN
assets/screenshots/dark-4.png
Normal file
After Width: | Height: | Size: 734 KiB |
BIN
assets/screenshots/dark-5.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
assets/screenshots/hacki-1.png
Normal file
After Width: | Height: | Size: 890 KiB |
BIN
assets/screenshots/hacki-2.png
Normal file
After Width: | Height: | Size: 873 KiB |
BIN
assets/screenshots/hacki-3.png
Normal file
After Width: | Height: | Size: 770 KiB |
BIN
assets/screenshots/hacki-4.png
Normal file
After Width: | Height: | Size: 517 KiB |
BIN
assets/screenshots/light-1.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
BIN
assets/screenshots/light-2.png
Normal file
After Width: | Height: | Size: 893 KiB |
BIN
assets/screenshots/light-3.png
Normal file
After Width: | Height: | Size: 460 KiB |
BIN
assets/screenshots/light-4.png
Normal file
After Width: | Height: | Size: 712 KiB |
BIN
assets/screenshots/light-5.png
Normal file
After Width: | Height: | Size: 1.0 MiB |
BIN
assets/screenshots/tablet-dark-1.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
assets/screenshots/tablet-dark-2.png
Normal file
After Width: | Height: | Size: 1.5 MiB |
BIN
assets/screenshots/tablet-light-1.png
Normal file
After Width: | Height: | Size: 1.9 MiB |
BIN
assets/screenshots/tablet-light-2.png
Normal file
After Width: | Height: | Size: 1.7 MiB |
BIN
assets/tablet-hacki.xcf
Normal file
30
components/in_app_review/.gitignore
vendored
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# Miscellaneous
|
||||||
|
*.class
|
||||||
|
*.log
|
||||||
|
*.pyc
|
||||||
|
*.swp
|
||||||
|
.DS_Store
|
||||||
|
.atom/
|
||||||
|
.buildlog/
|
||||||
|
.history
|
||||||
|
.svn/
|
||||||
|
migrate_working_dir/
|
||||||
|
|
||||||
|
# IntelliJ related
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# The .vscode folder contains launch configuration and tasks you configure in
|
||||||
|
# VS Code which you may wish to be included in version control, so this line
|
||||||
|
# is commented out by default.
|
||||||
|
#.vscode/
|
||||||
|
|
||||||
|
# Flutter/Dart/Pub related
|
||||||
|
# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
|
||||||
|
/pubspec.lock
|
||||||
|
**/doc/api/
|
||||||
|
.dart_tool/
|
||||||
|
.packages
|
||||||
|
build/
|
39
components/in_app_review/.metadata
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# This file tracks properties of this Flutter project.
|
||||||
|
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||||
|
#
|
||||||
|
# This file should be version controlled.
|
||||||
|
|
||||||
|
version:
|
||||||
|
revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
|
||||||
|
channel: stable
|
||||||
|
|
||||||
|
project_type: plugin
|
||||||
|
|
||||||
|
# Tracks metadata for the flutter migrate command
|
||||||
|
migration:
|
||||||
|
platforms:
|
||||||
|
- platform: root
|
||||||
|
create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
|
||||||
|
base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
|
||||||
|
- platform: android
|
||||||
|
create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
|
||||||
|
base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
|
||||||
|
- platform: ios
|
||||||
|
create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
|
||||||
|
base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
|
||||||
|
- platform: macos
|
||||||
|
create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
|
||||||
|
base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
|
||||||
|
- platform: windows
|
||||||
|
create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
|
||||||
|
base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1
|
||||||
|
|
||||||
|
# User provided section
|
||||||
|
|
||||||
|
# List of Local paths (relative to this file) that should be
|
||||||
|
# ignored by the migrate tool.
|
||||||
|
#
|
||||||
|
# Files that are not part of the templates will be ignored by default.
|
||||||
|
unmanaged_files:
|
||||||
|
- 'lib/main.dart'
|
||||||
|
- 'ios/Runner.xcodeproj/project.pbxproj'
|
102
components/in_app_review/CHANGELOG.md
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
# [2.0.6]
|
||||||
|
- Update Android Play Core dependency to Play Review 2.0.1.
|
||||||
|
|
||||||
|
# [2.0.5]
|
||||||
|
|
||||||
|
- Migrate Android Play Core dependency to Play Review 2.0.0.
|
||||||
|
- Recreate the example app.
|
||||||
|
- Update in_app_review_platform_interface to 2.0.4
|
||||||
|
|
||||||
|
# [2.0.4]
|
||||||
|
|
||||||
|
- Migrate maven repository from jcenter to mavenCentral
|
||||||
|
- `isAvailable()` now returns `false` on web.
|
||||||
|
|
||||||
|
# [2.0.3]
|
||||||
|
|
||||||
|
- Fix iOS no-scene exception. ([#41](https://github.com/britannio/in_app_review/issues/41))
|
||||||
|
# [2.0.2]
|
||||||
|
|
||||||
|
- Replace iOS Swift code with Objective-C to add compatibility with Objective-C Flutter apps.
|
||||||
|
|
||||||
|
# [2.0.1]
|
||||||
|
|
||||||
|
- Fix rare null pointer exception on Android
|
||||||
|
- Fix MissingPluginException on MacOS
|
||||||
|
- Bump the minimum Dart SDK version from `2.12.0-0` to `2.12.0`.
|
||||||
|
- Bump the minimum Flutter version to `2.0.0`.
|
||||||
|
- Update in_app_review_platform_interface to 2.0.2
|
||||||
|
|
||||||
|
# [2.0.0]
|
||||||
|
|
||||||
|
- Migrate to null safety.
|
||||||
|
|
||||||
|
# [1.0.4]
|
||||||
|
|
||||||
|
- Update in_app_review_platform_interface to 1.0.5
|
||||||
|
- Remove dependency on `package_info`.
|
||||||
|
- Handle `openStoreListing()` with native code for Android, iOS and MacOS.
|
||||||
|
|
||||||
|
# [1.0.3]
|
||||||
|
|
||||||
|
- Update in_app_review_platform_interface to 1.0.4
|
||||||
|
- Update android compileSdkVersion to 29.
|
||||||
|
- Lower dependency version constraints.
|
||||||
|
|
||||||
|
# [1.0.2]
|
||||||
|
|
||||||
|
- Update in_app_review_platform_interface to 1.0.3
|
||||||
|
- Open the App Store directly instead of via the Safari View Controller.
|
||||||
|
- Add automated tests.
|
||||||
|
- Improve docs.
|
||||||
|
|
||||||
|
# [1.0.1+1]
|
||||||
|
|
||||||
|
- Update in_app_review_platform_interface to 1.0.2
|
||||||
|
|
||||||
|
# [1.0.0]
|
||||||
|
|
||||||
|
- Migrate to use `in_app_review_platform_interface`.
|
||||||
|
- Add Windows support for `openStoreListing`.
|
||||||
|
|
||||||
|
# [0.2.1+1]
|
||||||
|
|
||||||
|
- Improve iOS testing docs.
|
||||||
|
|
||||||
|
# [0.2.1]
|
||||||
|
|
||||||
|
- Update dependencies.
|
||||||
|
- Android Play Core Library V1.8.2 release notes:
|
||||||
|
- Fixed UI flickering in the In-App Review API
|
||||||
|
|
||||||
|
# [0.2.0+4]
|
||||||
|
|
||||||
|
- Remove deprecated API warning.
|
||||||
|
- Update dependencies.
|
||||||
|
|
||||||
|
# [0.2.0+3]
|
||||||
|
|
||||||
|
- Instructions in the README have been improved along with the example.
|
||||||
|
|
||||||
|
# [0.2.0+2]
|
||||||
|
|
||||||
|
- Update changelog format
|
||||||
|
|
||||||
|
# [0.2.0+1]
|
||||||
|
|
||||||
|
- Update MacOS testing instructions
|
||||||
|
|
||||||
|
# [0.2.0] Breaking Change
|
||||||
|
|
||||||
|
- Add MacOS support
|
||||||
|
- Rename `openStoreListing(iOSAppStoreId: '')` to `openStoreListing(appStoreId: '')`
|
||||||
|
|
||||||
|
# [0.1.0]
|
||||||
|
|
||||||
|
- Improve docs
|
||||||
|
- Set Android minSdkVersion to 16
|
||||||
|
- Refactor Android Plugin
|
||||||
|
|
||||||
|
# [0.0.1]
|
||||||
|
|
||||||
|
Initial release
|
21
components/in_app_review/LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020 Britannio Jarrett
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
0
components/in_app_review/analysis_options.yaml
Normal file
9
components/in_app_review/android/.gitignore
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
*.iml
|
||||||
|
.gradle
|
||||||
|
/local.properties
|
||||||
|
/.idea/workspace.xml
|
||||||
|
/.idea/libraries
|
||||||
|
.DS_Store
|
||||||
|
/build
|
||||||
|
/captures
|
||||||
|
.cxx
|
51
components/in_app_review/android/build.gradle
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
group 'dev.britannio.in_app_review'
|
||||||
|
version '1.0-SNAPSHOT'
|
||||||
|
|
||||||
|
buildscript {
|
||||||
|
ext.kotlin_version = '1.6.10'
|
||||||
|
repositories {
|
||||||
|
google()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:7.1.2'
|
||||||
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
google()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
apply plugin: 'com.android.library'
|
||||||
|
apply plugin: 'kotlin-android'
|
||||||
|
|
||||||
|
android {
|
||||||
|
namespace "dev.britannio.in_app_review"
|
||||||
|
|
||||||
|
compileSdkVersion 31
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = '1.8'
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
main.java.srcDirs += 'src/main/kotlin'
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
minSdkVersion 16
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
1
components/in_app_review/android/settings.gradle
Normal file
@ -0,0 +1 @@
|
|||||||
|
rootProject.name = 'in_app_review'
|
@ -0,0 +1,3 @@
|
|||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="dev.britannio.in_app_review">
|
||||||
|
</manifest>
|
@ -0,0 +1,59 @@
|
|||||||
|
package dev.britannio.in_app_review;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
|
||||||
|
import io.flutter.embedding.engine.plugins.FlutterPlugin;
|
||||||
|
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
|
||||||
|
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
|
||||||
|
import io.flutter.plugin.common.MethodCall;
|
||||||
|
import io.flutter.plugin.common.MethodChannel;
|
||||||
|
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
|
||||||
|
import io.flutter.plugin.common.MethodChannel.Result;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* InAppReviewPlugin
|
||||||
|
*/
|
||||||
|
public class InAppReviewPlugin implements FlutterPlugin, MethodCallHandler {
|
||||||
|
/// The MethodChannel that will the communication between Flutter and native Android
|
||||||
|
///
|
||||||
|
/// This local reference serves to register the plugin with the Flutter Engine and unregister it
|
||||||
|
/// when the Flutter Engine is detached from the Activity
|
||||||
|
private MethodChannel channel;
|
||||||
|
|
||||||
|
|
||||||
|
private final String TAG = "InAppReviewPlugin";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
|
||||||
|
channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "dev.britannio.in_app_review");
|
||||||
|
channel.setMethodCallHandler(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
|
||||||
|
Log.i(TAG, "onMethodCall: " + call.method);
|
||||||
|
switch (call.method) {
|
||||||
|
case "isAvailable":
|
||||||
|
case "requestReview":
|
||||||
|
case "openStoreListing":
|
||||||
|
default:
|
||||||
|
result.notImplemented();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
|
||||||
|
channel.setMethodCallHandler(null);
|
||||||
|
}
|
||||||
|
}
|
38
components/in_app_review/ios/.gitignore
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
.idea/
|
||||||
|
.vagrant/
|
||||||
|
.sconsign.dblite
|
||||||
|
.svn/
|
||||||
|
|
||||||
|
.DS_Store
|
||||||
|
*.swp
|
||||||
|
profile
|
||||||
|
|
||||||
|
DerivedData/
|
||||||
|
build/
|
||||||
|
GeneratedPluginRegistrant.h
|
||||||
|
GeneratedPluginRegistrant.m
|
||||||
|
|
||||||
|
.generated/
|
||||||
|
|
||||||
|
*.pbxuser
|
||||||
|
*.mode1v3
|
||||||
|
*.mode2v3
|
||||||
|
*.perspectivev3
|
||||||
|
|
||||||
|
!default.pbxuser
|
||||||
|
!default.mode1v3
|
||||||
|
!default.mode2v3
|
||||||
|
!default.perspectivev3
|
||||||
|
|
||||||
|
xcuserdata
|
||||||
|
|
||||||
|
*.moved-aside
|
||||||
|
|
||||||
|
*.pyc
|
||||||
|
*sync/
|
||||||
|
Icon?
|
||||||
|
.tags*
|
||||||
|
|
||||||
|
/Flutter/Generated.xcconfig
|
||||||
|
/Flutter/ephemeral/
|
||||||
|
/Flutter/flutter_export_environment.sh
|
0
components/in_app_review/ios/Assets/.gitkeep
Normal file
4
components/in_app_review/ios/Classes/InAppReviewPlugin.h
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#import <Flutter/Flutter.h>
|
||||||
|
|
||||||
|
@interface InAppReviewPlugin : NSObject<FlutterPlugin>
|
||||||
|
@end
|
107
components/in_app_review/ios/Classes/InAppReviewPlugin.m
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
#import "InAppReviewPlugin.h"
|
||||||
|
|
||||||
|
@import StoreKit;
|
||||||
|
@implementation InAppReviewPlugin
|
||||||
|
|
||||||
|
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
|
||||||
|
|
||||||
|
FlutterMethodChannel* channel = [FlutterMethodChannel methodChannelWithName:@"dev.britannio.in_app_review" binaryMessenger:[registrar messenger]];
|
||||||
|
|
||||||
|
InAppReviewPlugin* instance = [[InAppReviewPlugin alloc] init];
|
||||||
|
[registrar addMethodCallDelegate:instance channel:channel];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
|
||||||
|
|
||||||
|
[self logMessage:@"handle" details:call.method];
|
||||||
|
|
||||||
|
if ([call.method isEqual:@"requestReview"]) {
|
||||||
|
[self requestReview:result];
|
||||||
|
} else if ([call.method isEqual:@"isAvailable"]) {
|
||||||
|
[self isAvailable:result];
|
||||||
|
} else if ([call.method isEqual:@"openStoreListing"]) {
|
||||||
|
[self openStoreListingWithStoreId:call.arguments result:result];
|
||||||
|
} else {
|
||||||
|
[self logMessage:@"method not implemented"];
|
||||||
|
result(FlutterMethodNotImplemented);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) requestReview:(FlutterResult)result {
|
||||||
|
if (@available(iOS 14, *)) {
|
||||||
|
[self logMessage:@"iOS 14+"];
|
||||||
|
UIWindowScene *scene = [self findActiveScene];
|
||||||
|
[SKStoreReviewController requestReviewInScene:scene];
|
||||||
|
result(nil);
|
||||||
|
} else if (@available(iOS 10.3, *)) {
|
||||||
|
[self logMessage:@"iOS 10.3+"];
|
||||||
|
[SKStoreReviewController requestReview];
|
||||||
|
result(nil);
|
||||||
|
} else {
|
||||||
|
result([FlutterError errorWithCode:@"unavailable"
|
||||||
|
message:@"In-App Review unavailable"
|
||||||
|
details:nil]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIWindowScene *) findActiveScene API_AVAILABLE(ios(13.0)){
|
||||||
|
for (UIWindowScene *scene in UIApplication.sharedApplication.connectedScenes) {
|
||||||
|
|
||||||
|
if (scene.activationState == UISceneActivationStateForegroundActive) {
|
||||||
|
return scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) isAvailable:(FlutterResult)result {
|
||||||
|
if (@available(iOS 10.3, *)) {
|
||||||
|
[self logMessage:@"available"];
|
||||||
|
result(@YES);
|
||||||
|
} else {
|
||||||
|
[self logMessage:@"unavailable"];
|
||||||
|
result(@NO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) openStoreListingWithStoreId:(NSString *)storeId result:(FlutterResult)result {
|
||||||
|
|
||||||
|
if (!storeId) {
|
||||||
|
result([FlutterError errorWithCode:@"no-store-id"
|
||||||
|
message:@"Your store id must be passed as the method channel's argument"
|
||||||
|
details:nil]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"https://apps.apple.com/app/id%@?action=write-review", storeId]];
|
||||||
|
|
||||||
|
if (!url) {
|
||||||
|
result([FlutterError errorWithCode:@"url-construct-fail"
|
||||||
|
message:@"Failed to construct url"
|
||||||
|
details:nil]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UIApplication *app = [UIApplication sharedApplication];
|
||||||
|
if (@available(iOS 10.0, *)) {
|
||||||
|
[app openURL:url options:@{} completionHandler:nil];
|
||||||
|
} else {
|
||||||
|
[app openURL:url];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark - Logging Helpers
|
||||||
|
|
||||||
|
- (void) logMessage:(NSString *) message {
|
||||||
|
NSLog(@"InAppReviewPlugin: %@", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) logMessage:(NSString *) message
|
||||||
|
details:(NSString *) details {
|
||||||
|
NSLog(@"InAppReviewPlugin: %@ %@", message, details);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
23
components/in_app_review/ios/in_app_review.podspec
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#
|
||||||
|
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
|
||||||
|
# Run `pod lib lint in_app_review.podspec` to validate before publishing.
|
||||||
|
#
|
||||||
|
Pod::Spec.new do |s|
|
||||||
|
s.name = 'in_app_review'
|
||||||
|
s.version = '0.2.0'
|
||||||
|
s.summary = 'Flutter plugin for showing the In-App Review/System Rating pop up.'
|
||||||
|
s.description = <<-DESC
|
||||||
|
Flutter plugin for showing the In-App Review/System Rating pop up..
|
||||||
|
DESC
|
||||||
|
s.homepage = 'http://example.com'
|
||||||
|
s.license = { :file => '../LICENSE' }
|
||||||
|
s.author = { 'Britannio Jarrett' => 'britanniojarrett@gmail.com' }
|
||||||
|
s.source = { :path => '.' }
|
||||||
|
s.source_files = 'Classes/**/*'
|
||||||
|
s.dependency 'Flutter'
|
||||||
|
s.platform = :ios, '9.0'
|
||||||
|
|
||||||
|
# Flutter.framework does not contain a i386 slice.
|
||||||
|
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
|
||||||
|
s.swift_version = '5.0'
|
||||||
|
end
|
50
components/in_app_review/lib/in_app_review.dart
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:in_app_review_platform_interface/in_app_review_platform_interface.dart';
|
||||||
|
|
||||||
|
class InAppReview {
|
||||||
|
InAppReview._();
|
||||||
|
|
||||||
|
static final InAppReview instance = InAppReview._();
|
||||||
|
|
||||||
|
/// Checks if the device is able to show a review dialog.
|
||||||
|
///
|
||||||
|
/// On Android the Google Play Store must be installed and the device must be
|
||||||
|
/// running **Android 5 Lollipop(API 21)** or higher.
|
||||||
|
///
|
||||||
|
/// iOS devices must be running **iOS version 10.3** or higher.
|
||||||
|
///
|
||||||
|
/// MacOS devices must be running **MacOS version 10.14** or higher
|
||||||
|
Future<bool> isAvailable() => InAppReviewPlatform.instance.isAvailable();
|
||||||
|
|
||||||
|
/// Attempts to show the review dialog. It's recommended to first check if
|
||||||
|
/// the device supports this feature via [isAvailable].
|
||||||
|
///
|
||||||
|
/// To improve the users experience, iOS and Android enforce limitations
|
||||||
|
/// that might prevent this from working after a few tries. iOS & MacOS users
|
||||||
|
/// can also disable this feature entirely in the App Store settings.
|
||||||
|
///
|
||||||
|
/// More info and guidance:
|
||||||
|
/// https://developer.android.com/guide/playcore/in-app-review#when-to-request
|
||||||
|
/// https://developer.apple.com/design/human-interface-guidelines/ios/system-capabilities/ratings-and-reviews/
|
||||||
|
/// https://developer.apple.com/design/human-interface-guidelines/macos/system-capabilities/ratings-and-reviews/
|
||||||
|
Future<void> requestReview() => InAppReviewPlatform.instance.requestReview();
|
||||||
|
|
||||||
|
/// Opens the Play Store on Android, the App Store with a review
|
||||||
|
/// screen on iOS & MacOS and the Microsoft Store on Windows.
|
||||||
|
///
|
||||||
|
/// [appStoreId] is required for iOS & MacOS.
|
||||||
|
///
|
||||||
|
/// [microsoftStoreId] is required for Windows.
|
||||||
|
Future<void> openStoreListing({
|
||||||
|
/// Required for iOS & MacOS.
|
||||||
|
String? appStoreId,
|
||||||
|
|
||||||
|
/// Required for Windows.
|
||||||
|
String? microsoftStoreId,
|
||||||
|
}) =>
|
||||||
|
InAppReviewPlatform.instance.openStoreListing(
|
||||||
|
appStoreId: appStoreId,
|
||||||
|
microsoftStoreId: microsoftStoreId,
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
import Cocoa
|
||||||
|
import FlutterMacOS
|
||||||
|
import StoreKit
|
||||||
|
|
||||||
|
public class InAppReviewPlugin: NSObject, FlutterPlugin {
|
||||||
|
public static func register(with registrar: FlutterPluginRegistrar) {
|
||||||
|
let channel = FlutterMethodChannel(name: "dev.britannio.in_app_review", binaryMessenger: registrar.messenger)
|
||||||
|
let instance = InAppReviewPlugin()
|
||||||
|
registrar.addMethodCallDelegate(instance, channel: channel)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
||||||
|
switch call.method {
|
||||||
|
case "requestReview":
|
||||||
|
//App Store Review
|
||||||
|
if #available(OSX 10.14, *) {
|
||||||
|
SKStoreReviewController.requestReview()
|
||||||
|
result(nil)
|
||||||
|
} else {
|
||||||
|
result(FlutterError(code: "unavailable", message: "In-App Review unavailable", details: nil))
|
||||||
|
}
|
||||||
|
case "isAvailable":
|
||||||
|
if #available(OSX 10.14, *) {
|
||||||
|
result(true)
|
||||||
|
} else {
|
||||||
|
result(false)
|
||||||
|
}
|
||||||
|
case "openStoreListing":
|
||||||
|
let storeId : String = call.arguments as! String;
|
||||||
|
|
||||||
|
guard let writeReviewURL = URL(string: "macappstore://apps.apple.com/app/id" + storeId + "?action=write-review")
|
||||||
|
else {
|
||||||
|
result(FlutterError(code: "url_construct_fail", message: "Failed to construct url", details: nil))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
NSWorkspace.shared.open(writeReviewURL)
|
||||||
|
result(nil);
|
||||||
|
default:
|
||||||
|
result(FlutterMethodNotImplemented)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
22
components/in_app_review/macos/in_app_review.podspec
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#
|
||||||
|
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
|
||||||
|
# Run `pod lib lint in_app_review.podspec' to validate before publishing.
|
||||||
|
#
|
||||||
|
Pod::Spec.new do |s|
|
||||||
|
s.name = 'in_app_review'
|
||||||
|
s.version = '0.2.0'
|
||||||
|
s.summary = 'Flutter plugin for showing the In-App Review/System Rating pop up.'
|
||||||
|
s.description = <<-DESC
|
||||||
|
Flutter plugin for showing the In-App Review/System Rating pop up.
|
||||||
|
DESC
|
||||||
|
s.homepage = 'https://github.com/britannio/in_app_review'
|
||||||
|
s.license = { :file => '../LICENSE' }
|
||||||
|
s.author = { 'Britannio Jarrett' => 'britanniojarrett@gmail.com' }
|
||||||
|
s.source = { :path => '.' }
|
||||||
|
s.source_files = 'Classes/**/*'
|
||||||
|
s.dependency 'FlutterMacOS'
|
||||||
|
|
||||||
|
s.platform = :osx, '10.11'
|
||||||
|
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }
|
||||||
|
s.swift_version = '5.0'
|
||||||
|
end
|
46
components/in_app_review/pubspec.yaml
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
name: in_app_review
|
||||||
|
description: Flutter plugin for showing the In-App Review/System Rating pop up on Android, iOS and MacOS. It makes it easy for users to rate your app.
|
||||||
|
version: 2.0.6
|
||||||
|
homepage: https://github.com/britannio/in_app_review/tree/master/in_app_review
|
||||||
|
|
||||||
|
environment:
|
||||||
|
sdk: '>=2.12.0 <3.0.0'
|
||||||
|
flutter: ">=2.0.0"
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
flutter:
|
||||||
|
sdk: flutter
|
||||||
|
|
||||||
|
in_app_review_platform_interface: ^2.0.4
|
||||||
|
|
||||||
|
dev_dependencies:
|
||||||
|
flutter_test:
|
||||||
|
sdk: flutter
|
||||||
|
mockito: ^5.0.0
|
||||||
|
plugin_platform_interface: ^2.0.0
|
||||||
|
|
||||||
|
|
||||||
|
# For information on the generic Dart part of this file, see the
|
||||||
|
# following page: https://dart.dev/tools/pub/pubspec
|
||||||
|
|
||||||
|
# The following section is specific to Flutter packages.
|
||||||
|
flutter:
|
||||||
|
# This section identifies this Flutter project as a plugin project.
|
||||||
|
# The 'pluginClass' specifies the class (in Java, Kotlin, Swift, Objective-C, etc.)
|
||||||
|
# which should be registered in the plugin registry. This is required for
|
||||||
|
# using method channels.
|
||||||
|
# The Android 'package' specifies package in which the registered class is.
|
||||||
|
# This is required for using method channels on Android.
|
||||||
|
# The 'ffiPlugin' specifies that native code should be built and bundled.
|
||||||
|
# This is required for using `dart:ffi`.
|
||||||
|
# All these are used by the tooling to maintain consistency when
|
||||||
|
# adding or updating assets for this project.
|
||||||
|
plugin:
|
||||||
|
platforms:
|
||||||
|
android:
|
||||||
|
package: dev.britannio.in_app_review
|
||||||
|
pluginClass: InAppReviewPlugin
|
||||||
|
ios:
|
||||||
|
pluginClass: InAppReviewPlugin
|
||||||
|
macos:
|
||||||
|
pluginClass: InAppReviewPlugin
|
12
components/in_app_review_platform_interface/.gitignore
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
.DS_Store
|
||||||
|
.dart_tool/
|
||||||
|
|
||||||
|
.packages
|
||||||
|
.pub/
|
||||||
|
|
||||||
|
build/
|
||||||
|
|
||||||
|
|
||||||
|
pubspec.lock
|
||||||
|
.flutter-plugins
|
||||||
|
.flutter-plugins-dependencies
|
46
components/in_app_review_platform_interface/CHANGELOG.md
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# [2.0.4]
|
||||||
|
|
||||||
|
- Update usage of `pkg:url_launcher` to address deprecations.
|
||||||
|
|
||||||
|
# [2.0.3]
|
||||||
|
|
||||||
|
- `isAvailable()` now returns `false` on web.
|
||||||
|
|
||||||
|
# [2.0.2]
|
||||||
|
|
||||||
|
- Bump the minimum Flutter version to `2.0.0`.
|
||||||
|
|
||||||
|
# [2.0.1]
|
||||||
|
|
||||||
|
- Bump the minimum Dart SDK version from `2.12.0-0` to `2.12.0`.
|
||||||
|
|
||||||
|
# [2.0.0]
|
||||||
|
|
||||||
|
- Migrate to null safety.
|
||||||
|
|
||||||
|
# [1.0.5]
|
||||||
|
|
||||||
|
- Remove dependency on `package_info`.
|
||||||
|
- Handle `openStoreListing()` with native code for Android, iOS and MacOS.
|
||||||
|
|
||||||
|
# [1.0.4]
|
||||||
|
|
||||||
|
- Lower dependency version constraints
|
||||||
|
|
||||||
|
# [1.0.3]
|
||||||
|
|
||||||
|
- Open the App Store directly instead of via the Safari View Controller.
|
||||||
|
- Add automated tests.
|
||||||
|
|
||||||
|
# [1.0.2]
|
||||||
|
|
||||||
|
- Rename `openStoreListing(windowsStoreId: '')` to `openStoreListing(microsoftStoreId: '')`.
|
||||||
|
- Update dependencies.
|
||||||
|
|
||||||
|
# [1.0.1]
|
||||||
|
|
||||||
|
- Remove unnecessary files.
|
||||||
|
|
||||||
|
# [1.0.0]
|
||||||
|
|
||||||
|
- Initial release.
|
21
components/in_app_review_platform_interface/LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020 Britannio Jarrett
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
26
components/in_app_review_platform_interface/README.md
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# in_app_review_platform_interface
|
||||||
|
|
||||||
|
A common platform interface for the [`in_app_review`][1] plugin.
|
||||||
|
|
||||||
|
This interface allows platform-specific implementations of the `in_app_review`
|
||||||
|
plugin, as well as the plugin itself, to ensure they are supporting the
|
||||||
|
same interface.
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
|
||||||
|
To implement a new platform-specific implementation of `in_app_review`, extend
|
||||||
|
[`InAppReviewPlatform`][2] with an implementation that performs the
|
||||||
|
platform-specific behavior, and when you register your plugin, set the default
|
||||||
|
`InAppReviewPlatform` by calling
|
||||||
|
`InAppReviewPlatform.instance = MyInAppReview()`.
|
||||||
|
|
||||||
|
# Note on breaking changes
|
||||||
|
|
||||||
|
Strongly prefer non-breaking changes (such as adding a method to the interface)
|
||||||
|
over breaking changes for this package.
|
||||||
|
|
||||||
|
See https://flutter.dev/go/platform-interface-breaking-changes for a discussion
|
||||||
|
on why a less-clean interface is preferable to a breaking change.
|
||||||
|
|
||||||
|
[1]: ../in_app_review
|
||||||
|
[2]: lib/in_app_review_platform_interface.dart
|
@ -0,0 +1,71 @@
|
|||||||
|
import 'package:in_app_review_platform_interface/method_channel_in_app_review.dart';
|
||||||
|
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
|
||||||
|
|
||||||
|
/// The interface that implementations of in_app_review must implement.
|
||||||
|
///
|
||||||
|
/// Platform implementations should extend this class rather than implement it
|
||||||
|
/// as `in_app_review` does not consider newly added methods to be breaking
|
||||||
|
/// changes. Extending this class (using `extends`) ensures that the subclass
|
||||||
|
/// will get the default implementation, while platform implementations that
|
||||||
|
/// `implements` this interface will be broken by newly added
|
||||||
|
/// [InAppReviewPlatform] methods.
|
||||||
|
abstract class InAppReviewPlatform extends PlatformInterface {
|
||||||
|
InAppReviewPlatform() : super(token: _token);
|
||||||
|
|
||||||
|
static InAppReviewPlatform _instance = MethodChannelInAppReview();
|
||||||
|
|
||||||
|
static final Object _token = Object();
|
||||||
|
|
||||||
|
static InAppReviewPlatform get instance => _instance;
|
||||||
|
|
||||||
|
/// Platform-specific plugins should set this with their own platform-specific
|
||||||
|
/// class that extends [InAppReviewPlatform] when they register themselves.
|
||||||
|
static set instance(InAppReviewPlatform instance) {
|
||||||
|
PlatformInterface.verifyToken(instance, _token);
|
||||||
|
_instance = instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks if the device is able to show a review dialog.
|
||||||
|
///
|
||||||
|
/// On Android the Google Play Store must be installed and the device must be
|
||||||
|
/// running **Android 5 Lollipop(API 21)** or higher.
|
||||||
|
///
|
||||||
|
/// iOS devices must be running **iOS version 10.3** or higher.
|
||||||
|
///
|
||||||
|
/// MacOS devices must be running **MacOS version 10.14** or higher
|
||||||
|
Future<bool> isAvailable() {
|
||||||
|
throw UnimplementedError('isAvailable() has not been implemented.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Attempts to show the review dialog. It's recommended to first check if
|
||||||
|
/// this cannot be done via [isAvailable]. If it is not available then
|
||||||
|
/// you can open the store listing via [openStoreListing].
|
||||||
|
///
|
||||||
|
/// To improve the users experience, iOS and Android enforce limitations
|
||||||
|
/// that might prevent this from working after a few tries. iOS & MacOS users
|
||||||
|
/// can also disable this feature entirely in the App Store settings.
|
||||||
|
///
|
||||||
|
/// More info and guidance:
|
||||||
|
/// https://developer.android.com/guide/playcore/in-app-review#when-to-request
|
||||||
|
/// https://developer.apple.com/design/human-interface-guidelines/ios/system-capabilities/ratings-and-reviews/
|
||||||
|
/// https://developer.apple.com/design/human-interface-guidelines/macos/system-capabilities/ratings-and-reviews/
|
||||||
|
Future<void> requestReview() {
|
||||||
|
throw UnimplementedError('requestReview() has not been implemented.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Opens the Play Store on Android, the App Store with a review
|
||||||
|
/// screen on iOS & MacOS and the Microsoft Store on Windows.
|
||||||
|
///
|
||||||
|
/// [appStoreId] is required for iOS & MacOS.
|
||||||
|
///
|
||||||
|
/// [microsoftStoreId] is required for Windows.
|
||||||
|
Future<void> openStoreListing({
|
||||||
|
/// Required for iOS & MacOS.
|
||||||
|
String? appStoreId,
|
||||||
|
|
||||||
|
/// Required for Windows.
|
||||||
|
String? microsoftStoreId,
|
||||||
|
}) {
|
||||||
|
throw UnimplementedError('openStoreListing() has not been implemented.');
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:platform/platform.dart';
|
||||||
|
import 'package:url_launcher/url_launcher_string.dart';
|
||||||
|
|
||||||
|
import 'in_app_review_platform_interface.dart';
|
||||||
|
|
||||||
|
/// An implementation of [InAppReviewPlatform] that uses method channels.
|
||||||
|
class MethodChannelInAppReview extends InAppReviewPlatform {
|
||||||
|
MethodChannel _channel = MethodChannel('dev.britannio.in_app_review');
|
||||||
|
Platform _platform = const LocalPlatform();
|
||||||
|
|
||||||
|
@visibleForTesting
|
||||||
|
set channel(MethodChannel channel) => _channel = channel;
|
||||||
|
|
||||||
|
@visibleForTesting
|
||||||
|
set platform(Platform platform) => _platform = platform;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> isAvailable() async {
|
||||||
|
if (kIsWeb) return false;
|
||||||
|
return _channel
|
||||||
|
.invokeMethod<bool>('isAvailable')
|
||||||
|
.then((bool? available) => available ?? false, onError: (_) => false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> requestReview() => _channel.invokeMethod('requestReview');
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> openStoreListing({
|
||||||
|
String? appStoreId,
|
||||||
|
String? microsoftStoreId,
|
||||||
|
}) async {
|
||||||
|
final bool isiOS = _platform.isIOS;
|
||||||
|
final bool isMacOS = _platform.isMacOS;
|
||||||
|
final bool isAndroid = _platform.isAndroid;
|
||||||
|
final bool isWindows = _platform.isWindows;
|
||||||
|
|
||||||
|
if (isiOS || isMacOS) {
|
||||||
|
await _channel.invokeMethod(
|
||||||
|
'openStoreListing',
|
||||||
|
ArgumentError.checkNotNull(appStoreId, 'appStoreId'),
|
||||||
|
);
|
||||||
|
} else if (isAndroid) {
|
||||||
|
await _channel.invokeMethod('openStoreListing');
|
||||||
|
} else if (isWindows) {
|
||||||
|
ArgumentError.checkNotNull(microsoftStoreId, 'microsoftStoreId');
|
||||||
|
await _launchUrl(
|
||||||
|
'ms-windows-store://review/?ProductId=$microsoftStoreId',
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
throw UnsupportedError(
|
||||||
|
'Platform(${_platform.operatingSystem}) not supported',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _launchUrl(String url) async {
|
||||||
|
if (!await canLaunchUrlString(url)) return;
|
||||||
|
await launchUrlString(url, mode: LaunchMode.externalNonBrowserApplication);
|
||||||
|
}
|
||||||
|
}
|
24
components/in_app_review_platform_interface/pubspec.yaml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
name: in_app_review_platform_interface
|
||||||
|
description: A common platform interface for the in_app_review plugin.
|
||||||
|
# NOTE: We strongly prefer non-breaking changes, even at the expense of a
|
||||||
|
# less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes
|
||||||
|
version: 2.0.4
|
||||||
|
homepage: https://github.com/britannio/in_app_review/tree/master/in_app_review_platform_interface
|
||||||
|
|
||||||
|
environment:
|
||||||
|
sdk: '>=2.12.0 <3.0.0'
|
||||||
|
flutter: ">=2.0.0"
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
flutter:
|
||||||
|
sdk: flutter
|
||||||
|
|
||||||
|
url_launcher: ^6.1.0
|
||||||
|
plugin_platform_interface: ^2.0.0
|
||||||
|
platform: ^3.0.0
|
||||||
|
|
||||||
|
|
||||||
|
dev_dependencies:
|
||||||
|
flutter_test:
|
||||||
|
sdk: flutter
|
||||||
|
|
@ -76,6 +76,15 @@ final class SharedPrefsCore {
|
|||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fileprivate func remove(key: String?) -> Bool{
|
||||||
|
if let key = key {
|
||||||
|
let keyStore = NSUbiquitousKeyValueStore()
|
||||||
|
keyStore.removeObject(forKey: key)
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SwiftSyncedSharedPreferencesPlugin: NSObject, FlutterPlugin {
|
public class SwiftSyncedSharedPreferencesPlugin: NSObject, FlutterPlugin {
|
||||||
@ -87,6 +96,14 @@ public class SwiftSyncedSharedPreferencesPlugin: NSObject, FlutterPlugin {
|
|||||||
|
|
||||||
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
||||||
switch call.method {
|
switch call.method {
|
||||||
|
case "remove":
|
||||||
|
if let params = call.arguments as? [String: Any] {
|
||||||
|
let key = params[keyKey] as? String
|
||||||
|
|
||||||
|
let res = SharedPrefsCore.shared.remove(key: key)
|
||||||
|
result(res)
|
||||||
|
}
|
||||||
|
|
||||||
case "setBool":
|
case "setBool":
|
||||||
if let params = call.arguments as? [String: Any] {
|
if let params = call.arguments as? [String: Any] {
|
||||||
let val = params[valKey] as? Bool
|
let val = params[valKey] as? Bool
|
||||||
|
@ -15,6 +15,14 @@ class SyncedSharedPreferences {
|
|||||||
const MethodChannel(channel),
|
const MethodChannel(channel),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Future<bool?> remove({
|
||||||
|
required String key,
|
||||||
|
}) async {
|
||||||
|
return _channel.invokeMethod('remove', <String, dynamic>{
|
||||||
|
'key': key,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Future<bool?> setBool({
|
Future<bool?> setBool({
|
||||||
required String key,
|
required String key,
|
||||||
required bool val,
|
required bool val,
|
||||||
|
@ -5,103 +5,116 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: async
|
name: async
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.8.2"
|
version: "2.11.0"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: boolean_selector
|
name: boolean_selector
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0"
|
version: "2.1.1"
|
||||||
characters:
|
characters:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: characters
|
name: characters
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.3.0"
|
||||||
charcode:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: charcode
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.3.1"
|
|
||||||
clock:
|
clock:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: clock
|
name: clock
|
||||||
url: "https://pub.dartlang.org"
|
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.1"
|
||||||
collection:
|
collection:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: collection
|
name: collection
|
||||||
url: "https://pub.dartlang.org"
|
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.15.0"
|
version: "1.18.0"
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: fake_async
|
name: fake_async
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.3.1"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
flutter_lints:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description:
|
|
||||||
name: flutter_lints
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.4"
|
|
||||||
flutter_test:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
lints:
|
leak_tracker:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: lints
|
name: leak_tracker
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.1"
|
version: "10.0.5"
|
||||||
|
leak_tracker_flutter_testing:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: leak_tracker_flutter_testing
|
||||||
|
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.5"
|
||||||
|
leak_tracker_testing:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: leak_tracker_testing
|
||||||
|
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.1"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: matcher
|
name: matcher
|
||||||
url: "https://pub.dartlang.org"
|
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.11"
|
version: "0.12.16+1"
|
||||||
material_color_utilities:
|
material_color_utilities:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: material_color_utilities
|
name: material_color_utilities
|
||||||
url: "https://pub.dartlang.org"
|
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.3"
|
version: "0.11.1"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: meta
|
name: meta
|
||||||
url: "https://pub.dartlang.org"
|
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.7.0"
|
version: "1.15.0"
|
||||||
path:
|
path:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path
|
name: path
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.0"
|
version: "1.9.0"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -111,58 +124,66 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: source_span
|
name: source_span
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.1"
|
version: "1.10.0"
|
||||||
stack_trace:
|
stack_trace:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stack_trace
|
name: stack_trace
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.10.0"
|
version: "1.11.1"
|
||||||
stream_channel:
|
stream_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stream_channel
|
name: stream_channel
|
||||||
url: "https://pub.dartlang.org"
|
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0"
|
version: "2.1.2"
|
||||||
string_scanner:
|
string_scanner:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: string_scanner
|
name: string_scanner
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.2.0"
|
||||||
term_glyph:
|
term_glyph:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: term_glyph
|
name: term_glyph
|
||||||
url: "https://pub.dartlang.org"
|
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.2.1"
|
||||||
test_api:
|
test_api:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.4.8"
|
version: "0.7.2"
|
||||||
typed_data:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: typed_data
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.3.0"
|
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vector_math
|
name: vector_math
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "2.1.4"
|
||||||
|
vm_service:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: vm_service
|
||||||
|
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "14.2.5"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=2.16.2 <3.0.0"
|
dart: ">=3.3.0 <4.0.0"
|
||||||
flutter: ">=2.5.0"
|
flutter: ">=3.18.0-18.0.pre.54"
|
||||||
|
1
fastlane/metadata/android/en-US/changelogs/108.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
- Navigation shortcuts.
|
1
fastlane/metadata/android/en-US/changelogs/121.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
- Ability to mark a story as read once scrolling past.
|
2
fastlane/metadata/android/en-US/changelogs/125.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
- Ability to customize text scale factor.
|
||||||
|
- Ability to customize app's accent color.
|
4
fastlane/metadata/android/en-US/changelogs/127.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
- Ability to use Material 3.
|
||||||
|
- Ability to search in thread.
|
||||||
|
- Ability to customize text scale factor.
|
||||||
|
- Ability to customize app's accent color.
|
5
fastlane/metadata/android/en-US/changelogs/128.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
- Ability to use pagination on home screen.
|
||||||
|
- Ability to use Material 3 (experimental).
|
||||||
|
- Ability to search in thread.
|
||||||
|
- Ability to customize text scale factor.
|
||||||
|
- Ability to customize app's accent color.
|
5
fastlane/metadata/android/en-US/changelogs/129.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
- Ability to use manual pagination on home screen.
|
||||||
|
- Ability to use Material 3 (experimental).
|
||||||
|
- Ability to search in thread.
|
||||||
|
- Ability to customize text scale factor.
|
||||||
|
- Ability to customize app's accent color.
|