Compare commits

...

40 Commits

Author SHA1 Message Date
b3e994269c v0.2.32 (#74)
* fixed background color of nav bar on Android.

* fixed comment tile overflow.

* added github action. (#73)

* updated provisioning profile.

* updated profile.

* updated profile.

* updated profile

* updated profile.

* updated profile.

* updated fastfile.

* updated actions

* updated action.

* updated fastlane.

* revert actions.

* fixed action.

* avoid running on tag creation.

* updated action.

* bump version of Flutter.

* bump version of Flutter.
2022-10-14 19:39:26 -07:00
a2c66a0075 fixed background color of nav bar on Android. (#72) 2022-09-17 00:44:27 -07:00
5f43fd6968 v0.2.31 (#71)
* bumped version.

* bumped version.

* bumped version

* bumped version.

* downgrade flutter version.

* Use transparent color for navigation bar (#70)

* Use transparent color for navigation bar

* Fixed whitespace

Co-authored-by: Niklas Weinhart <git@weinhart.net>

* bumped ios version.

* bumped versions.

* updated min screen width.

* removed print.

* fixed stack overflow in EditCubit.

* added integration test.

* bumped version.

Co-authored-by: wnhrt <github@weinhart.net>
Co-authored-by: Niklas Weinhart <git@weinhart.net>
2022-09-16 22:37:16 -07:00
d83381a7fd v0.2.30 (#68)
* bumped version.

* cache  in case app gets killed in the background.

* bumped flutter version.

* updated

* improved 'ReplyBox'.

* fixed lint.

* fixed EditCubit.

* updated EditCubit.

* fixed navigation in tablet mode.

* clear cache after submission.
2022-08-05 22:13:30 -07:00
764ff09345 v0.2.29-hotfix (#67)
* fixed datetime extension.

* updated README.md
2022-07-06 20:37:18 -07:00
ab449adce2 v0.2.29 (#66)
* fixed stuff.

* fixed UI.

* bumped version.
2022-07-06 17:04:14 -07:00
2ec41b26f2 updated README.md 2022-07-06 16:23:05 -07:00
19f2107d95 v0.2.28 (#65)
* bumped version.

* fixed comments cubit and story tile.

* cancel subscription on error.
2022-07-02 01:14:40 -07:00
c9b2d82dfc v0.2.27 (#64)
* bumped version.

* fixed comment cubit.

* fixed share button.

* fixed share dialog.

* added lazy loading.

* bumped version.

* fixed lazy loading.

* bumped version.

* updated screenshots.

* added customization of fetch mode and comments order.

* updated screenshots.

* added haptic feedback.
2022-06-30 18:32:11 -07:00
56e442b09f v0.2.26 (#63)
* added integration test.

* replace listview with listview.builder

* added cache.

* bumped version.

* bumped version.

* updated github action.

* bumped version.

* fixed time machine cubit.

* fixed time machine cubit.

* reverted changes.

* removed keepAliveMixin
2022-06-28 17:32:50 -07:00
9069efcced improved logging. 2022-06-28 12:08:02 -07:00
bf6a5667dc fixed naming. 2022-06-28 12:01:36 -07:00
cff73a010b v0.2.25 (#62)
* bumped version.

* improved cache.

* improved comment cache.

* updated default val for navigationMode.
2022-06-28 00:08:07 -07:00
f0d6cac3fd v0.2.24 (#61)
* bumped version.

* improved collapse.

* improved download speed.

* improved err handling.

* improved error handling.

* improved error handling.

* improved logging.

* improved logging.

* bumped version.
2022-06-27 00:47:22 -07:00
a90d52f348 v0.2.23 (#60)
* fixed #58

* bumped version.
2022-06-23 19:38:14 -07:00
cff4a3c5c4 v0.2.22 (#59)
* bumped version.

* cleaned up code.

* bumped version.

* fixed lint.

* updated android config.

* prevent backup of secure storage.

* small fix.

* cleaned up code.

* cleaned up.

* small fix
2022-06-22 23:44:49 -07:00
502faaf188 corrected spelling. 2022-06-22 10:28:27 -07:00
b952f349fc v0.2.21 (#57)
* replaced StoryScreen with ItemScreen.

* use ItemScreen for share extension.

* fixed getItemId()

* bumped version.

* force new screen on viewing comments in separate thread.

* disable comment thread if comment is deleted or dead.

* navigate to new screen on viewing parent thread.

* bumped version.

* fixed inconsistent fontsize.

* bumped version.
2022-06-21 20:20:09 -07:00
9cefffa518 v0.2.20 (#56)
* bumped version.

* fixed web analyzer.

* improved comments loading mechanism.

* fixed delete all button.

* improved reply box logic.

* improved web analyzer.

* allow users to sort comments.

* fixed styles.

* fixed bugs.

* bumped version.

* fixed comments cubit.

* fixed dead comments.
2022-06-21 02:38:24 -07:00
fe630ea7a9 v0.2.20 (#55)
* bumped version.

* fixed web analyzer.

* improved comments loading mechanism.

* fixed delete all button.

* improved reply box logic.

* improved web analyzer.

* allow users to sort comments.

* fixed styles.

* fixed bugs.

* bumped version.

* fixed comments cubit.
2022-06-21 02:15:42 -07:00
459ab961d1 v0.2.19 hotfix (#52)
* improved offline mode.

* bumped version.

* reset stories count on download event.

* fixed overflow.
2022-06-18 23:40:56 -07:00
362d7005df fixed jank while exiting story screen. 2022-06-18 11:44:34 -07:00
6b7c1d42de fixed offline mode. 2022-06-18 02:38:31 -07:00
2a889bca56 v0.2.19 (#51)
* improved comments loading.

* added web page caching to offline mode.

* improved offline webview.

* fixed web analyzer.

* updated description.
2022-06-18 02:18:03 -07:00
e25026f129 created FUNDING.yml 2022-06-17 21:25:24 -07:00
fefc86275d v0.2.18 (#49)
* allow plaintext http connections (#48)

via https://stackoverflow.com/a/56837613

I was unable to open an article just now, and a fww minutes later unable to open a comment (since the webview is still being forced on my not-yet-updated client, i have to find the artocle to open it.

* bumped version.

* improved link preview.

* added share button.

* added ability to launch third party app for url on Android.

* added support for siri suggestions.

* bumped version.

* added support for app links on Android.

Co-authored-by: Efreak <Efreak@users.noreply.github.com>
2022-06-15 23:56:45 -07:00
1a73a6991e updated screenshots. 2022-06-10 02:28:31 -07:00
36d7f4606e updated screenshots. 2022-06-10 02:27:22 -07:00
9312c56dd0 v0.2.17 (#47)
* improved story screen scrolling.

* bumped version.

* shrink instead of return on tapping back button. #42

* allowed users to view other user's profile. #45

* bumped version.

* added back underline to links.

* fixed overlow of popup menu,
2022-06-10 02:10:23 -07:00
6e71de5913 updated README.md 2022-06-05 22:39:54 -07:00
a9590af3e9 v0.2.16 (#41)
* bumped version.

* add badges for fdroid, GitHub release versions (#40)

* updated README.md

* replaced jobs with best.

* updated README.md

Co-authored-by: Efreak <Efreak@users.noreply.github.com>
2022-06-05 22:34:48 -07:00
18dadaa5ec v0.2.15 (#39)
* Add capitlzation to text fields (#37)

* added ability for split view to be expanded to full screen. (#38)

Co-authored-by: Efreak <Efreak@users.noreply.github.com>
2022-06-05 00:58:49 -07:00
d506297f4c v0.2.14 (#35)
* added custom search feature.

* removed equatable.

* added custom range.

* updated README.md
2022-06-04 02:11:26 -07:00
4e8cf9837f v0.2.13 (#34)
* fixed #32 and #33

* fall back to default browser #31

* fixed story tile.

* fixed version.

* use Listview.builder instead of listview.

* updated link utls.
2022-06-03 00:26:30 -07:00
f73269404a updated README.md 2022-06-01 09:13:35 -07:00
c4c109e4a3 v0.2.12 (#30)
* added metadata to story tile.

* bumped version

* fixed metadata tile

* bumped version.

* fixed pinned stories not being refreshed.
2022-06-01 01:34:21 -07:00
b7720d0584 v0.2.12 (#29)
* added metadata to story tile.

* bumped version

* fixed metadata tile

* bumped version.
2022-06-01 01:13:21 -07:00
7d5788dec3 updated README.md 2022-05-28 00:03:46 -07:00
80a836c6b9 updated README.md 2022-05-28 00:02:03 -07:00
913be9fc5d v0.2.11 (#27)
* fixed pinned story tile.

* bumped version.
2022-05-27 16:18:36 -07:00
194 changed files with 6231 additions and 3030 deletions

13
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,13 @@
# These are supported funding model platforms
github: livinglist
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: jfeng_for_open_source
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

22
.github/workflows/commit_check.yml vendored Normal file
View File

@ -0,0 +1,22 @@
name: Commit Guard
on:
push:
branches:
- "**"
jobs:
releases:
name: Check commit
runs-on: ubuntu-latest
env:
FLUTTER_VERSION: "3.3.4"
steps:
- uses: actions/checkout@v2
- uses: subosito/flutter-action@v2
with:
flutter-version: '3.3.4'
channel: 'stable'
- run: flutter pub get
- run: flutter format --set-exit-if-changed .
- run: flutter analyze

View File

@ -1,32 +0,0 @@
name: Releases
on:
push:
# tags:
# - '*'
jobs:
releases:
name: release apk
runs-on: ubuntu-latest
env:
JAVA_VERSION: "11.0"
FLUTTER_VERSION: "3.0.0"
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v2
with:
distribution: 'temurin' # See 'Supported distributions' for available options
java-version: '17'
- uses: subosito/flutter-action@v2
with:
flutter-version: '3.0.0'
channel: 'stable'
- run: flutter pub get
- run: flutter analyze
# - run: flutter test
# - run: flutter build apk --release
# - uses: ncipollo/release-action@v1
# with:
# artifacts: "build/app/outputs/flutter-apk/*.apk"
# token: ${{ secrets.GITHUB_TOKEN }}

54
.github/workflows/publish_ios.yml vendored Normal file
View File

@ -0,0 +1,54 @@
name: Publish (iOS)
on:
# Allow manual builds of this workflow
workflow_dispatch: {}
# Run the workflow whenever a new tag named 'v*' is pushed
push:
branches:
- "!*"
tags:
- "v*"
jobs:
build_and_publish:
runs-on: macos-latest
env:
# Point the `ruby/setup-ruby` action at this Gemfile, so it
# caches dependencies for us.
BUNDLE_GEMFILE: ${{ github.workspace }}/ios/Gemfile
steps:
- name: Check out from git
uses: actions/checkout@v2
# Configure ruby according to our .ruby-version
- name: Setup ruby & Bundler
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
# Set up flutter (feel free to adjust the version below)
- name: Setup flutter
uses: subosito/flutter-action@v2
with:
cache: true
flutter-version: 3.3.4
- run: flutter pub get
- run: flutter format --set-exit-if-changed .
- run: flutter analyze
# Start an ssh-agent that will provide the SSH key from the
# SSH_PRIVATE_KEY secret to `fastlane match`
- name: Setup SSH key
env:
SSH_AUTH_SOCK: /tmp/ssh_agent.sock
run: |
ssh-agent -a $SSH_AUTH_SOCK > /dev/null
ssh-add - <<< "${{ secrets.SSH_PRIVATE_KEY }}"
- name: Download dependencies
run: flutter pub get
- name: Build & Publish to TestFlight with Fastlane
env:
APP_STORE_CONNECT_API_KEY_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY_KEY }}
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
SSH_AUTH_SOCK: /tmp/ssh_agent.sock
run: cd ios && bundle exec fastlane beta "build_name:${{ github.ref_name }}"

1
.ruby-version Normal file
View File

@ -0,0 +1 @@
2.7.5

View File

@ -1,17 +1,15 @@
# <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 simple noiseless [Hacker News](https://news.ycombinator.com/) client made with Flutter that is just enough. A [Hacker News](https://news.ycombinator.com/) client made with Flutter that is just enough.
[![App Store](https://img.shields.io/itunes/v/1602043763?label=App%20Store)](https://apps.apple.com/us/app/hacki/id1602043763) [![App Store](https://img.shields.io/itunes/v/1602043763?label=App%20Store)](https://apps.apple.com/us/app/hacki/id1602043763?platform=iphone)
[![Play Store](https://img.shields.io/badge/Play%20Store--yellow)](https://play.google.com/store/apps/details?id=com.jiaqifeng.hacki&hl=en_US&gl=US) [![Fdroid version](https://img.shields.io/f-droid/v/com.jiaqifeng.hacki)](https://f-droid.org/en/packages/com.jiaqifeng.hacki/)
[![Visits Badge](https://badges.pufler.dev/visits/livinglist/Hacki)](https://badges.pufler.dev) [![GH version](https://img.shields.io/github/release/livinglist/hacki.svg?logo=github)](https://github.com/Livinglist/Hacki/releases/latest)
[![GitHub](https://img.shields.io/github/stars/livinglist/Hacki?style=social)](https://img.shields.io/github/stars/livinglist/Hacki?style=social)
[![style: effective dart](https://img.shields.io/badge/style-effective_dart-40c4ff.svg)](https://pub.dev/packages/effective_dart) [![style: effective dart](https://img.shields.io/badge/style-effective_dart-40c4ff.svg)](https://pub.dev/packages/effective_dart)
[![GitHub](https://img.shields.io/github/stars/livinglist/Hacki?style=social)](https://img.shields.io/github/stars/livinglist/Hacki?style=social)
<noscript><a href="https://liberapay.com/jfeng_for_open_source/donate"><img alt="Donate using Liberapay" src="https://liberapay.com/assets/widgets/donate.svg"></a></noscript> [<img src="assets/images/app_store_badge.png" height="50">](https://apps.apple.com/us/app/hacki/id1602043763?platform=iphone) [<img src="assets/images/google_play_badge.png" height="50">](https://play.google.com/store/apps/details?id=com.jiaqifeng.hacki&hl=en_US&gl=US) [<img src="assets/images/f_droid_badge.png" height="50">](https://f-droid.org/en/packages/com.jiaqifeng.hacki/)
[<img src="assets/images/app_store_badge.png" height="50">](https://apps.apple.com/us/app/hacki/id1602043763) [<img src="assets/images/google_play_badge.png" height="50">](https://play.google.com/store/apps/details?id=com.jiaqifeng.hacki&hl=en_US&gl=US) [<img src="assets/images/f_droid_badge.png" height="50">](https://f-droid.org/en/packages/com.jiaqifeng.hacki/)
Features: Features:
@ -36,24 +34,22 @@ Features:
<p align="center"> <p align="center">
<img width="200" alt="Screen Shot 2020-03-03 at 1 22 57 PM" src="https://user-images.githubusercontent.com/7277662/159799288-6e98352a-fe89-4a2e-8a74-c5782463a1e1.png"> <img width="200" alt="01" src="assets/screenshots/01.png">
<img width="200" alt="Screen Shot 2020-03-03 at 1 22 57 PM" src="https://user-images.githubusercontent.com/7277662/159799297-75b52eac-2066-4df9-bdfc-7c82bf7b81c8.png"> <img width="200" alt="02" src="assets/screenshots/02.png">
<img width="200" alt="Screen Shot 2020-03-03 at 1 22 57 PM" src="https://user-images.githubusercontent.com/7277662/159799302-860c61b8-abba-486a-9592-bc84a6af3232.png"> <img width="200" alt="03" src="assets/screenshots/03.png">
<img width="200" alt="Screen Shot 2020-03-03 at 1 22 57 PM" src="https://user-images.githubusercontent.com/7277662/159799305-308743d3-1c89-45de-9645-3b6ec789c282.png"> <img width="200" alt="04" src="assets/screenshots/04.png">
<img width="200" alt="Screen Shot 2020-03-03 at 1 22 57 PM" src="https://user-images.githubusercontent.com/7277662/159798176-5212e9bf-296d-4d9b-ab48-19b741684c8a.png"> <img width="200" alt="05" src="assets/screenshots/05.png">
<img width="200" alt="Screen Shot 2020-03-03 at 1 22 57 PM" src="https://user-images.githubusercontent.com/7277662/159798179-72edbe49-7444-4e54-a07c-fc1244447a74.png"> <img width="200" alt="06" src="assets/screenshots/06.png">
<img width="200" alt="Screen Shot 2020-03-03 at 1 22 57 PM" src="https://user-images.githubusercontent.com/7277662/159798182-28397805-a7cc-4124-b65b-c02c80afbbec.png"> <img width="200" alt="07" src="assets/screenshots/07.png">
<img width="200" alt="Screen Shot 2020-03-03 at 1 22 57 PM" src="https://user-images.githubusercontent.com/7277662/159798183-c2984270-ee99-4419-841e-65e98890464f.png"> <img width="200" alt="08" src="assets/screenshots/08.png">
<img width="200" alt="Screen Shot 2020-03-03 at 1 22 57 PM" src="https://user-images.githubusercontent.com/7277662/159798184-2fce5d97-710e-44a7-b99a-3296ebcf273b.png"> <img width="200" alt="09" src="assets/screenshots/09.png">
<img width="200" alt="Screen Shot 2020-03-03 at 1 22 57 PM" src="https://user-images.githubusercontent.com/7277662/159798185-d7c81348-956e-483c-a1bc-5cd872bdad62.png"> <img width="200" alt="10" src="assets/screenshots/10.png">
<img width="200" alt="Screen Shot 2020-03-03 at 1 22 57 PM" src="https://user-images.githubusercontent.com/7277662/159798186-1457ae21-f1aa-40a4-9206-0f3a1e24653e.png"> <img width="200" alt="11" src="assets/screenshots/11.png">
<img width="200" alt="Screen Shot 2020-03-03 at 1 22 57 PM" src="https://user-images.githubusercontent.com/7277662/159798187-4404adea-b2bc-472e-8568-2379e6db01a4.png"> <img width="200" alt="12" src="assets/screenshots/12.png">
<img width="400" alt="Screen Shot 2020-03-03 at 1 22 57 PM" src="https://user-images.githubusercontent.com/7277662/160162711-a9146326-9645-4db6-a04e-1f82e6133e40.png"> <img width="400" alt="ipad-01" src="assets/screenshots/ipad-01.png">
<img width="400" alt="Screen Shot 2020-03-03 at 1 22 57 PM" src="https://user-images.githubusercontent.com/7277662/160162726-ef1d3f2a-5179-417c-8a5f-0cddb52249da.png"> <img width="400" alt="ipad-02" src="assets/screenshots/ipad-02.png">
<img width="400" alt="Screen Shot 2020-03-03 at 1 22 57 PM" src="https://user-images.githubusercontent.com/7277662/160162733-906c4afd-39a8-48ae-946a-8019b327eaa0.png"> <img width="400" alt="ipad-03" src="assets/screenshots/ipad-03.png">
<img width="400" alt="Screen Shot 2020-03-03 at 1 22 57 PM" src="https://user-images.githubusercontent.com/7277662/160162735-f2b25119-4702-4308-b2f5-281a2a2c5901.png"> <img width="400" alt="ipad-04" src="assets/screenshots/ipad-04.png">
<img width="400" alt="Screen Shot 2020-03-03 at 1 22 57 PM" src="https://user-images.githubusercontent.com/7277662/160163024-6dcd65b6-bada-4c1c-95af-387fd4f42fb2.png">
<img width="400" alt="Screen Shot 2020-03-03 at 1 22 57 PM" src="https://user-images.githubusercontent.com/7277662/160163033-7bcf7038-b9aa-4ce4-8b58-64578eae8531.png">
</p> </p>

View File

@ -5,4 +5,5 @@ linter:
public_member_api_docs: false public_member_api_docs: false
library_private_types_in_public_api: false library_private_types_in_public_api: false
omit_local_variable_types: false omit_local_variable_types: false
one_member_abstracts: false
always_specify_types: true always_specify_types: true

View File

@ -33,7 +33,7 @@ if (keystorePropertiesFile.exists()) {
android { android {
compileSdkVersion 31 compileSdkVersion 33
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8
@ -49,10 +49,9 @@ android {
} }
defaultConfig { defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.jiaqifeng.hacki" applicationId "com.jiaqifeng.hacki"
minSdkVersion 26 minSdkVersion 26
targetSdkVersion 30 targetSdkVersion 33
versionCode flutterVersionCode.toInteger() versionCode flutterVersionCode.toInteger()
versionName flutterVersionName versionName flutterVersionName
} }
@ -78,5 +77,5 @@ flutter {
} }
dependencies { dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
} }

View File

@ -9,17 +9,25 @@
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
<data android:scheme="https" /> <data android:scheme="https" />
</intent> </intent>
<intent>
<action android:name="android.intent.action.SEND" />
<data android:mimeType="*/*" />
</intent>
</queries> </queries>
<application <application
android:label="hacki" android:label="Hacki"
android:icon="@mipmap/ic_launcher"> android:icon="@mipmap/ic_launcher"
android:allowBackup="true"
android:fullBackupContent="@xml/backup_rules"
android:usesCleartextTraffic="true">
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:launchMode="singleTop" android:launchMode="singleTop"
android:theme="@style/LaunchTheme" android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:exported="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as <!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user the Android process has started. This theme is visible to the user
@ -48,6 +56,21 @@
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" /> <data android:mimeType="*/*" />
</intent-filter> </intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="http"
android:host="news.ycombinator.com"
android:pathPrefix="/item" />
<data
android:scheme="https"
android:host="news.ycombinator.com"
android:pathPrefix="/item" />
</intent-filter>
</activity> </activity>
<!-- Don't delete the meta-data below. <!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<full-backup-content>
<exclude domain="sharedpref" path="FlutterSecureStorage"/>
</full-backup-content>

View File

@ -1,12 +1,12 @@
buildscript { buildscript {
ext.kotlin_version = '1.6.10' ext.kotlin_version = '1.7.0'
repositories { repositories {
google() google()
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:7.1.1' classpath 'com.android.tools.build:gradle:7.1.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
} }
} }

BIN
assets/screenshots/01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 522 KiB

BIN
assets/screenshots/02.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 835 KiB

BIN
assets/screenshots/03.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 KiB

BIN
assets/screenshots/04.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 KiB

BIN
assets/screenshots/05.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 820 KiB

BIN
assets/screenshots/06.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 868 KiB

BIN
assets/screenshots/07.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

BIN
assets/screenshots/08.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 KiB

BIN
assets/screenshots/09.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 KiB

BIN
assets/screenshots/10.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 KiB

BIN
assets/screenshots/11.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 530 KiB

BIN
assets/screenshots/12.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 763 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1005 KiB

View File

@ -1 +0,0 @@
- Bugfixes.

View File

@ -1 +0,0 @@
- Updates to UI.

View File

@ -1 +0,0 @@
- Updates to UI.

View File

@ -1 +0,0 @@
- Updates to UI.

View File

@ -1 +0,0 @@
- Tapping on comments in notification and history screen will lead you directly to the comment.

View File

@ -1,3 +0,0 @@
- Tapping on comment in notification or history screen will now lead you directly to the comment.
- Fixed the bug where reply box cannot be expanded in editing mode.
- Fixed inconsistent font size in history screen.

View File

@ -1 +0,0 @@
- Added offline mode.

View File

@ -1,2 +0,0 @@
- Added offline mode.
- Bugfixes.

View File

@ -1,2 +0,0 @@
- Added offline mode.
- Bugfixes.

View File

@ -1,2 +0,0 @@
- Added offline mode.
- Bugfixes.

View File

@ -1,3 +0,0 @@
- Pick up where you left off.
- Swipe left on comment tile to view its parents without scrolling all the way up.
- Huge performance boost.

View File

@ -1,3 +0,0 @@
- Pick up where you left off.
- Swipe left on comment tile to view its parents without scrolling all the way up.
- Huge performance boost.

View File

@ -1,3 +0,0 @@
- Pick up where you left off.
- Swipe left on comment tile to view its parents without scrolling all the way up.
- Huge performance boost.

View File

@ -1,4 +0,0 @@
- You can now participate in polls.
- Pick up where you left off.
- Swipe left on comment tile to view its parents without scrolling all the way up.
- Huge performance boost.

View File

@ -1,4 +0,0 @@
- You can now participate in polls.
- Pick up where you left off.
- Swipe left on comment tile to view its parents without scrolling all the way up.
- Huge performance boost.

View File

@ -1,4 +0,0 @@
- You can now participate in polls.
- Pick up where you left off.
- Swipe left on comment tile to view its parents without scrolling all the way up.
- Huge performance boost.

View File

@ -1,4 +0,0 @@
- You can now participate in polls.
- Pick up where you left off.
- Swipe left on comment tile to view its parents without scrolling all the way up.
- Huge performance boost.

View File

@ -1,4 +0,0 @@
- You can now participate in polls.
- Pick up where you left off.
- Swipe left on comment tile to view its parents without scrolling all the way up.
- Huge performance boost.

View File

@ -1,4 +0,0 @@
- You can now participate in polls.
- Pick up where you left off.
- Swipe left on comment tile to view its parents without scrolling all the way up.
- Huge performance boost.

View File

@ -1,4 +0,0 @@
- You can now participate in polls.
- Pick up where you left off.
- Swipe left on comment tile to view its parents without scrolling all the way up.
- Huge performance boost.

View File

@ -1,4 +0,0 @@
- You can now participate in polls.
- Pick up where you left off.
- Swipe left on comment tile to view its parents without scrolling all the way up.
- Huge performance boost.

View File

@ -1,4 +0,0 @@
- You can now participate in polls.
- Pick up where you left off.
- Swipe left on comment tile to view its parents without scrolling all the way up.
- Huge performance boost.

View File

@ -1,4 +0,0 @@
- You can now participate in polls.
- Pick up where you left off.
- Swipe left on comment tile to view its parents without scrolling all the way up.
- Huge performance boost.

View File

@ -1,4 +0,0 @@
- You can now participate in polls.
- Pick up where you left off.
- Swipe left on comment tile to view its parents without scrolling all the way up.
- Huge performance boost.

View File

@ -1,4 +0,0 @@
- You can now participate in polls.
- Pick up where you left off.
- Swipe left on comment tile to view its parents without scrolling all the way up.
- Huge performance boost.

View File

@ -0,0 +1 @@
- Offline mode now includes web pages.

View File

@ -0,0 +1 @@
- Offline mode now includes web pages.

View File

@ -0,0 +1 @@
- Offline mode now includes web pages.

View File

@ -0,0 +1 @@
- Offline mode now includes web pages.

View File

@ -0,0 +1,2 @@
- Offline mode now includes web pages.
- You can now sort comments in story screen.

View File

@ -0,0 +1,2 @@
- Offline mode now includes web pages.
- You can now sort comments in story screen.

View File

@ -0,0 +1,2 @@
- Offline mode now includes web pages.
- You can now sort comments in story screen.

View File

@ -0,0 +1,2 @@
- Offline mode now includes web pages.
- You can now sort comments in story screen.

View File

@ -0,0 +1,2 @@
- Offline mode now includes web pages.
- You can now sort comments in story screen.

View File

@ -0,0 +1,2 @@
- Offline mode now includes web pages.
- You can now sort comments in story screen.

View File

@ -0,0 +1,2 @@
- Offline mode now includes web pages.
- You can now sort comments in story screen.

View File

@ -0,0 +1,3 @@
- Lazy loading.
- Offline mode now includes web pages.
- You can now sort comments in story screen.

View File

@ -0,0 +1,3 @@
- Lazy loading.
- Offline mode now includes web pages.
- You can now sort comments in story screen.

View File

@ -0,0 +1,3 @@
- Lazy loading.
- Offline mode now includes web pages.
- You can now sort comments in story screen.

View File

@ -0,0 +1,3 @@
- Lazy loading.
- Offline mode now includes web pages.
- You can now sort comments in story screen.

View File

@ -0,0 +1,3 @@
- Lazy loading.
- Offline mode now includes web pages.
- You can now sort comments in story screen.

View File

@ -0,0 +1,2 @@
- Bumped Flutter version.
- Updated navigation bar background color.

View File

@ -0,0 +1,2 @@
- Bumped Flutter version.
- Updated navigation bar background color.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 393 KiB

After

Width:  |  Height:  |  Size: 522 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 696 KiB

After

Width:  |  Height:  |  Size: 835 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 250 KiB

After

Width:  |  Height:  |  Size: 282 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 231 KiB

After

Width:  |  Height:  |  Size: 298 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 903 KiB

After

Width:  |  Height:  |  Size: 820 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 931 KiB

After

Width:  |  Height:  |  Size: 868 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 298 KiB

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 247 KiB

After

Width:  |  Height:  |  Size: 375 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 496 KiB

After

Width:  |  Height:  |  Size: 282 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 420 KiB

After

Width:  |  Height:  |  Size: 414 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 530 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 KiB

View File

@ -0,0 +1,68 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:hacki/main.dart' as app;
import 'package:hacki/screens/widgets/widgets.dart';
import 'package:integration_test/integration_test.dart';
void main() {
final IntegrationTestWidgetsFlutterBinding binding =
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
testWidgets('Scrolling test', (WidgetTester tester) async {
await app.main(testing: true);
await tester.pumpAndSettle();
final Finder bestTabFinder = find.widgetWithText(Tab, 'BEST');
expect(bestTabFinder, findsOneWidget);
Future<void> scrollDown(WidgetTester tester) async {
await tester.timedDragFrom(
const Offset(100, 200),
const Offset(100, -700),
const Duration(seconds: 2),
);
await tester.pump();
}
Future<void> scrollUp(WidgetTester tester) async {
await tester.timedDragFrom(
const Offset(100, 200),
const Offset(100, 700),
const Duration(seconds: 1),
);
await tester.pump();
}
await binding.traceAction(
() async {
await tester.tap(bestTabFinder);
await tester.pump();
const int count = 10;
for (int i = 0; i < count; i++) {
await scrollDown(tester);
}
for (int i = 0; i < count - 3; i++) {
await scrollUp(tester);
}
await tester.pumpAndSettle(const Duration(seconds: 2));
final Finder storyFinder = find.byType(StoryTile);
expect(storyFinder, findsWidgets);
final Finder firstStoryFinder = storyFinder.first;
expect(firstStoryFinder, findsOneWidget);
await tester.tap(firstStoryFinder);
await tester.pump(const Duration(seconds: 4));
},
reportKey: 'scrolling_timeline',
);
});
}

View File

@ -21,6 +21,6 @@
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.0</string> <string>1.0</string>
<key>MinimumOSVersion</key> <key>MinimumOSVersion</key>
<string>9.0</string> <string>11.0</string>
</dict> </dict>
</plist> </plist>

4
ios/Gemfile Normal file
View File

@ -0,0 +1,4 @@
source "https://rubygems.org"
gem "fastlane"
gem "cocoapods"

285
ios/Gemfile.lock Normal file
View File

@ -0,0 +1,285 @@
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.5)
rexml
activesupport (6.1.7)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
zeitwerk (~> 2.3)
addressable (2.8.1)
public_suffix (>= 2.0.2, < 6.0)
algoliasearch (1.27.5)
httpclient (~> 2.8, >= 2.8.3)
json (>= 1.5.1)
artifactory (3.0.15)
atomos (0.1.3)
aws-eventstream (1.2.0)
aws-partitions (1.636.0)
aws-sdk-core (3.154.0)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.525.0)
aws-sigv4 (~> 1.1)
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.58.0)
aws-sdk-core (~> 3, >= 3.127.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.114.0)
aws-sdk-core (~> 3, >= 3.127.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.4)
aws-sigv4 (1.5.1)
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4)
claide (1.1.0)
cocoapods (1.11.3)
addressable (~> 2.8)
claide (>= 1.0.2, < 2.0)
cocoapods-core (= 1.11.3)
cocoapods-deintegrate (>= 1.0.3, < 2.0)
cocoapods-downloader (>= 1.4.0, < 2.0)
cocoapods-plugins (>= 1.0.0, < 2.0)
cocoapods-search (>= 1.0.0, < 2.0)
cocoapods-trunk (>= 1.4.0, < 2.0)
cocoapods-try (>= 1.1.0, < 2.0)
colored2 (~> 3.1)
escape (~> 0.0.4)
fourflusher (>= 2.3.0, < 3.0)
gh_inspector (~> 1.0)
molinillo (~> 0.8.0)
nap (~> 1.0)
ruby-macho (>= 1.0, < 3.0)
xcodeproj (>= 1.21.0, < 2.0)
cocoapods-core (1.11.3)
activesupport (>= 5.0, < 7)
addressable (~> 2.8)
algoliasearch (~> 1.0)
concurrent-ruby (~> 1.1)
fuzzy_match (~> 2.0.4)
nap (~> 1.0)
netrc (~> 0.11)
public_suffix (~> 4.0)
typhoeus (~> 1.0)
cocoapods-deintegrate (1.0.5)
cocoapods-downloader (1.6.3)
cocoapods-plugins (1.0.0)
nap
cocoapods-search (1.0.1)
cocoapods-trunk (1.6.0)
nap (>= 0.8, < 2.0)
netrc (~> 0.11)
cocoapods-try (1.2.0)
colored (1.2)
colored2 (3.1.2)
commander (4.6.0)
highline (~> 2.0.0)
concurrent-ruby (1.1.10)
declarative (0.0.20)
digest-crc (0.6.4)
rake (>= 12.0.0, < 14.0.0)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
dotenv (2.8.1)
emoji_regex (3.2.3)
escape (0.0.4)
ethon (0.15.0)
ffi (>= 1.15.0)
excon (0.92.5)
faraday (1.10.2)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1)
faraday-httpclient (~> 1.0)
faraday-multipart (~> 1.0)
faraday-net_http (~> 1.0)
faraday-net_http_persistent (~> 1.0)
faraday-patron (~> 1.0)
faraday-rack (~> 1.0)
faraday-retry (~> 1.0)
ruby2_keywords (>= 0.0.4)
faraday-cookie_jar (0.0.7)
faraday (>= 0.8.0)
http-cookie (~> 1.0.0)
faraday-em_http (1.0.0)
faraday-em_synchrony (1.0.0)
faraday-excon (1.1.0)
faraday-httpclient (1.0.1)
faraday-multipart (1.0.4)
multipart-post (~> 2)
faraday-net_http (1.0.1)
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
faraday-rack (1.0.0)
faraday-retry (1.0.3)
faraday_middleware (1.2.0)
faraday (~> 1.0)
fastimage (2.2.6)
fastlane (2.210.1)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.8, < 3.0.0)
artifactory (~> 3.0)
aws-sdk-s3 (~> 1.0)
babosa (>= 1.0.3, < 2.0.0)
bundler (>= 1.12.0, < 3.0.0)
colored
commander (~> 4.6)
dotenv (>= 2.1.1, < 3.0.0)
emoji_regex (>= 0.1, < 4.0)
excon (>= 0.71.0, < 1.0.0)
faraday (~> 1.0)
faraday-cookie_jar (~> 0.0.6)
faraday_middleware (~> 1.0)
fastimage (>= 2.1.0, < 3.0.0)
gh_inspector (>= 1.1.2, < 2.0.0)
google-apis-androidpublisher_v3 (~> 0.3)
google-apis-playcustomapp_v1 (~> 0.1)
google-cloud-storage (~> 1.31)
highline (~> 2.0)
json (< 3.0.0)
jwt (>= 2.1.0, < 3)
mini_magick (>= 4.9.4, < 5.0.0)
multipart-post (~> 2.0.0)
naturally (~> 2.2)
optparse (~> 0.1.1)
plist (>= 3.1.0, < 4.0.0)
rubyzip (>= 2.0.0, < 3.0.0)
security (= 0.1.3)
simctl (~> 1.6.3)
terminal-notifier (>= 2.0.0, < 3.0.0)
terminal-table (>= 1.4.5, < 2.0.0)
tty-screen (>= 0.6.3, < 1.0.0)
tty-spinner (>= 0.8.0, < 1.0.0)
word_wrap (~> 1.0.0)
xcodeproj (>= 1.13.0, < 2.0.0)
xcpretty (~> 0.3.0)
xcpretty-travis-formatter (>= 0.0.3)
ffi (1.15.5)
fourflusher (2.3.1)
fuzzy_match (2.0.4)
gh_inspector (1.1.3)
google-apis-androidpublisher_v3 (0.27.0)
google-apis-core (>= 0.7.2, < 2.a)
google-apis-core (0.9.0)
addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.16.2, < 2.a)
httpclient (>= 2.8.1, < 3.a)
mini_mime (~> 1.0)
representable (~> 3.0)
retriable (>= 2.0, < 4.a)
rexml
webrick
google-apis-iamcredentials_v1 (0.14.0)
google-apis-core (>= 0.7.2, < 2.a)
google-apis-playcustomapp_v1 (0.10.0)
google-apis-core (>= 0.7, < 2.a)
google-apis-storage_v1 (0.17.0)
google-apis-core (>= 0.7, < 2.a)
google-cloud-core (1.6.0)
google-cloud-env (~> 1.0)
google-cloud-errors (~> 1.0)
google-cloud-env (1.6.0)
faraday (>= 0.17.3, < 3.0)
google-cloud-errors (1.3.0)
google-cloud-storage (1.42.0)
addressable (~> 2.8)
digest-crc (~> 0.4)
google-apis-iamcredentials_v1 (~> 0.1)
google-apis-storage_v1 (~> 0.17.0)
google-cloud-core (~> 1.6)
googleauth (>= 0.16.2, < 2.a)
mini_mime (~> 1.0)
googleauth (1.2.0)
faraday (>= 0.17.3, < 3.a)
jwt (>= 1.4, < 3.0)
memoist (~> 0.16)
multi_json (~> 1.11)
os (>= 0.9, < 2.0)
signet (>= 0.16, < 2.a)
highline (2.0.3)
http-cookie (1.0.5)
domain_name (~> 0.5)
httpclient (2.8.3)
i18n (1.12.0)
concurrent-ruby (~> 1.0)
jmespath (1.6.1)
json (2.6.2)
jwt (2.5.0)
memoist (0.16.2)
mini_magick (4.11.0)
mini_mime (1.1.2)
minitest (5.16.3)
molinillo (0.8.0)
multi_json (1.15.0)
multipart-post (2.0.0)
nanaimo (0.3.0)
nap (1.1.0)
naturally (2.2.1)
netrc (0.11.0)
optparse (0.1.1)
os (1.1.4)
plist (3.6.0)
public_suffix (4.0.7)
rake (13.0.6)
representable (3.2.0)
declarative (< 0.1.0)
trailblazer-option (>= 0.1.1, < 0.2.0)
uber (< 0.2.0)
retriable (3.1.2)
rexml (3.2.5)
rouge (2.0.7)
ruby-macho (2.5.1)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
security (0.1.3)
signet (0.17.0)
addressable (~> 2.8)
faraday (>= 0.17.5, < 3.a)
jwt (>= 1.5, < 3.0)
multi_json (~> 1.10)
simctl (1.6.8)
CFPropertyList
naturally
terminal-notifier (2.0.0)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
trailblazer-option (0.1.2)
tty-cursor (0.7.1)
tty-screen (0.8.1)
tty-spinner (0.9.3)
tty-cursor (~> 0.7)
typhoeus (1.4.0)
ethon (>= 0.9.0)
tzinfo (2.0.5)
concurrent-ruby (~> 1.0)
uber (0.1.0)
unf (0.1.4)
unf_ext
unf_ext (0.0.8.2)
unicode-display_width (1.8.0)
webrick (1.7.0)
word_wrap (1.0.0)
xcodeproj (1.22.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.3.0)
rexml (~> 3.2.4)
xcpretty (0.3.0)
rouge (~> 2.0.7)
xcpretty-travis-formatter (1.0.1)
xcpretty (~> 0.2, >= 0.0.7)
zeitwerk (2.6.0)
PLATFORMS
universal-darwin-21
x86_64-darwin-19
DEPENDENCIES
cocoapods
fastlane
BUNDLED WITH
2.3.22

View File

@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project # Uncomment this line to define a global platform for your project
platform :ios, '13.0' # platform :ios, '11.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency. # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true' ENV['COCOAPODS_DISABLE_STATS'] = 'true'
@ -37,8 +37,5 @@ end
post_install do |installer| post_install do |installer|
installer.pods_project.targets.each do |target| installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target) flutter_additional_ios_build_settings(target)
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0'
end
end end
end end

View File

@ -14,15 +14,21 @@ PODS:
- Flutter - Flutter
- flutter_secure_storage (3.3.1): - flutter_secure_storage (3.3.1):
- Flutter - Flutter
- flutter_siri_suggestions (0.0.1):
- Flutter
- FMDB (2.7.5): - FMDB (2.7.5):
- FMDB/standard (= 2.7.5) - FMDB/standard (= 2.7.5)
- FMDB/standard (2.7.5) - FMDB/standard (2.7.5)
- integration_test (0.0.1):
- Flutter
- OrderedSet (5.0.0) - OrderedSet (5.0.0)
- path_provider_ios (0.0.1): - path_provider_ios (0.0.1):
- Flutter - Flutter
- ReachabilitySwift (5.0.0) - ReachabilitySwift (5.0.0)
- receive_sharing_intent (0.0.1): - receive_sharing_intent (0.0.1):
- Flutter - Flutter
- share_plus (0.0.1):
- Flutter
- shared_preferences_ios (0.0.1): - shared_preferences_ios (0.0.1):
- Flutter - Flutter
- sqflite (0.0.2): - sqflite (0.0.2):
@ -32,8 +38,6 @@ PODS:
- Flutter - Flutter
- url_launcher_ios (0.0.1): - url_launcher_ios (0.0.1):
- Flutter - Flutter
- video_player_avfoundation (0.0.1):
- Flutter
- wakelock (0.0.1): - wakelock (0.0.1):
- Flutter - Flutter
- webview_flutter_wkwebview (0.0.1): - webview_flutter_wkwebview (0.0.1):
@ -47,13 +51,15 @@ DEPENDENCIES:
- flutter_inappwebview (from `.symlinks/plugins/flutter_inappwebview/ios`) - flutter_inappwebview (from `.symlinks/plugins/flutter_inappwebview/ios`)
- flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`) - flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`)
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`) - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
- flutter_siri_suggestions (from `.symlinks/plugins/flutter_siri_suggestions/ios`)
- integration_test (from `.symlinks/plugins/integration_test/ios`)
- path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`) - path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`)
- receive_sharing_intent (from `.symlinks/plugins/receive_sharing_intent/ios`) - receive_sharing_intent (from `.symlinks/plugins/receive_sharing_intent/ios`)
- share_plus (from `.symlinks/plugins/share_plus/ios`)
- shared_preferences_ios (from `.symlinks/plugins/shared_preferences_ios/ios`) - shared_preferences_ios (from `.symlinks/plugins/shared_preferences_ios/ios`)
- sqflite (from `.symlinks/plugins/sqflite/ios`) - sqflite (from `.symlinks/plugins/sqflite/ios`)
- synced_shared_preferences (from `.symlinks/plugins/synced_shared_preferences/ios`) - synced_shared_preferences (from `.symlinks/plugins/synced_shared_preferences/ios`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
- video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/ios`)
- wakelock (from `.symlinks/plugins/wakelock/ios`) - wakelock (from `.symlinks/plugins/wakelock/ios`)
- webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`) - webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`)
- workmanager (from `.symlinks/plugins/workmanager/ios`) - workmanager (from `.symlinks/plugins/workmanager/ios`)
@ -75,10 +81,16 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/flutter_local_notifications/ios" :path: ".symlinks/plugins/flutter_local_notifications/ios"
flutter_secure_storage: flutter_secure_storage:
:path: ".symlinks/plugins/flutter_secure_storage/ios" :path: ".symlinks/plugins/flutter_secure_storage/ios"
flutter_siri_suggestions:
:path: ".symlinks/plugins/flutter_siri_suggestions/ios"
integration_test:
:path: ".symlinks/plugins/integration_test/ios"
path_provider_ios: path_provider_ios:
:path: ".symlinks/plugins/path_provider_ios/ios" :path: ".symlinks/plugins/path_provider_ios/ios"
receive_sharing_intent: receive_sharing_intent:
:path: ".symlinks/plugins/receive_sharing_intent/ios" :path: ".symlinks/plugins/receive_sharing_intent/ios"
share_plus:
:path: ".symlinks/plugins/share_plus/ios"
shared_preferences_ios: shared_preferences_ios:
:path: ".symlinks/plugins/shared_preferences_ios/ios" :path: ".symlinks/plugins/shared_preferences_ios/ios"
sqflite: sqflite:
@ -87,8 +99,6 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/synced_shared_preferences/ios" :path: ".symlinks/plugins/synced_shared_preferences/ios"
url_launcher_ios: url_launcher_ios:
:path: ".symlinks/plugins/url_launcher_ios/ios" :path: ".symlinks/plugins/url_launcher_ios/ios"
video_player_avfoundation:
:path: ".symlinks/plugins/video_player_avfoundation/ios"
wakelock: wakelock:
:path: ".symlinks/plugins/wakelock/ios" :path: ".symlinks/plugins/wakelock/ios"
webview_flutter_wkwebview: webview_flutter_wkwebview:
@ -98,24 +108,26 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS: SPEC CHECKSUMS:
connectivity_plus: 413a8857dd5d9f1c399a39130850d02fe0feaf7e connectivity_plus: 413a8857dd5d9f1c399a39130850d02fe0feaf7e
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_inappwebview: bfd58618f49dc62f2676de690fc6dcda1d6c3721 flutter_inappwebview: bfd58618f49dc62f2676de690fc6dcda1d6c3721
flutter_local_notifications: 0c0b1ae97e741e1521e4c1629a459d04b9aec743 flutter_local_notifications: 0c0b1ae97e741e1521e4c1629a459d04b9aec743
flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec
flutter_siri_suggestions: 226fb7ef33d25d3fe0d4aa2a8bcf4b72730c466f
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
integration_test: a1e7d09bd98eca2fc37aefd79d4f41ad37bdbbe5
OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c
path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02 path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
receive_sharing_intent: c0d87310754e74c0f9542947e7cbdf3a0335a3b1 receive_sharing_intent: c0d87310754e74c0f9542947e7cbdf3a0335a3b1
share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68
shared_preferences_ios: 548a61f8053b9b8a49ac19c1ffbc8b92c50d68ad shared_preferences_ios: 548a61f8053b9b8a49ac19c1ffbc8b92c50d68ad
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
synced_shared_preferences: f722742b06d65c7315b8e9f56b794c9fbd5597f7 synced_shared_preferences: f722742b06d65c7315b8e9f56b794c9fbd5597f7
url_launcher_ios: 839c58cdb4279282219f5e248c3321761ff3c4de url_launcher_ios: 839c58cdb4279282219f5e248c3321761ff3c4de
video_player_avfoundation: e489aac24ef5cf7af82702979ed16f2a5ef84cff
wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f
webview_flutter_wkwebview: b7e70ef1ddded7e69c796c7390ee74180182971f webview_flutter_wkwebview: b7e70ef1ddded7e69c796c7390ee74180182971f
workmanager: 0afdcf5628bbde6924c21af7836fed07b42e30e6 workmanager: 0afdcf5628bbde6924c21af7836fed07b42e30e6
PODFILE CHECKSUM: e4c97c7a9aacaeda4b952f7ef9ea29e47660f622 PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3
COCOAPODS: 1.11.2 COCOAPODS: 1.11.2

View File

@ -549,7 +549,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos; SUPPORTED_PLATFORMS = iphoneos;
@ -567,20 +567,23 @@
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = QMWX3X2NF7; DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = QMWX3X2NF7;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.0; IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 0.2.10; MARKETING_VERSION = 0.2.32;
PRODUCT_BUNDLE_IDENTIFIER = com.jiaqi.hacki; PRODUCT_BUNDLE_IDENTIFIER = com.jiaqi.hacki;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match Development com.jiaqi.hacki";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
@ -635,7 +638,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos; SDKROOT = iphoneos;
@ -684,7 +687,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos; SUPPORTED_PLATFORMS = iphoneos;
@ -704,20 +707,23 @@
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = QMWX3X2NF7; DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = QMWX3X2NF7;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.0; IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 0.2.10; MARKETING_VERSION = 0.2.32;
PRODUCT_BUNDLE_IDENTIFIER = com.jiaqi.hacki; PRODUCT_BUNDLE_IDENTIFIER = com.jiaqi.hacki;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match Development com.jiaqi.hacki";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
@ -735,20 +741,23 @@
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = QMWX3X2NF7; DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = QMWX3X2NF7;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.0; IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 0.2.10; MARKETING_VERSION = 0.2.32;
PRODUCT_BUNDLE_IDENTIFIER = com.jiaqi.hacki; PRODUCT_BUNDLE_IDENTIFIER = com.jiaqi.hacki;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.jiaqi.hacki";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
@ -767,9 +776,11 @@
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = "Share Extension/Share Extension.entitlements"; CODE_SIGN_ENTITLEMENTS = "Share Extension/Share Extension.entitlements";
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = QMWX3X2NF7; DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = QMWX3X2NF7;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "Share Extension/Info.plist"; INFOPLIST_FILE = "Share Extension/Info.plist";
@ -786,6 +797,8 @@
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.jiaqi.hacki.Share-Extension"; PRODUCT_BUNDLE_IDENTIFIER = "com.jiaqi.hacki.Share-Extension";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "hacki share extension profile";
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_EMIT_LOC_STRINGS = YES;
@ -806,9 +819,11 @@
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = "Share Extension/Share Extension.entitlements"; CODE_SIGN_ENTITLEMENTS = "Share Extension/Share Extension.entitlements";
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = QMWX3X2NF7; DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = QMWX3X2NF7;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "Share Extension/Info.plist"; INFOPLIST_FILE = "Share Extension/Info.plist";
@ -824,6 +839,8 @@
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.jiaqi.hacki.Share-Extension"; PRODUCT_BUNDLE_IDENTIFIER = "com.jiaqi.hacki.Share-Extension";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.jiaqi.hacki.Share-Extension";
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
@ -842,9 +859,11 @@
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = "Share Extension/Share Extension.entitlements"; CODE_SIGN_ENTITLEMENTS = "Share Extension/Share Extension.entitlements";
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = QMWX3X2NF7; DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = QMWX3X2NF7;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "Share Extension/Info.plist"; INFOPLIST_FILE = "Share Extension/Info.plist";
@ -860,6 +879,8 @@
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.jiaqi.hacki.Share-Extension"; PRODUCT_BUNDLE_IDENTIFIER = "com.jiaqi.hacki.Share-Extension";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "hacki share extension profile";
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
@ -880,9 +901,11 @@
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = "Action Extension/Action Extension.entitlements"; CODE_SIGN_ENTITLEMENTS = "Action Extension/Action Extension.entitlements";
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = QMWX3X2NF7; DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = QMWX3X2NF7;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "Action Extension/Info.plist"; INFOPLIST_FILE = "Action Extension/Info.plist";
@ -899,6 +922,8 @@
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.jiaqi.hacki.Action-Extension"; PRODUCT_BUNDLE_IDENTIFIER = "com.jiaqi.hacki.Action-Extension";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "hacki action extension profile";
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_EMIT_LOC_STRINGS = YES;
@ -921,9 +946,11 @@
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = "Action Extension/Action Extension.entitlements"; CODE_SIGN_ENTITLEMENTS = "Action Extension/Action Extension.entitlements";
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = QMWX3X2NF7; DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = QMWX3X2NF7;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "Action Extension/Info.plist"; INFOPLIST_FILE = "Action Extension/Info.plist";
@ -939,6 +966,8 @@
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.jiaqi.hacki.Action-Extension"; PRODUCT_BUNDLE_IDENTIFIER = "com.jiaqi.hacki.Action-Extension";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.jiaqi.hacki.Action-Extension";
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
@ -959,9 +988,11 @@
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = "Action Extension/Action Extension.entitlements"; CODE_SIGN_ENTITLEMENTS = "Action Extension/Action Extension.entitlements";
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = QMWX3X2NF7; DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = QMWX3X2NF7;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "Action Extension/Info.plist"; INFOPLIST_FILE = "Action Extension/Info.plist";
@ -977,6 +1008,8 @@
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.jiaqi.hacki.Action-Extension"; PRODUCT_BUNDLE_IDENTIFIER = "com.jiaqi.hacki.Action-Extension";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "hacki action extension profile";
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;

View File

@ -39,6 +39,12 @@
</array> </array>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string> <string>$(CURRENT_PROJECT_VERSION)</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>https</string>
<string>http</string>
<string>mailto</string>
</array>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/> <true/>
<key>UIBackgroundModes</key> <key>UIBackgroundModes</key>

View File

@ -7,10 +7,10 @@
<key>NSExtensionAttributes</key> <key>NSExtensionAttributes</key>
<dict> <dict>
<key>NSExtensionActivationRule</key> <key>NSExtensionActivationRule</key>
<dict> <dict>
<key>NSExtensionActivationSupportsWebURLWithMaxCount</key> <key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
<integer>1</integer> <integer>1</integer>
</dict> </dict>
</dict> </dict>
<key>NSExtensionMainStoryboard</key> <key>NSExtensionMainStoryboard</key>
<string>MainInterface</string> <string>MainInterface</string>

8
ios/fastlane/Appfile Normal file
View File

@ -0,0 +1,8 @@
app_identifier("com.jiaqi.hacki") # The bundle identifier of your app
apple_id("georgefung78@Live.com") # Your Apple Developer Portal username
itc_team_id("120097292") # App Store Connect Team ID
team_id("QMWX3X2NF7") # Developer Portal Team ID
# For more information about the Appfile, see:
# https://docs.fastlane.tools/advanced/#appfile

96
ios/fastlane/Fastfile Normal file
View File

@ -0,0 +1,96 @@
# This file contains the fastlane.tools configuration
# You can find the documentation at https://docs.fastlane.tools
#
# For a list of all available actions, check out
#
# https://docs.fastlane.tools/actions
#
# For a list of all available plugins, check out
#
# https://docs.fastlane.tools/plugins/available-plugins
#
## Update these lines to match your project!
# Bundle Identifier used for the iOS App on the App Store Connect portal
APP_IDENTIFIER = 'com.jiaqi.hacki'
# Issuer ID from the Keys section of https://appstoreconnect.apple.com/access/users
APPSTORECONNECT_ISSUER_ID = '0b588ac9-5b3e-4420-867a-a33decce7b91'
# Key ID from the key matching the `APP_STORE_CONNECT_API_KEY_KEY` secret, found under the Keys section of https://appstoreconnect.apple.com/access/users
APPSTORECONNECT_KEY_ID = 'DPNP8R66QS'
# Uncomment the line if you want fastlane to automatically update itself
# update_fastlane
default_platform(:ios)
platform :ios do
desc "Push a new beta build to TestFlight"
lane :beta do |options|
setup_ci if ENV['CI']
is_example_repo = ENV['CI'] && ENV['GITHUB_REPOSITORY'] == 'jorgenpt/flutter_github_example'
if !is_example_repo && APP_IDENTIFIER == 'no.tjer.HelloWorld' then
UI.user_error! "You need to update your Fastfile to use your own `APP_IDENTIFIER`"
end
# Download code signing certificates using `match` (and the `MATCH_PASSWORD` secret)
sync_code_signing(
type: "appstore",
app_identifier: [APP_IDENTIFIER, "#{APP_IDENTIFIER}.Share-Extension", "#{APP_IDENTIFIER}.Action-Extension"],
readonly: true
)
if !is_example_repo then
if APPSTORECONNECT_ISSUER_ID == '69a6de83-feb7-47e3-e053-5b8c7c11a4d1' then
UI.user_error! "You need to update your Fastfile to use your own `APPSTORECONNECT_ISSUER_ID`"
end
if APPSTORECONNECT_KEY_ID == 'YRQDJRKMR9' then
UI.user_error! "You need to update your Fastfile to use your own `APPSTORECONNECT_KEY_ID`"
end
end
# We expose the key data using `APP_STORE_CONNECT_API_KEY_KEY` secret on GH
app_store_connect_api_key(
key_id: APPSTORECONNECT_KEY_ID,
issuer_id: APPSTORECONNECT_ISSUER_ID
)
latest_testflight_build_number
# Figure out the build number (and optionally build name)
new_build_number = ( + 1)
extra_config_args = []
if options.key?(:build_name) then
extra_config_args = ["--build-name", options[:build_name].delete_prefix('v')]
end
# Prep the xcodeproject from Flutter without building (`--config-only`)
sh(
"flutter", "build", "ios", "--config-only",
"--release", "--no-pub", "--no-codesign",
"--build-number", new_build_number.to_s,
*extra_config_args
)
increment_version_number(
version_number: options[:build_name].delete_prefix('v').delete_suffix('-rc')
)
increment_build_number({
build_number: latest_testflight_build_number + 1
})
# Build & sign using Runner.xcworkspace
build_app(
workspace: "Runner.xcworkspace",
scheme: "Runner",
output_directory: "../build/ios/archive"
)
upload_to_testflight(
# This takes a long time, so don't waste GH runner minutes (but it means manually needing to
# set the build live for external testers).
skip_waiting_for_build_processing: true,
)
end
end

13
ios/fastlane/Matchfile Normal file
View File

@ -0,0 +1,13 @@
git_url("git@github.com:Livinglist/certificates.git")
storage_mode("git")
type("development") # The default type, can be: appstore, adhoc, enterprise or development
# app_identifier(["tools.fastlane.app", "tools.fastlane.app2"])
# username("user@fastlane.tools") # Your Apple Developer Portal username
# For all available options run `fastlane match --help`
# Remove the # in the beginning of the line to enable the other options
# The docs are available on https://docs.fastlane.tools/actions/match

View File

@ -7,7 +7,9 @@ import 'package:hacki/config/locator.dart';
import 'package:hacki/cubits/cubits.dart'; import 'package:hacki/cubits/cubits.dart';
import 'package:hacki/models/models.dart'; import 'package:hacki/models/models.dart';
import 'package:hacki/repositories/repositories.dart'; import 'package:hacki/repositories/repositories.dart';
import 'package:logger/logger.dart';
import 'package:responsive_builder/responsive_builder.dart'; import 'package:responsive_builder/responsive_builder.dart';
import 'package:rxdart/rxdart.dart';
part 'stories_event.dart'; part 'stories_event.dart';
part 'stories_state.dart'; part 'stories_state.dart';
@ -15,15 +17,18 @@ part 'stories_state.dart';
class StoriesBloc extends Bloc<StoriesEvent, StoriesState> { class StoriesBloc extends Bloc<StoriesEvent, StoriesState> {
StoriesBloc({ StoriesBloc({
required PreferenceCubit preferenceCubit, required PreferenceCubit preferenceCubit,
CacheRepository? cacheRepository, OfflineRepository? offlineRepository,
StoriesRepository? storiesRepository, StoriesRepository? storiesRepository,
PreferenceRepository? preferenceRepository, PreferenceRepository? preferenceRepository,
Logger? logger,
}) : _preferenceCubit = preferenceCubit, }) : _preferenceCubit = preferenceCubit,
_cacheRepository = cacheRepository ?? locator.get<CacheRepository>(), _offlineRepository =
offlineRepository ?? locator.get<OfflineRepository>(),
_storiesRepository = _storiesRepository =
storiesRepository ?? locator.get<StoriesRepository>(), storiesRepository ?? locator.get<StoriesRepository>(),
_preferenceRepository = _preferenceRepository =
preferenceRepository ?? locator.get<PreferenceRepository>(), preferenceRepository ?? locator.get<PreferenceRepository>(),
_logger = logger ?? locator.get<Logger>(),
super(const StoriesState.init()) { super(const StoriesState.init()) {
on<StoriesInitialize>(onInitialize); on<StoriesInitialize>(onInitialize);
on<StoriesRefresh>(onRefresh); on<StoriesRefresh>(onRefresh);
@ -32,15 +37,17 @@ class StoriesBloc extends Bloc<StoriesEvent, StoriesState> {
on<StoryRead>(onStoryRead); on<StoryRead>(onStoryRead);
on<StoriesLoaded>(onStoriesLoaded); on<StoriesLoaded>(onStoriesLoaded);
on<StoriesDownload>(onDownload); on<StoriesDownload>(onDownload);
on<StoryDownloaded>(onStoryDownloaded);
on<StoriesExitOffline>(onExitOffline); on<StoriesExitOffline>(onExitOffline);
on<StoriesPageSizeChanged>(onPageSizeChanged); on<StoriesPageSizeChanged>(onPageSizeChanged);
on<ClearAllReadStories>(onClearAllReadStories); on<ClearAllReadStories>(onClearAllReadStories);
} }
final PreferenceCubit _preferenceCubit; final PreferenceCubit _preferenceCubit;
final CacheRepository _cacheRepository; final OfflineRepository _offlineRepository;
final StoriesRepository _storiesRepository; final StoriesRepository _storiesRepository;
final PreferenceRepository _preferenceRepository; final PreferenceRepository _preferenceRepository;
final Logger _logger;
DeviceScreenType? deviceScreenType; DeviceScreenType? deviceScreenType;
StreamSubscription<PreferenceState>? _streamSubscription; StreamSubscription<PreferenceState>? _streamSubscription;
static const int _smallPageSize = 10; static const int _smallPageSize = 10;
@ -48,6 +55,15 @@ class StoriesBloc extends Bloc<StoriesEvent, StoriesState> {
static const int _tabletSmallPageSize = 15; static const int _tabletSmallPageSize = 15;
static const int _tabletLargePageSize = 25; static const int _tabletLargePageSize = 25;
/// Types of story to be shown in the tab bar.
static const Set<StoryType> types = <StoryType>{
StoryType.top,
StoryType.best,
StoryType.latest,
StoryType.ask,
StoryType.show,
};
Future<void> onInitialize( Future<void> onInitialize(
StoriesInitialize event, StoriesInitialize event,
Emitter<StoriesState> emit, Emitter<StoriesState> emit,
@ -61,7 +77,7 @@ class StoriesBloc extends Bloc<StoriesEvent, StoriesState> {
add(StoriesPageSizeChanged(pageSize: pageSize)); add(StoriesPageSizeChanged(pageSize: pageSize));
} }
}); });
final bool hasCachedStories = await _cacheRepository.hasCachedStories; final bool hasCachedStories = await _offlineRepository.hasCachedStories;
final bool isComplexTile = _preferenceCubit.state.showComplexStoryTile; final bool isComplexTile = _preferenceCubit.state.showComplexStoryTile;
final int pageSize = _getPageSize(isComplexTile: isComplexTile); final int pageSize = _getPageSize(isComplexTile: isComplexTile);
emit( emit(
@ -70,11 +86,9 @@ class StoriesBloc extends Bloc<StoriesEvent, StoriesState> {
currentPageSize: pageSize, currentPageSize: pageSize,
), ),
); );
await loadStories(of: StoryType.top, emit: emit); for (final StoryType type in types) {
await loadStories(of: StoryType.latest, emit: emit); await loadStories(of: type, emit: emit);
await loadStories(of: StoryType.ask, emit: emit); }
await loadStories(of: StoryType.show, emit: emit);
await loadStories(of: StoryType.jobs, emit: emit);
} }
Future<void> loadStories({ Future<void> loadStories({
@ -82,13 +96,13 @@ class StoriesBloc extends Bloc<StoriesEvent, StoriesState> {
required Emitter<StoriesState> emit, required Emitter<StoriesState> emit,
}) async { }) async {
if (state.offlineReading) { if (state.offlineReading) {
final List<int> ids = await _cacheRepository.getCachedStoryIds(of: of); final List<int> ids = await _offlineRepository.getCachedStoryIds(of: of);
emit( emit(
state state
.copyWithStoryIdsUpdated(of: of, to: ids) .copyWithStoryIdsUpdated(of: of, to: ids)
.copyWithCurrentPageUpdated(of: of, to: 0), .copyWithCurrentPageUpdated(of: of, to: 0),
); );
_cacheRepository _offlineRepository
.getCachedStoriesStream( .getCachedStoriesStream(
ids: ids.sublist(0, min(ids.length, state.currentPageSize)), ids: ids.sublist(0, min(ids.length, state.currentPageSize)),
) )
@ -159,7 +173,7 @@ class StoriesBloc extends Bloc<StoriesEvent, StoriesState> {
} }
if (state.offlineReading) { if (state.offlineReading) {
_cacheRepository _offlineRepository
.getCachedStoriesStream( .getCachedStoriesStream(
ids: state.storyIdsByType[event.type]!.sublist( ids: state.storyIdsByType[event.type]!.sublist(
lower, lower,
@ -233,56 +247,46 @@ class StoriesBloc extends Bloc<StoriesEvent, StoriesState> {
), ),
); );
await _cacheRepository.deleteAllStoryIds(); await _offlineRepository.deleteAllStoryIds();
await _cacheRepository.deleteAllStories(); await _offlineRepository.deleteAllStories();
await _cacheRepository.deleteAllComments(); await _offlineRepository.deleteAllComments();
final List<int> topIds = final Set<int> prioritizedIds = <int>{};
await _storiesRepository.fetchStoryIds(of: StoryType.top); final List<StoryType> prioritizedTypes = <StoryType>[...types]
final List<int> newIds = ..remove(StoryType.latest);
await _storiesRepository.fetchStoryIds(of: StoryType.latest);
final List<int> askIds =
await _storiesRepository.fetchStoryIds(of: StoryType.ask);
final List<int> showIds =
await _storiesRepository.fetchStoryIds(of: StoryType.show);
final List<int> jobIds =
await _storiesRepository.fetchStoryIds(of: StoryType.jobs);
await _cacheRepository.cacheStoryIds(of: StoryType.top, ids: topIds); for (final StoryType type in prioritizedTypes) {
await _cacheRepository.cacheStoryIds(of: StoryType.latest, ids: newIds); final List<int> ids = await _storiesRepository.fetchStoryIds(of: type);
await _cacheRepository.cacheStoryIds(of: StoryType.ask, ids: askIds); await _offlineRepository.cacheStoryIds(of: type, ids: ids);
await _cacheRepository.cacheStoryIds(of: StoryType.show, ids: showIds); prioritizedIds.addAll(ids);
await _cacheRepository.cacheStoryIds(of: StoryType.jobs, ids: jobIds); }
final List<int> allIds = <int>[ emit(
...topIds, state.copyWith(
...newIds, storiesDownloaded: 0,
...askIds, storiesToBeDownloaded: prioritizedIds.length,
...showIds, ),
...jobIds );
];
try { try {
_storiesRepository await fetchAndCacheStories(
.fetchStoriesStream(ids: allIds) prioritizedIds,
.listen((Story story) async { includingWebPage: event.includingWebPage,
if (story.kids.isNotEmpty) { isPrioritized: true,
await _cacheRepository.cacheStory(story: story); );
_storiesRepository
.fetchAllChildrenComments(ids: story.kids) final Set<int> latestIds = <int>{};
.listen((Comment? comment) async { final List<int> ids = await _storiesRepository.fetchStoryIds(
if (comment != null) { of: StoryType.latest,
await _cacheRepository.cacheComment(comment: comment); );
} await _offlineRepository.cacheStoryIds(of: StoryType.latest, ids: ids);
}); latestIds.addAll(ids);
}
}).onDone(() { await fetchAndCacheStories(
emit( latestIds,
state.copyWith( includingWebPage: event.includingWebPage,
downloadStatus: StoriesDownloadStatus.finished, isPrioritized: false,
), );
);
});
} catch (_) { } catch (_) {
emit( emit(
state.copyWith( state.copyWith(
@ -292,6 +296,80 @@ class StoriesBloc extends Bloc<StoriesEvent, StoriesState> {
} }
} }
Future<void> fetchAndCacheStories(
Iterable<int> ids, {
required bool includingWebPage,
required bool isPrioritized,
}) async {
for (final int id in ids) {
final Story? story = await _storiesRepository.fetchStoryBy(id);
if (story == null) {
if (isPrioritized) {
add(StoryDownloaded(skipped: true));
}
continue;
}
if (story.kids.isEmpty) {
if (isPrioritized) {
add(StoryDownloaded(skipped: true));
}
continue;
}
await _offlineRepository.cacheStory(story: story);
if (story.url.isNotEmpty && includingWebPage) {
_logger.i('downloading ${story.url}');
await _offlineRepository.cacheUrl(url: story.url);
}
_storiesRepository
.fetchAllChildrenComments(ids: story.kids)
.whereType<Comment>()
.listen(
(Comment comment) => unawaited(
_offlineRepository.cacheComment(comment: comment),
),
)
.onDone(() => add(StoryDownloaded(skipped: false)));
}
}
void onStoryDownloaded(StoryDownloaded event, Emitter<StoriesState> emit) {
if (event.skipped) {
final int updatedStoriesToBeDownloaded = state.storiesToBeDownloaded - 1;
emit(
state.copyWith(
storiesToBeDownloaded: updatedStoriesToBeDownloaded,
downloadStatus:
state.storiesDownloaded == updatedStoriesToBeDownloaded
? StoriesDownloadStatus.finished
: null,
),
);
} else {
final int updatedStoriesDownloaded = state.storiesDownloaded + 1;
final int updatedStoriesToBeDownloaded =
updatedStoriesDownloaded > state.storiesToBeDownloaded
? state.storiesToBeDownloaded + 1
: state.storiesToBeDownloaded;
emit(
state.copyWith(
storiesDownloaded: updatedStoriesDownloaded,
storiesToBeDownloaded: updatedStoriesToBeDownloaded,
downloadStatus:
updatedStoriesDownloaded == updatedStoriesToBeDownloaded
? StoriesDownloadStatus.finished
: null,
),
);
}
}
Future<void> onPageSizeChanged( Future<void> onPageSizeChanged(
StoriesPageSizeChanged event, StoriesPageSizeChanged event,
Emitter<StoriesState> emit, Emitter<StoriesState> emit,
@ -304,9 +382,10 @@ class StoriesBloc extends Bloc<StoriesEvent, StoriesState> {
StoriesExitOffline event, StoriesExitOffline event,
Emitter<StoriesState> emit, Emitter<StoriesState> emit,
) async { ) async {
await _cacheRepository.deleteAllStoryIds(); await _offlineRepository.deleteAllStoryIds();
await _cacheRepository.deleteAllStories(); await _offlineRepository.deleteAllStories();
await _cacheRepository.deleteAllComments(); await _offlineRepository.deleteAllComments();
await _offlineRepository.deleteAllWebPages();
emit(state.copyWith(offlineReading: false)); emit(state.copyWith(offlineReading: false));
add(StoriesInitialize()); add(StoriesInitialize());
} }

View File

@ -38,8 +38,21 @@ class StoriesLoadMore extends StoriesEvent {
} }
class StoriesDownload extends StoriesEvent { class StoriesDownload extends StoriesEvent {
StoriesDownload({required this.includingWebPage});
final bool includingWebPage;
@override @override
List<Object?> get props => <Object?>[]; List<Object?> get props => <Object?>[includingWebPage];
}
class StoryDownloaded extends StoriesEvent {
StoryDownloaded({required this.skipped});
final bool skipped;
@override
List<Object?> get props => <Object?>[skipped];
} }
class StoriesExitOffline extends StoriesEvent { class StoriesExitOffline extends StoriesEvent {

View File

@ -23,11 +23,14 @@ class StoriesState extends Equatable {
required this.offlineReading, required this.offlineReading,
required this.downloadStatus, required this.downloadStatus,
required this.currentPageSize, required this.currentPageSize,
required this.storiesDownloaded,
required this.storiesToBeDownloaded,
}); });
const StoriesState.init({ const StoriesState.init({
this.storiesByType = const <StoryType, List<Story>>{ this.storiesByType = const <StoryType, List<Story>>{
StoryType.top: <Story>[], StoryType.top: <Story>[],
StoryType.best: <Story>[],
StoryType.latest: <Story>[], StoryType.latest: <Story>[],
StoryType.ask: <Story>[], StoryType.ask: <Story>[],
StoryType.show: <Story>[], StoryType.show: <Story>[],
@ -35,6 +38,7 @@ class StoriesState extends Equatable {
}, },
this.storyIdsByType = const <StoryType, List<int>>{ this.storyIdsByType = const <StoryType, List<int>>{
StoryType.top: <int>[], StoryType.top: <int>[],
StoryType.best: <int>[],
StoryType.latest: <int>[], StoryType.latest: <int>[],
StoryType.ask: <int>[], StoryType.ask: <int>[],
StoryType.show: <int>[], StoryType.show: <int>[],
@ -42,6 +46,7 @@ class StoriesState extends Equatable {
}, },
this.statusByType = const <StoryType, StoriesStatus>{ this.statusByType = const <StoryType, StoriesStatus>{
StoryType.top: StoriesStatus.initial, StoryType.top: StoriesStatus.initial,
StoryType.best: StoriesStatus.initial,
StoryType.latest: StoriesStatus.initial, StoryType.latest: StoriesStatus.initial,
StoryType.ask: StoriesStatus.initial, StoryType.ask: StoriesStatus.initial,
StoryType.show: StoriesStatus.initial, StoryType.show: StoriesStatus.initial,
@ -49,6 +54,7 @@ class StoriesState extends Equatable {
}, },
this.currentPageByType = const <StoryType, int>{ this.currentPageByType = const <StoryType, int>{
StoryType.top: 0, StoryType.top: 0,
StoryType.best: 0,
StoryType.latest: 0, StoryType.latest: 0,
StoryType.ask: 0, StoryType.ask: 0,
StoryType.show: 0, StoryType.show: 0,
@ -57,7 +63,9 @@ class StoriesState extends Equatable {
}) : offlineReading = false, }) : offlineReading = false,
downloadStatus = StoriesDownloadStatus.initial, downloadStatus = StoriesDownloadStatus.initial,
currentPageSize = 0, currentPageSize = 0,
readStoriesIds = const <int>{}; readStoriesIds = const <int>{},
storiesDownloaded = 0,
storiesToBeDownloaded = 0;
final Map<StoryType, List<Story>> storiesByType; final Map<StoryType, List<Story>> storiesByType;
final Map<StoryType, List<int>> storyIdsByType; final Map<StoryType, List<int>> storyIdsByType;
@ -67,6 +75,8 @@ class StoriesState extends Equatable {
final StoriesDownloadStatus downloadStatus; final StoriesDownloadStatus downloadStatus;
final bool offlineReading; final bool offlineReading;
final int currentPageSize; final int currentPageSize;
final int storiesDownloaded;
final int storiesToBeDownloaded;
StoriesState copyWith({ StoriesState copyWith({
Map<StoryType, List<Story>>? storiesByType, Map<StoryType, List<Story>>? storiesByType,
@ -77,6 +87,8 @@ class StoriesState extends Equatable {
StoriesDownloadStatus? downloadStatus, StoriesDownloadStatus? downloadStatus,
bool? offlineReading, bool? offlineReading,
int? currentPageSize, int? currentPageSize,
int? storiesDownloaded,
int? storiesToBeDownloaded,
}) { }) {
return StoriesState( return StoriesState(
storiesByType: storiesByType ?? this.storiesByType, storiesByType: storiesByType ?? this.storiesByType,
@ -87,6 +99,9 @@ class StoriesState extends Equatable {
offlineReading: offlineReading ?? this.offlineReading, offlineReading: offlineReading ?? this.offlineReading,
downloadStatus: downloadStatus ?? this.downloadStatus, downloadStatus: downloadStatus ?? this.downloadStatus,
currentPageSize: currentPageSize ?? this.currentPageSize, currentPageSize: currentPageSize ?? this.currentPageSize,
storiesDownloaded: storiesDownloaded ?? this.storiesDownloaded,
storiesToBeDownloaded:
storiesToBeDownloaded ?? this.storiesToBeDownloaded,
); );
} }
@ -98,18 +113,12 @@ class StoriesState extends Equatable {
final Map<StoryType, List<Story>> newMap = final Map<StoryType, List<Story>> newMap =
Map<StoryType, List<Story>>.from(storiesByType); Map<StoryType, List<Story>>.from(storiesByType);
newMap[of] = List<Story>.from(newMap[of]!)..add(story); newMap[of] = List<Story>.from(newMap[of]!)..add(story);
return StoriesState( return copyWith(
storiesByType: newMap, storiesByType: newMap,
storyIdsByType: storyIdsByType,
statusByType: statusByType,
currentPageByType: currentPageByType,
readStoriesIds: <int>{ readStoriesIds: <int>{
...readStoriesIds, ...readStoriesIds,
if (hasRead) story.id, if (hasRead) story.id,
}, },
offlineReading: offlineReading,
downloadStatus: downloadStatus,
currentPageSize: currentPageSize,
); );
} }
@ -120,15 +129,8 @@ class StoriesState extends Equatable {
final Map<StoryType, List<int>> newMap = final Map<StoryType, List<int>> newMap =
Map<StoryType, List<int>>.from(storyIdsByType); Map<StoryType, List<int>>.from(storyIdsByType);
newMap[of] = to; newMap[of] = to;
return StoriesState( return copyWith(
storiesByType: storiesByType,
storyIdsByType: newMap, storyIdsByType: newMap,
statusByType: statusByType,
currentPageByType: currentPageByType,
readStoriesIds: readStoriesIds,
offlineReading: offlineReading,
downloadStatus: downloadStatus,
currentPageSize: currentPageSize,
); );
} }
@ -139,15 +141,8 @@ class StoriesState extends Equatable {
final Map<StoryType, StoriesStatus> newMap = final Map<StoryType, StoriesStatus> newMap =
Map<StoryType, StoriesStatus>.from(statusByType); Map<StoryType, StoriesStatus>.from(statusByType);
newMap[of] = to; newMap[of] = to;
return StoriesState( return copyWith(
storiesByType: storiesByType,
storyIdsByType: storyIdsByType,
statusByType: newMap, statusByType: newMap,
currentPageByType: currentPageByType,
readStoriesIds: readStoriesIds,
offlineReading: offlineReading,
downloadStatus: downloadStatus,
currentPageSize: currentPageSize,
); );
} }
@ -158,15 +153,8 @@ class StoriesState extends Equatable {
final Map<StoryType, int> newMap = final Map<StoryType, int> newMap =
Map<StoryType, int>.from(currentPageByType); Map<StoryType, int>.from(currentPageByType);
newMap[of] = to; newMap[of] = to;
return StoriesState( return copyWith(
storiesByType: storiesByType,
storyIdsByType: storyIdsByType,
statusByType: statusByType,
currentPageByType: newMap, currentPageByType: newMap,
readStoriesIds: readStoriesIds,
offlineReading: offlineReading,
downloadStatus: downloadStatus,
currentPageSize: currentPageSize,
); );
} }
@ -183,15 +171,11 @@ class StoriesState extends Equatable {
final Map<StoryType, int> newCurrentPageMap = final Map<StoryType, int> newCurrentPageMap =
Map<StoryType, int>.from(currentPageByType); Map<StoryType, int>.from(currentPageByType);
newCurrentPageMap[of] = 0; newCurrentPageMap[of] = 0;
return StoriesState( return copyWith(
storiesByType: newStoriesMap, storiesByType: newStoriesMap,
storyIdsByType: newStoryIdsMap, storyIdsByType: newStoryIdsMap,
statusByType: newStatusMap, statusByType: newStatusMap,
currentPageByType: newCurrentPageMap, currentPageByType: newCurrentPageMap,
readStoriesIds: readStoriesIds,
offlineReading: offlineReading,
downloadStatus: downloadStatus,
currentPageSize: currentPageSize,
); );
} }
@ -205,5 +189,7 @@ class StoriesState extends Equatable {
offlineReading, offlineReading,
downloadStatus, downloadStatus,
currentPageSize, currentPageSize,
storiesDownloaded,
storiesToBeDownloaded,
]; ];
} }

View File

@ -9,6 +9,7 @@ abstract class Constants {
'https://apps.apple.com/us/app/hacki/id1602043763?action=write-review'; 'https://apps.apple.com/us/app/hacki/id1602043763?action=write-review';
static const String googlePlayLink = static const String googlePlayLink =
'https://play.google.com/store/apps/details?id=com.jiaqifeng.hacki&hl=en_US&gl=US'; 'https://play.google.com/store/apps/details?id=com.jiaqifeng.hacki&hl=en_US&gl=US';
static const String sponsorLink = 'https://github.com/sponsors/Livinglist';
static const String _imagePath = 'assets/images'; static const String _imagePath = 'assets/images';
static const String hackerNewsLogoPath = '$_imagePath/hacker_news_logo.png'; static const String hackerNewsLogoPath = '$_imagePath/hacker_news_logo.png';

View File

@ -0,0 +1,30 @@
import 'package:logger/logger.dart';
class CustomLogFilter extends LogFilter {
@override
Level? get level => Level.verbose;
/// The minimal level allowed in production.
static const Level _minimalLevel = Level.info;
@override
bool shouldLog(LogEvent event) {
bool shouldLog = false;
if (event.level.index >= _minimalLevel.index) {
return true;
}
assert(
() {
if (event.level.index >= level!.index) {
shouldLog = true;
}
return true;
}(),
'',
);
return shouldLog;
}
}

View File

@ -10,8 +10,8 @@ class CustomRouter {
switch (settings.name) { switch (settings.name) {
case HomeScreen.routeName: case HomeScreen.routeName:
return HomeScreen.route(); return HomeScreen.route();
case StoryScreen.routeName: case ItemScreen.routeName:
return StoryScreen.route(settings.arguments! as StoryScreenArgs); return ItemScreen.route(settings.arguments! as ItemScreenArgs);
case SubmitScreen.routeName: case SubmitScreen.routeName:
return SubmitScreen.route(); return SubmitScreen.route();
default: default:
@ -22,8 +22,8 @@ class CustomRouter {
/// Nested routing for bottom navigation bar. /// Nested routing for bottom navigation bar.
static Route<dynamic> onGenerateNestedRoute(RouteSettings settings) { static Route<dynamic> onGenerateNestedRoute(RouteSettings settings) {
switch (settings.name) { switch (settings.name) {
case StoryScreen.routeName: case ItemScreen.routeName:
return StoryScreen.route(settings.arguments! as StoryScreenArgs); return ItemScreen.route(settings.arguments! as ItemScreenArgs);
case SubmitScreen.routeName: case SubmitScreen.routeName:
return SubmitScreen.route(); return SubmitScreen.route();
default: default:

Some files were not shown because too many files have changed in this diff Show More