Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
314 commits
Select commit Hold shift + click to select a range
1ed2efe
Migrate more widgets to use the new measurement provider
rolandgeider Mar 13, 2026
d38a760
Start removing the old MeasurementProvider, refactor measurement form
rolandgeider Mar 14, 2026
e20de66
Fix and cleanup some tests
rolandgeider Mar 14, 2026
8ddd964
Remove old MeasurementProvider
rolandgeider Mar 14, 2026
b106090
Move language models to "core"
rolandgeider Mar 14, 2026
997e4af
Add ingredient and license tables
rolandgeider Mar 14, 2026
6750859
Move powersync table definitions
rolandgeider Mar 14, 2026
c916136
Update measurement models
rolandgeider Mar 15, 2026
3ea4713
Use UUIDv7, as in the backend
rolandgeider Mar 21, 2026
9c531a7
Merge branch 'master' into feature/offline-mode
rolandgeider Apr 17, 2026
6dea8d5
Merge branch 'master' into feature/offline-mode
rolandgeider Apr 17, 2026
0b9d3d5
Move exercise model to new variation structure
rolandgeider Apr 17, 2026
efce4a9
Bump some dependencies
rolandgeider Apr 17, 2026
4cbbdbf
Don't make the repositories final
rolandgeider Apr 17, 2026
70dff57
Fix tests
rolandgeider Apr 17, 2026
8ad3585
Refactor the auth provider, and move it to riverpod
rolandgeider Apr 17, 2026
f4a0a9b
Migrate the user provider to riverpode
rolandgeider Apr 17, 2026
95fb6c6
Migrate the nutrition provider to riverpod
rolandgeider Apr 17, 2026
97dee19
Migrate the gallery provider to riverpod
rolandgeider Apr 17, 2026
d708860
Migrate the contribute provider to riverpod and remove the old provid…
rolandgeider Apr 17, 2026
c1a733b
Clear the powersync database when a user logs out
rolandgeider Apr 17, 2026
8252dcd
Properly check if the userprofile was correctly loaded
rolandgeider Apr 18, 2026
7a15ea0
Remove rive as a dependency, not needed anymore
rolandgeider Apr 18, 2026
0afb102
Further refactor how the new providers fetch data
rolandgeider Apr 18, 2026
af378df
Make the routines provider async
rolandgeider Apr 18, 2026
9a4fec8
Refactor the workout session provider
rolandgeider Apr 18, 2026
fdce3bf
Rename file with the wger base provider
rolandgeider Apr 18, 2026
d70c43e
Properly gate the parts of the application that need network connecti…
rolandgeider Apr 18, 2026
1258382
Use common widget to render AsyncValues (errors, loading, etc.)
rolandgeider Apr 18, 2026
dc67d29
Don't do real DNS checks during tests
rolandgeider Apr 18, 2026
7f68036
Invalidate data providers after successful login/logout
rolandgeider Apr 20, 2026
e0892c4
Refactor calendar widget
rolandgeider Apr 20, 2026
e8e0cc5
Remove the uuid column in the weight table, this doesn't exist anymore
rolandgeider Apr 20, 2026
c59fd68
Pass the userID and the expiration to the PowerSync credentials
rolandgeider Apr 20, 2026
eaa4579
Use correct controller
rolandgeider Apr 22, 2026
f7458f8
Add unreachable server screen and related error handling
rolandgeider Apr 23, 2026
9cccca2
Consolidate app server checks in one helper
rolandgeider Apr 23, 2026
f5ab4ca
Handle HTTP errors
rolandgeider Apr 23, 2026
c1d2fbe
Show loading spinner for the routine widget in the dashboard
rolandgeider Apr 23, 2026
30072fb
Properly handle timezones for datetime values
rolandgeider Apr 24, 2026
27cdd32
Set the exercises for log objects
rolandgeider Apr 24, 2026
b6923d1
Refactor exercise providers
rolandgeider Apr 24, 2026
88e0248
Remove BodyWeightState
rolandgeider Apr 24, 2026
e2d650f
Use the AsyncValueWidget when handling Stream-Provider data
rolandgeider Apr 24, 2026
72ef83e
Translate the sync status in the main icon
rolandgeider Apr 24, 2026
4b58117
Show more sync information to the user
rolandgeider Apr 24, 2026
4353f00
Start handling validation errors from the backend for powersync opera…
rolandgeider Apr 28, 2026
680127e
Sync the base Routine and Nutritional plan entries via powersync
rolandgeider Apr 29, 2026
06a445a
Properly gate the nutritional plan FAB when there's no network connec…
rolandgeider Apr 29, 2026
cbc4fa1
Properly handle DateFields
rolandgeider Apr 29, 2026
c5dbcc2
Extract routines repository to its own file
rolandgeider Apr 29, 2026
733fe24
Remove fetchAndSetRoutineFull from future
rolandgeider Apr 29, 2026
40c3bbc
Use the workout session and logs from the current routine in summary.…
rolandgeider Apr 29, 2026
379d86c
Commit connector transform test
rolandgeider Apr 29, 2026
5f52538
Wrap the log and session saving logic in a transaction
rolandgeider Apr 29, 2026
271d9f9
Refactor unit selection for repetitions and weight
rolandgeider Apr 29, 2026
e0068e9
Hydrate exercise and unit objects in routine entries
rolandgeider Apr 29, 2026
3fbdaac
Consolidate routine hydration logic
rolandgeider Apr 29, 2026
5bf2dd2
Properly load the ingredient images
rolandgeider Apr 29, 2026
d135e81
Cache ingredient and exercise images on device
rolandgeider Apr 30, 2026
4751b2d
Delete old images from the device older than approx. 3 months
rolandgeider Apr 30, 2026
3505611
Be a bit smarter about contructing the absolute URL for images
rolandgeider Apr 30, 2026
c5ac063
Properly mark columns as nullable
rolandgeider Apr 30, 2026
a9644ab
Refactor ingredient handling to use direct object references
rolandgeider Apr 30, 2026
d6e652f
Sync the ingredient weight units to the local sqlite db
rolandgeider Apr 30, 2026
5ee653b
Improve error logging
rolandgeider Apr 30, 2026
d152031
Refactor ingredient weight unit handling and remove unused methods
rolandgeider Apr 30, 2026
97c4a5b
Refactor ingredient weight unit handling and remove unused methods
rolandgeider Apr 30, 2026
a1722f1
Open ingredient info dialog from the nutritional plan list
rolandgeider Apr 30, 2026
445063b
Properly fake network connectivity in the tests
rolandgeider Apr 30, 2026
73e1621
Updated goldens
rolandgeider Apr 30, 2026
d1f6fc2
Sync nutritional logs
rolandgeider Apr 30, 2026
5fea670
Merge master
rolandgeider Apr 30, 2026
9f365f8
Consolidate ingredient search methods into the ingredient repo
rolandgeider May 1, 2026
09f0202
Merge remote-tracking branch 'origin/feature/offline-mode' into featu…
rolandgeider May 1, 2026
9226b06
Rename for more consistency
rolandgeider May 1, 2026
3540437
Refactor exercise repository online/offline search
rolandgeider May 1, 2026
209ab7c
Add gallery sync tables
rolandgeider May 1, 2026
16ffafe
Remove unused methods
rolandgeider May 1, 2026
2f2c781
Cleanup providers and use consistent naming
rolandgeider May 1, 2026
5d30a1c
Cleanup providers and use consistent naming
rolandgeider May 1, 2026
2cb4061
Cleanup providers and use consistent naming
rolandgeider May 1, 2026
e56d5a8
Add missing tests for the new repositories and states
rolandgeider May 1, 2026
df9a69d
Create a new id for when setting new logs
rolandgeider May 1, 2026
35789cf
Remove validateLanguage, this wasn't used
rolandgeider May 1, 2026
a63cce2
Test the powersync communications with the outer world
rolandgeider May 1, 2026
cf13af1
Sync the rest of the nutrition tables to powersync
rolandgeider May 1, 2026
d6affe4
Sync the rest of the nutrition tables with powersync
rolandgeider May 2, 2026
1a9ab58
refactor: improve image error handling with pattern matching and URI …
pankaj-basnet May 2, 2026
f578938
refactor(models): add copyWith to Routine and make replaceExercise im…
pankaj-basnet May 2, 2026
11a8393
fix(gym): resolve in-place routine mutation in replaceExercises
pankaj-basnet May 2, 2026
050258b
Merge pull request #1187 from pankaj-basnet/fix/offline-mode--provide…
rolandgeider May 3, 2026
c1dccbd
Make the "impression" in workout session an enum
rolandgeider May 2, 2026
1ec921f
Consistent usage of uuid IDs
rolandgeider May 2, 2026
1249036
Properly update routine data
rolandgeider May 2, 2026
0fb660d
Move access to nutritional plans to the nutrition state
rolandgeider May 3, 2026
2ce3cc2
Cleanup
rolandgeider May 3, 2026
c39c418
Merge master
rolandgeider May 3, 2026
2c8164f
Update Podfile.lock
rolandgeider May 4, 2026
395eb58
Merge remote-tracking branch 'origin/master' into feature/offline-mode
rolandgeider May 7, 2026
83569fc
Merge remote-tracking branch 'origin/master' into feature/offline-mode
rolandgeider May 7, 2026
130232e
Remove null assertions where not needed
rolandgeider May 8, 2026
11699f8
Slightly increase the maximum workout duration
rolandgeider May 8, 2026
f4c8db7
Properly use mutable objects
rolandgeider May 8, 2026
98737fd
Extract helper functions as own widgets
rolandgeider May 8, 2026
944b27e
Also sync all the license information, even if we don't expose all of…
rolandgeider May 15, 2026
d71bbcf
Update to flutter 3.44
rolandgeider May 19, 2026
d5acd00
Move to swift package manager
rolandgeider May 19, 2026
cbf6884
Update the online connectivity gates
rolandgeider May 20, 2026
0674066
Remove unused code and mocks
rolandgeider May 20, 2026
99d8d2c
Remove unused test fixtures
rolandgeider May 20, 2026
4866551
Move exercises and their translations to RawTables
rolandgeider May 20, 2026
f8187b2
Cleanup exercise models
rolandgeider May 20, 2026
25b4441
Correctly load the notes and aliases for exercises
rolandgeider May 20, 2026
bf9916a
Merge remote-tracking branch 'origin/master' into feature/offline-mode
rolandgeider May 20, 2026
a5cb4e2
feat(nutrition): add ingredient filters model and repository, riverpo…
pankaj-basnet May 12, 2026
508b552
Remove unused fatalResponseCodes
rolandgeider May 20, 2026
9913ee4
Use WgerImage to render the trophies
rolandgeider May 20, 2026
c411e89
Consolidate time and date picking logic into their own widgets
rolandgeider May 20, 2026
dc5bd1e
Consolidate localized number edit logic into its own widgets
rolandgeider May 20, 2026
97e0e63
Consolidate submission logic into its own widget
rolandgeider May 20, 2026
834d7e4
Consolidate form error handling
rolandgeider May 21, 2026
52364eb
Merge branch 'master' into feature/offline-mode
rolandgeider May 21, 2026
cd2f3db
Merge branch 'feature/offline-mode' into feat/nutrition-ingredients-i…
rolandgeider May 21, 2026
394cb48
Show local ingredients in overview
rolandgeider May 21, 2026
4ebc98e
Regenerate mock files and fix test
rolandgeider May 21, 2026
848ba17
Format number inputs according to locale
rolandgeider May 21, 2026
370a7d8
Remove obsolete _isSaving guard
rolandgeider May 21, 2026
cfa40da
Remove obsolete FormProgressIndicator
rolandgeider May 21, 2026
60cf1b9
Remove remaining podfiles and their configurations
rolandgeider May 21, 2026
e99a036
Replace the allowed connectivity list
rolandgeider May 21, 2026
d97de48
Refactor the error logic
rolandgeider May 22, 2026
d0c56c4
Re-probe the connection to the wger server itself
rolandgeider May 22, 2026
4edf49b
Reduce the pollution of logs from powersync
rolandgeider May 22, 2026
51730e9
Make more widgets online-aware
rolandgeider May 22, 2026
1075a28
Remove the AuthStatus.serverUnreachable case
rolandgeider May 22, 2026
af8ed10
Also write to the user profile via powersync
rolandgeider May 22, 2026
a08defb
feature(nutrition): refactor IngredientsScreen and create IngredientD…
pankaj-basnet May 22, 2026
736cb41
Improve the login process
rolandgeider May 22, 2026
164d583
Gate the trophies provider when the server is not available
rolandgeider May 22, 2026
26722a4
Start implementing JWT support
rolandgeider May 15, 2026
3f89b5a
Add secure storage integration and headless (allauth) JWT support
rolandgeider May 15, 2026
225a689
Implement refresh token logic
rolandgeider May 15, 2026
42752de
Move Authorization header to a dedicated HTTP client
rolandgeider May 15, 2026
87a40fd
Switch the pasted-token field from DRF tokens to refresh tokens
rolandgeider May 15, 2026
6188175
Add 2fa login screen
rolandgeider May 15, 2026
8fc1497
Edit the user's email via allauth's endpoints
rolandgeider May 15, 2026
32677fb
Edit the user's email via allauth's endpoints
rolandgeider May 15, 2026
291d3f0
Extract token from correct key
rolandgeider May 15, 2026
8213c44
Add "login via web"
rolandgeider May 18, 2026
0e6dfe9
Receive wger:// deep links on Linux
rolandgeider May 18, 2026
efd9620
Add D-Bus service file
rolandgeider May 19, 2026
e282c57
Remove DBusActivatable, this is probably not needed
rolandgeider May 19, 2026
d1077ff
Mark app as needing attention
rolandgeider May 19, 2026
fadcb93
Add missing build dependencies
rolandgeider May 19, 2026
99f54a8
Regenerate build files
rolandgeider May 19, 2026
fe5c7bb
Regenerate build files
rolandgeider May 22, 2026
b9dd03c
Re-apply login-process improvements on headless auth
rolandgeider May 22, 2026
3772934
Fix trophy provider online gate
rolandgeider May 22, 2026
cc7ae51
Mark trophy box in the dashboard when no internet is available
rolandgeider May 22, 2026
1b72fb7
Fix circular provider dependency
rolandgeider May 22, 2026
ea30877
Merge branch 'feature/allauth' into feature/offline-mode
rolandgeider May 22, 2026
aaa7885
Cleanup auth screen
rolandgeider May 22, 2026
d77fc07
More cleanup on the auth screen
rolandgeider May 22, 2026
6ffb1b6
Add some more tests for the auth screen
rolandgeider May 22, 2026
a7e30fc
Refactor auth screen
rolandgeider May 24, 2026
dff9ed5
Better validators for logs
rolandgeider May 25, 2026
b3b1387
Better validators for workout sessions
rolandgeider May 25, 2026
987d82b
Better validators for min/max constrained values
rolandgeider May 25, 2026
45e693d
Better validators for min/max constrained values
rolandgeider May 25, 2026
e7d0028
Fix bug in the measurements overview
rolandgeider May 25, 2026
0f4a122
Better validators for workout session notes
rolandgeider May 25, 2026
7858008
Better validators for nutritional plan values
rolandgeider May 25, 2026
806fc93
Cleanup
rolandgeider May 25, 2026
34b1fa6
Merge branch 'feature/offline-mode' into feat/nutrition-ingredients-i…
rolandgeider May 25, 2026
bcfe836
Fix some i18n issues
rolandgeider May 25, 2026
1f55069
Don't rebuild on every keystroke
rolandgeider May 25, 2026
4132779
Split ingredient providers
rolandgeider May 25, 2026
5c91624
Make the ingredient object nullable for logs and meal items
rolandgeider May 25, 2026
5194a6c
Refactor the ingredient detail screen
rolandgeider May 25, 2026
3204df1
Properly filter the ingredient list
rolandgeider May 25, 2026
6849685
Watch the passed ingredient
rolandgeider May 25, 2026
92d731f
Don't rebuild the whole widget on every keystroke
rolandgeider May 25, 2026
a485fd2
Split gym state and notifier into their own files
rolandgeider May 25, 2026
c8b1aa3
Online-gate the exercise submission page/links
rolandgeider May 25, 2026
6436226
Remove network info dashboard widget
rolandgeider May 25, 2026
7d958b5
Top-align the contents of the WidescreenWrapper
rolandgeider May 25, 2026
98e9ea9
Smarter handling of token lifetimes
rolandgeider May 25, 2026
1009477
Fix behaviour on logout
rolandgeider May 25, 2026
9003b46
Add migration path from old permanent token to JWT
rolandgeider May 25, 2026
f4df847
Extract some logic into their own files
rolandgeider May 25, 2026
fa36a16
Small cleanup
rolandgeider May 25, 2026
400b210
Add brand to the model
rolandgeider May 26, 2026
00db3d9
Properly online-gate access to the user profile
rolandgeider May 26, 2026
6f0a322
Add outgoing icons to external links
rolandgeider May 26, 2026
d3da6dc
Online-gate the ingredient scan button
rolandgeider May 26, 2026
b2250fa
Merge remote-tracking branch 'origin/master' into feature/offline-mode
rolandgeider May 27, 2026
7908664
Update flatpak configuration file
rolandgeider May 27, 2026
4deab80
Configure shared preferences for the test
rolandgeider May 27, 2026
ed757d2
Slight refactor of appVersion handling
rolandgeider May 27, 2026
759b393
Updated goldens
rolandgeider May 27, 2026
14abce7
Suppress drift's multiple databases warning
rolandgeider May 27, 2026
8f562e5
Properly handle exercise videos
rolandgeider May 27, 2026
fb74e25
Remove dependency on wgerBaseProvider
rolandgeider Jun 2, 2026
137ad19
Properly handle "." and "," for numerical inputs
rolandgeider Jun 3, 2026
8a626ae
Handle (transient) case where an exercise has no translations
rolandgeider Jun 3, 2026
f86ee08
Add tests for the powersync transaction process logic
rolandgeider Jun 3, 2026
ae2c693
Use leftOuterJoin in the nutrition sql
rolandgeider Jun 3, 2026
33dbd15
Correctly delete the user's local db on logout
rolandgeider Jun 3, 2026
152e5ca
Fold the tests from the log_page_test into gym_mode_test.dart
rolandgeider Jun 3, 2026
a411461
Cleanup
rolandgeider Jun 3, 2026
ac2eaff
Revive log_page_test.dart
rolandgeider Jun 3, 2026
67bf658
Fix bug causing the routine provider to enter a refresh loop
rolandgeider Jun 3, 2026
1a13785
Add a new hydration provider family for routines
rolandgeider Jun 4, 2026
68428a0
Wipe the local DB only on a real user switch
rolandgeider Jun 4, 2026
0d3d7d7
Remove unused translation keys
rolandgeider Jun 4, 2026
ca2530e
Better error handling for powersync errors
rolandgeider Jun 4, 2026
a923574
Show a bit more info for RetryableUploadException
rolandgeider Jun 4, 2026
5b9be74
Add more validators to the slot configs
rolandgeider Jun 4, 2026
e29c120
Add more validators
rolandgeider Jun 4, 2026
c795bb4
Fix empty selection bug
rolandgeider Jun 4, 2026
0e7a7db
Properly save the correct unit type
rolandgeider Jun 4, 2026
b04db23
Remove unused code
rolandgeider Jun 4, 2026
40e3b56
Fix tests
rolandgeider Jun 4, 2026
14c7e8d
More i18n cleanup
rolandgeider Jun 4, 2026
b7674aa
Reset the accountProvider on logout
rolandgeider Jun 5, 2026
41bb7d3
Throw exception if the db could not be wiped on logout
rolandgeider Jun 5, 2026
63cc163
Be more lenient on transient server errors
rolandgeider Jun 5, 2026
0c10e32
Make sure the search filters are not rebuilt every time
rolandgeider Jun 5, 2026
3cbe7c9
Correctly reset the session ID so a new one is generated
rolandgeider Jun 5, 2026
a442535
Add bug preventing the web-handoff workflow from working with self-ho…
rolandgeider Jun 5, 2026
16a6cd0
Harden detail screen pages
rolandgeider Jun 5, 2026
57947ea
Don't default to black text
rolandgeider Jun 5, 2026
662ad9b
Properly handle timezones
rolandgeider Jun 5, 2026
dbce51f
The ingredient energy is stored in kcal, not kJ
rolandgeider Jun 5, 2026
675fb44
Also properly handle (for now) unused datetime fields
rolandgeider Jun 5, 2026
e93c4ef
Exercise IDs are integers, not text
rolandgeider Jun 5, 2026
30df030
Add converter for date-only fields, otherwise comparisons break
rolandgeider Jun 14, 2026
51508d5
Handle case where after submitting an exercise it is not synced back yet
rolandgeider Jun 14, 2026
efaa512
Fix column types
rolandgeider Jun 14, 2026
db458ac
Don't log the user's refresh token
rolandgeider Jun 14, 2026
eae855b
Properly handle the case where the token could not be decrypted
rolandgeider Jun 14, 2026
01b746f
Fix image picker validation and error handling logic
rolandgeider Jun 14, 2026
3ec7e23
Pass the slotUUID to some gym pages
rolandgeider Jun 14, 2026
5f9abdb
Slight refactor of the error handling
rolandgeider Jun 14, 2026
54e9729
Consolidate usage of FormSubmitButton
rolandgeider Jun 14, 2026
0651cbb
Consolidate usage of showConfirmDeleteDialog
rolandgeider Jun 14, 2026
63e9d81
Consolidate usage of DateInputWidget
rolandgeider Jun 14, 2026
499d156
Merge remote-tracking branch 'origin/master' into feature/offline-mode
rolandgeider Jun 15, 2026
62042bd
Rename allauth's URLs
rolandgeider Jun 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .github/actions/flutter-common/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ runs:
uses: subosito/flutter-action@v2
with:
channel: stable
flutter-version: 3.41.9
flutter-version: 3.44.0
cache: true

- name: Install Flutter dependencies
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/build-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ jobs:
- name: Build application for linux
run: |
sudo apt update
sudo apt install -y pkg-config libgtk-3-dev liblzma-dev libstdc++-12-dev --no-install-recommends
sudo apt install -y pkg-config libgtk-3-dev liblzma-dev libstdc++-12-dev libsecret-1-dev libjsoncpp-dev --no-install-recommends
flutter build linux --release
tar -zcvf linux-${{ matrix.platform }}.tar.gz build/linux/${{ matrix.platform }}/release/bundle
- uses: actions/upload-artifact@v7
Expand Down Expand Up @@ -92,7 +92,7 @@ jobs:
git clone https://github.com/TheAppgineer/flatpak-flutter.git --branch 0.14.1 ../flatpak-flutter
pip install -r ../flatpak-flutter/requirements.txt
python bump-versions.py ${{ inputs.ref }} ${{ needs.build_linux.outputs.flutter_sdk_version }}
../flatpak-flutter/flatpak-flutter.py --app-module wger flatpak-flutter.json
../flatpak-flutter/flatpak-flutter.py --app-module wger flatpak-flutter.yml

- name: Push updated config to flathub repository
env:
Expand Down
6 changes: 0 additions & 6 deletions .github/workflows/screenshots.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,6 @@ jobs:
- name: Common flutter setup
uses: ./.github/actions/flutter-common

- name: Install CocoaPods
run: |
cd ios
pod install || true
cd ..

- name: Boot iOS simulator
id: boot
run: |
Expand Down
9 changes: 9 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,15 @@
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

<!-- Web-handoff deep link: the server redirects to wger://app-auth#token=…
after a browser login; app_link_router consumes the URI. -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="wger" android:host="app-auth" />
</intent-filter>
</activity>


Expand Down
6 changes: 6 additions & 0 deletions build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
targets:
$default:
builders:
drift_dev:
options:
store_date_time_values_as_text: true
3 changes: 2 additions & 1 deletion devtools_options.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
extensions:
- drift: true
- provider: true
- provider: true
- shared_preferences: true
3 changes: 2 additions & 1 deletion flatpak/de.wger.flutter.desktop
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ Comment=Fitness/workout, nutrition and weight tracker
# HealthFitness;Exercise;Nutrition
Categories=Education;Utility;Sports;
Icon=de.wger.flutter
Exec=wger
Exec=wger %u
MimeType=x-scheme-handler/wger;
StartupWMClass=wger
X-Purism-FormFactor=Workstation;Mobile;
X-KDE-FormFactors=desktop;tablet;handset;mediacenter;
3 changes: 3 additions & 0 deletions flatpak/de.wger.flutter.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[D-BUS Service]
Name=de.wger.flutter
Exec=/app/bin/wger --gapplication-service
3 changes: 1 addition & 2 deletions integration_test/make_screenshots_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ enum DeviceType {
androidWear('wearScreenshots'),

iOSPhoneBig('iPhone 6.9', isAndroid: false),
iOSPhoneSmall('iPhone 6.7', isAndroid: false)
;
iOSPhoneSmall('iPhone 6.7', isAndroid: false);

final String folderName;
final bool isAndroid;
Expand Down
175 changes: 78 additions & 97 deletions integration_test/screenshots_01_dashboard.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,131 +17,112 @@
*/

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart' as riverpod;
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mockito/mockito.dart';
import 'package:provider/provider.dart';
import 'package:wger/l10n/generated/app_localizations.dart';
import 'package:wger/models/workouts/session.dart';
import 'package:wger/providers/auth.dart';
import 'package:wger/providers/body_weight.dart';
import 'package:wger/providers/exercises.dart';
import 'package:wger/providers/gallery.dart';
import 'package:wger/providers/measurement.dart';
import 'package:wger/providers/nutrition.dart';
import 'package:wger/providers/routines.dart';
import 'package:wger/providers/user.dart';
import 'package:wger/models/measurements/measurement_category.dart';
import 'package:wger/providers/auth_notifier.dart';
import 'package:wger/providers/auth_state.dart';
import 'package:wger/providers/body_weight_repository.dart';
import 'package:wger/providers/gallery_repository.dart';
import 'package:wger/providers/ingredient_repository.dart';
import 'package:wger/providers/measurement_repository.dart';
import 'package:wger/providers/nutrition_notifier.dart';
import 'package:wger/providers/nutrition_repository.dart';
import 'package:wger/providers/routines_notifier.dart';
import 'package:wger/providers/user_profile_repository.dart';
import 'package:wger/screens/home_tabs_screen.dart';
import 'package:wger/theme/theme.dart';

import '../test/exercises/contribute_exercise_test.mocks.dart';
import '../test/gallery/gallery_form_test.mocks.dart';
import '../test/measurements/measurement_categories_screen_test.mocks.dart';
import '../test/nutrition/nutritional_plan_screen_test.mocks.dart';
import '../test/routine/weight_unit_form_widget_test.mocks.dart';
import '../test/weight/weight_screen_test.mocks.dart' as weight;
import '../test_data/body_weight.dart';
import '../test_data/exercises.dart';
import '../test_data/gallery.dart';
import '../test_data/measurements.dart';
import '../test_data/nutritional_plans.dart';
import '../test_data/profile.dart';
import '../test_data/routines.dart';

Widget createDashboardScreen({Locale? locale}) {
locale ??= const Locale('en');
class _FakeAuthNotifier extends AuthNotifier {
_FakeAuthNotifier(this._state);

final mockGalleryProvider = MockGalleryProvider();
final AuthState _state;

final mockExercisesProvider = MockExercisesProvider();
@override
Future<AuthState> build() async => _state;
}

final mockAuthProvider = MockAuthProvider();
when(mockAuthProvider.setServerVersion()).thenAnswer((_) async {});
when(mockAuthProvider.dataInit).thenReturn(true);
Widget createDashboardScreen({Locale? locale}) {
locale ??= const Locale('en');

final mockWorkoutProvider = MockRoutinesProvider();
when(mockWorkoutProvider.items).thenReturn([getTestRoutine(exercises: getScreenshotExercises())]);
when(
mockWorkoutProvider.currentRoutine,
).thenReturn(getTestRoutine(exercises: getScreenshotExercises()));
final mockGalleryRepo = MockGalleryRepository();
when(mockGalleryRepo.watchAllDrift()).thenAnswer((_) => Stream.value(getTestImages()));

when(mockWorkoutProvider.fetchSessionData()).thenAnswer(
(a) => Future.value([
WorkoutSession(
routineId: 1,
date: DateTime.now().add(const Duration(days: -1)),
timeStart: const TimeOfDay(hour: 17, minute: 34),
timeEnd: const TimeOfDay(hour: 19, minute: 3),
impression: 3,
),
]),
);
final mockNutritionRepo = weight.MockNutritionRepository();
final mockIngredientRepo = weight.MockIngredientRepository();
when(mockIngredientRepo.getById(any)).thenAnswer((_) async => null);

final mockNutritionProvider = weight.MockNutritionPlansProvider();
final mockBodyWeightRepository = MockBodyWeightRepository();
when(
mockBodyWeightRepository.watchAllDrift(),
).thenAnswer((_) => Stream.value(getWeightEntries()));

final mockMeasurementRepo = MockMeasurementRepository();
when(
mockNutritionProvider.currentPlan,
).thenAnswer((realInvocation) => getNutritionalPlanScreenshot());
when(mockNutritionProvider.items).thenReturn([getNutritionalPlanScreenshot()]);
mockMeasurementRepo.watchAll(),
).thenAnswer((_) => Stream<List<MeasurementCategory>>.value(getMeasurementCategories()));

final mockWeightProvider = weight.MockBodyWeightProvider();
when(mockWeightProvider.items).thenReturn(getScreenshotWeightEntries());
final mockUserProfileRepo = weight.MockUserProfileRepository();
when(
mockUserProfileRepo.watchDrift(),
).thenAnswer((_) => Stream.value(tUserProfile1));

final mockMeasurementProvider = MockMeasurementProvider();
when(mockMeasurementProvider.categories).thenReturn(getMeasurementCategories());
const loggedInAuth = AuthState(
status: AuthStatus.loggedIn,
credential: LegacyCredential('test-token'),
serverUrl: 'http://localhost',
);
final container = ProviderContainer.test(
overrides: [
bodyWeightRepositoryProvider.overrideWithValue(mockBodyWeightRepository),
measurementRepositoryProvider.overrideWithValue(mockMeasurementRepo),
authProvider.overrideWith(() => _FakeAuthNotifier(loggedInAuth)),
userProfileRepositoryProvider.overrideWithValue(mockUserProfileRepo),
nutritionRepositoryProvider.overrideWithValue(mockNutritionRepo),
ingredientRepositoryProvider.overrideWithValue(mockIngredientRepo),
galleryRepositoryProvider.overrideWithValue(mockGalleryRepo),
],
);
container.read(routinesRiverpodProvider.notifier).state = AsyncData(
RoutinesState(
routines: [getTestRoutine(exercises: getScreenshotExercises())],
),
);

final mockUserProvider = MockUserProvider();
when(mockUserProvider.profile).thenReturn(tProfile1);
when(mockUserProvider.dashboardWidgets).thenReturn([
DashboardWidget.routines,
DashboardWidget.weight,
DashboardWidget.measurements,
DashboardWidget.calendar,
DashboardWidget.nutrition,
DashboardWidget.trophies,
]);
// Seed the nutrition notifier with the screenshot plan so the dashboard can
// show it without going through the server.
container.read(nutritionProvider.notifier).state = AsyncData(
NutritionState(plans: [getNutritionalPlanScreenshot()]),
);

return riverpod.ProviderScope(
child: MediaQuery(
data: MediaQueryData.fromView(WidgetsBinding.instance.platformDispatcher.views.first)
.copyWith(
padding: EdgeInsets.zero,
viewPadding: EdgeInsets.zero,
viewInsets: EdgeInsets.zero,
),
child: MultiProvider(
providers: [
ChangeNotifierProvider<GalleryProvider>(
create: (context) => mockGalleryProvider,
),
ChangeNotifierProvider<ExercisesProvider>(
create: (context) => mockExercisesProvider,
),
ChangeNotifierProvider<AuthProvider>(
create: (context) => mockAuthProvider,
),
ChangeNotifierProvider<UserProvider>(
create: (context) => mockUserProvider,
),
ChangeNotifierProvider<RoutinesProvider>(
create: (context) => mockWorkoutProvider,
),
ChangeNotifierProvider<NutritionPlansProvider>(
create: (context) => mockNutritionProvider,
),
ChangeNotifierProvider<BodyWeightProvider>(
create: (context) => mockWeightProvider,
),
ChangeNotifierProvider<MeasurementProvider>(
create: (context) => mockMeasurementProvider,
),
],
child: MaterialApp(
locale: locale,
debugShowCheckedModeBanner: false,
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
theme: wgerLightTheme,
home: HomeTabsScreen(),
),
return MediaQuery(
data: MediaQueryData.fromView(WidgetsBinding.instance.platformDispatcher.views.first).copyWith(
padding: EdgeInsets.zero,
viewPadding: EdgeInsets.zero,
viewInsets: EdgeInsets.zero,
),
child: UncontrolledProviderScope(
container: container,
child: MaterialApp(
locale: locale,
debugShowCheckedModeBanner: false,
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
theme: wgerLightTheme,
home: HomeTabsScreen(),
),
),
);
Expand Down
22 changes: 10 additions & 12 deletions integration_test/screenshots_02_workout.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,37 +17,35 @@
*/

import 'package:flutter/material.dart';
import 'package:mockito/mockito.dart';
import 'package:provider/provider.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart' as riverpod;
import 'package:wger/l10n/generated/app_localizations.dart';
import 'package:wger/providers/routines.dart';
import 'package:wger/providers/routines_notifier.dart';
import 'package:wger/screens/routine_screen.dart';
import 'package:wger/theme/theme.dart';

import '../test/routine/routine_form_test.mocks.dart';
import '../test_data/exercises.dart';
import '../test_data/routines.dart';

Widget createWorkoutDetailScreen({Locale? locale}) {
locale ??= const Locale('en');
final key = GlobalKey<NavigatorState>();

final mockRoutinesProvider = MockRoutinesProvider();
final routine = getTestRoutine(exercises: getScreenshotExercises());
when(mockRoutinesProvider.findById(1)).thenReturn(routine);
final container = riverpod.ProviderContainer.test();
container.read(routinesRiverpodProvider.notifier).state = riverpod.AsyncData(
RoutinesState(
routines: [getTestRoutine(exercises: getScreenshotExercises())],
),
);

return MediaQuery(
data: MediaQueryData.fromView(WidgetsBinding.instance.platformDispatcher.views.first).copyWith(
padding: EdgeInsets.zero,
viewPadding: EdgeInsets.zero,
viewInsets: EdgeInsets.zero,
),
child: MultiProvider(
providers: [
ChangeNotifierProvider<RoutinesProvider>(
create: (context) => mockRoutinesProvider,
),
],
child: riverpod.UncontrolledProviderScope(
container: container,
child: MaterialApp(
locale: locale,
debugShowCheckedModeBanner: false,
Expand Down
Loading
Loading