mirror of
https://github.com/gabehf/Fladder.git
synced 2026-03-07 21:48:14 -08:00
[Setup] Added build.yaml and check.yaml (#1)
Co-authored-by: PartyDonut <PartyDonut@users.noreply.github.com>
This commit is contained in:
parent
226686eb18
commit
7b3e733b76
112 changed files with 3926 additions and 3784 deletions
188
.github/workflows/build.yml
vendored
188
.github/workflows/build.yml
vendored
|
|
@ -1,63 +1,90 @@
|
||||||
name: Build Fladder
|
name: Build Fladder artifacts
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
tags:
|
||||||
|
- "v*"
|
||||||
branches:
|
branches:
|
||||||
- develop
|
- master
|
||||||
pull_request:
|
workflow_dispatch:
|
||||||
branches:
|
|
||||||
- develop
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
#Implement linting/tests here first
|
|
||||||
flutter-checks:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v4.1.1
|
|
||||||
|
|
||||||
- name: Set up Flutter
|
|
||||||
uses: subosito/flutter-action@v2.12.0
|
|
||||||
with:
|
|
||||||
channel: "stable"
|
|
||||||
cache: true
|
|
||||||
cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:" # optional, change this to force refresh cache
|
|
||||||
cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:" # optional, change this to specify the cache path
|
|
||||||
|
|
||||||
- name: Get dependencies
|
|
||||||
run: flutter pub get
|
|
||||||
|
|
||||||
build-android:
|
build-android:
|
||||||
needs: flutter-checks
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4.1.1
|
uses: actions/checkout@v4.1.1
|
||||||
|
|
||||||
- name: Set up Flutter
|
- name: Decode Keystore
|
||||||
uses: subosito/flutter-action@v2.12.0
|
env:
|
||||||
|
ENCODED_STRING: ${{ secrets.KEYSTORE_BASE_64 }}
|
||||||
|
RELEASE_KEYSTORE_PASSWORD: ${{ secrets.RELEASE_KEYSTORE_PASSWORD }}
|
||||||
|
RELEASE_KEYSTORE_ALIAS: ${{ secrets.RELEASE_KEYSTORE_ALIAS }}
|
||||||
|
RELEASE_KEY_PASSWORD: ${{ secrets.RELEASE_KEY_PASSWORD }}
|
||||||
|
GITHUB_RUN_NUMBER: ${{ github.run_number }}
|
||||||
|
run: |
|
||||||
|
echo "$ENCODED_STRING" | base64 -d > android/app/keystore.jks
|
||||||
|
|
||||||
|
# Create the key.properties file
|
||||||
|
cat > android/app/key.properties <<EOF
|
||||||
|
storePassword=$RELEASE_KEYSTORE_PASSWORD
|
||||||
|
keyPassword=$RELEASE_KEY_PASSWORD
|
||||||
|
keyAlias=$RELEASE_KEYSTORE_ALIAS
|
||||||
|
EOF
|
||||||
|
|
||||||
|
- name: Setup Java
|
||||||
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
channel: "stable"
|
distribution: "zulu"
|
||||||
|
java-version: "17"
|
||||||
|
cache: "gradle"
|
||||||
|
check-latest: true
|
||||||
|
|
||||||
|
- name: Set up Flutter
|
||||||
|
uses: subosito/flutter-action@v2.16.0
|
||||||
|
with:
|
||||||
|
channel: ${{ vars.FLUTTER_CHANNEL }}
|
||||||
|
flutter-version: ${{ vars.FLUTTER_VERSION }}
|
||||||
cache: true
|
cache: true
|
||||||
cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:" # optional, change this to force refresh cache
|
cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:"
|
||||||
cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:" # optional, change this to specify the cache path
|
cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:"
|
||||||
|
|
||||||
- name: Get dependencies
|
- name: Get dependencies
|
||||||
run: flutter pub get
|
run: flutter pub get
|
||||||
|
|
||||||
- name: Build Android APK
|
- name: Build Android APK and AAB
|
||||||
run: flutter build apk
|
run: |
|
||||||
|
APP_NAME=$(grep '^name:' pubspec.yaml | cut -d ':' -f2 | tr -d ' ')
|
||||||
|
VERSION_NAME=$(grep '^version:' pubspec.yaml | cut -d ':' -f2 | cut -d '+' -f1 | tr -d ' ')
|
||||||
|
echo "APP_NAME=$APP_NAME" >> $GITHUB_ENV
|
||||||
|
echo "VERSION_NAME=$VERSION_NAME" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Archive Android artifact
|
# Build APK
|
||||||
|
flutter build apk --release \
|
||||||
|
--build-name=$VERSION_NAME \
|
||||||
|
--build-number=$GITHUB_RUN_NUMBER \
|
||||||
|
--dart-define=FLAVOR=release
|
||||||
|
|
||||||
|
# Build AAB
|
||||||
|
flutter build appbundle --release \
|
||||||
|
--build-name=$VERSION_NAME \
|
||||||
|
--build-number=$GITHUB_RUN_NUMBER \
|
||||||
|
--dart-define=FLAVOR=release
|
||||||
|
|
||||||
|
- name: Rename APK and AAB
|
||||||
|
run: |
|
||||||
|
mv build/app/outputs/flutter-apk/app-release.apk "build/app/outputs/flutter-apk/${{ env.APP_NAME }}-${{ env.VERSION_NAME }}-release.apk"
|
||||||
|
mv build/app/outputs/bundle/release/app-release.aab "build/app/outputs/bundle/release/${{ env.APP_NAME }}-${{ env.VERSION_NAME }}-release.aab"
|
||||||
|
|
||||||
|
- name: Archive Android artifacts
|
||||||
uses: actions/upload-artifact@v4.0.0
|
uses: actions/upload-artifact@v4.0.0
|
||||||
with:
|
with:
|
||||||
name: Android
|
name: Android-${{ env.VERSION_NAME }}
|
||||||
path: build/app/outputs/apk/release/app-release.apk
|
path: |
|
||||||
|
build/app/outputs/flutter-apk/${{ env.APP_NAME }}-${{ env.VERSION_NAME }}-release.apk
|
||||||
|
build/app/outputs/bundle/release/${{ env.APP_NAME }}-${{ env.VERSION_NAME }}-release.aab
|
||||||
|
|
||||||
build-windows:
|
build-windows:
|
||||||
needs: flutter-checks
|
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|
@ -65,9 +92,10 @@ jobs:
|
||||||
uses: actions/checkout@v4.1.1
|
uses: actions/checkout@v4.1.1
|
||||||
|
|
||||||
- name: Set up Flutter
|
- name: Set up Flutter
|
||||||
uses: subosito/flutter-action@v2.12.0
|
uses: subosito/flutter-action@v2.16.0
|
||||||
with:
|
with:
|
||||||
channel: "stable"
|
channel: ${{ vars.FLUTTER_CHANNEL }}
|
||||||
|
flutter-version: ${{ vars.FLUTTER_VERSION }}
|
||||||
cache: true
|
cache: true
|
||||||
cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:" # optional, change this to force refresh cache
|
cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:" # optional, change this to force refresh cache
|
||||||
cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:" # optional, change this to specify the cache path
|
cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:" # optional, change this to specify the cache path
|
||||||
|
|
@ -76,12 +104,20 @@ jobs:
|
||||||
run: flutter pub get
|
run: flutter pub get
|
||||||
|
|
||||||
- name: Build Windows EXE
|
- name: Build Windows EXE
|
||||||
run: flutter build windows
|
run: |
|
||||||
|
$pubspec = Get-Content pubspec.yaml
|
||||||
|
$APP_NAME = ($pubspec | Select-String '^name:' | ForEach-Object { ($_ -split ':')[1].Trim() })
|
||||||
|
$VERSION_NAME = ($pubspec | Select-String '^version:' | ForEach-Object { ($_ -split ':')[1].Trim().Split('+')[0] })
|
||||||
|
|
||||||
|
echo "APP_NAME=$APP_NAME" >> $Env:GITHUB_ENV
|
||||||
|
echo "VERSION_NAME=$VERSION_NAME" >> $Env:GITHUB_ENV
|
||||||
|
|
||||||
|
flutter build windows
|
||||||
|
|
||||||
- name: Archive Windows artifact
|
- name: Archive Windows artifact
|
||||||
uses: actions/upload-artifact@v4.0.0
|
uses: actions/upload-artifact@v4.0.0
|
||||||
with:
|
with:
|
||||||
name: Windows
|
name: Windows-${{ env.VERSION_NAME }}
|
||||||
path: build\windows\x64\runner\Release\
|
path: build\windows\x64\runner\Release\
|
||||||
|
|
||||||
# build-ios:
|
# build-ios:
|
||||||
|
|
@ -92,27 +128,40 @@ jobs:
|
||||||
# uses: actions/checkout@v4.1.1
|
# uses: actions/checkout@v4.1.1
|
||||||
|
|
||||||
# - name: Set up Flutter
|
# - name: Set up Flutter
|
||||||
# uses: subosito/flutter-action@v2.12.0
|
# uses: subosito/flutter-action@v2.16.0
|
||||||
# with:
|
# with:
|
||||||
# channel: "stable"
|
# channel: ${{ vars.FLUTTER_CHANNEL }}
|
||||||
|
# flutter-version: ${{ vars.FLUTTER_VERSION }}
|
||||||
# cache: true
|
# cache: true
|
||||||
# cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:" # optional, change this to force refresh cache
|
# cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:" # optional
|
||||||
# cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:" # optional, change this to specify the cache path
|
# cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:" # optional
|
||||||
|
|
||||||
# - name: Get dependencies
|
# - name: Get dependencies
|
||||||
# run: flutter pub get
|
# run: flutter pub get
|
||||||
|
|
||||||
# - name: Build iOS app
|
# - name: Build iOS app
|
||||||
# run: flutter build ios
|
# run: |
|
||||||
|
# APP_NAME=$(grep '^name:' pubspec.yaml | cut -d ':' -f2 | tr -d ' ')
|
||||||
|
# VERSION_NAME=$(grep '^version:' pubspec.yaml | cut -d ':' -f2 | cut -d '+' -f1 | tr -d ' ')
|
||||||
|
# echo "APP_NAME=$APP_NAME" >> $GITHUB_ENV
|
||||||
|
# echo "VERSION_NAME=$VERSION_NAME" >> $GITHUB_ENV
|
||||||
|
|
||||||
# - name: Archive iOS artifact
|
# flutter build ipa --no-codesign
|
||||||
# uses: actions/upload-artifact@v2
|
|
||||||
|
# - name: Export IPA from .xcarchive
|
||||||
|
# run: |
|
||||||
|
# xcodebuild -exportArchive \
|
||||||
|
# -archivePath build/ios/archive/Runner.xcarchive \
|
||||||
|
# -exportOptionsPlist ios/exportOptions.plist \
|
||||||
|
# -exportPath build/ios/ipa
|
||||||
|
|
||||||
|
# - name: Archive iOS IPA artifact
|
||||||
|
# uses: actions/upload-artifact@v4.0.0
|
||||||
# with:
|
# with:
|
||||||
# name: ios
|
# name: ios-${{ env.VERSION_NAME }}
|
||||||
# path: build/ios/iphoneos/Runner.app
|
# path: build/ios/ipa/*.ipa
|
||||||
|
|
||||||
build-macos:
|
build-macos:
|
||||||
needs: flutter-checks
|
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|
@ -120,9 +169,10 @@ jobs:
|
||||||
uses: actions/checkout@v4.1.1
|
uses: actions/checkout@v4.1.1
|
||||||
|
|
||||||
- name: Set up Flutter
|
- name: Set up Flutter
|
||||||
uses: subosito/flutter-action@v2.12.0
|
uses: subosito/flutter-action@v2.16.0
|
||||||
with:
|
with:
|
||||||
channel: "stable"
|
channel: ${{ vars.FLUTTER_CHANNEL }}
|
||||||
|
flutter-version: ${{ vars.FLUTTER_VERSION }}
|
||||||
cache: true
|
cache: true
|
||||||
cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:" # optional, change this to force refresh cache
|
cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:" # optional, change this to force refresh cache
|
||||||
cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:" # optional, change this to specify the cache path
|
cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:" # optional, change this to specify the cache path
|
||||||
|
|
@ -131,16 +181,21 @@ jobs:
|
||||||
run: flutter pub get
|
run: flutter pub get
|
||||||
|
|
||||||
- name: Build macOS app
|
- name: Build macOS app
|
||||||
run: flutter build macos
|
run: |
|
||||||
|
APP_NAME=$(grep '^name:' pubspec.yaml | cut -d ':' -f2 | tr -d ' ')
|
||||||
|
VERSION_NAME=$(grep '^version:' pubspec.yaml | cut -d ':' -f2 | cut -d '+' -f1 | tr -d ' ')
|
||||||
|
echo "APP_NAME=$APP_NAME" >> $GITHUB_ENV
|
||||||
|
echo "VERSION_NAME=$VERSION_NAME" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
flutter build macos
|
||||||
|
|
||||||
- name: Archive macOS artifact
|
- name: Archive macOS artifact
|
||||||
uses: actions/upload-artifact@v4.0.0
|
uses: actions/upload-artifact@v4.0.0
|
||||||
with:
|
with:
|
||||||
name: macOS
|
name: macOS-${{ env.VERSION_NAME }}
|
||||||
path: build/macos/Build/Products/Release/fladder.app
|
path: build/macos/Build/Products/Release/fladder.app
|
||||||
|
|
||||||
# build-linux:
|
# build-linux:
|
||||||
# needs: flutter-checks
|
|
||||||
# runs-on: ubuntu-latest
|
# runs-on: ubuntu-latest
|
||||||
|
|
||||||
# steps:
|
# steps:
|
||||||
|
|
@ -148,9 +203,10 @@ jobs:
|
||||||
# uses: actions/checkout@v4.1.1
|
# uses: actions/checkout@v4.1.1
|
||||||
|
|
||||||
# - name: Set up Flutter
|
# - name: Set up Flutter
|
||||||
# uses: subosito/flutter-action@v2.12.0
|
# uses: subosito/flutter-action@v2.16.0
|
||||||
# with:
|
# with:
|
||||||
# channel: "stable"
|
# channel: ${{ vars.FLUTTER_CHANNEL }}
|
||||||
|
# flutter-version: ${{ vars.FLUTTER_VERSION }}
|
||||||
# cache: true
|
# cache: true
|
||||||
# cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:" # optional, change this to force refresh cache
|
# cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:" # optional, change this to force refresh cache
|
||||||
# cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:" # optional, change this to specify the cache path
|
# cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:" # optional, change this to specify the cache path
|
||||||
|
|
@ -173,7 +229,6 @@ jobs:
|
||||||
# path: build/linux/x64/release/bundle
|
# path: build/linux/x64/release/bundle
|
||||||
|
|
||||||
build-web:
|
build-web:
|
||||||
needs: flutter-checks
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|
@ -181,9 +236,10 @@ jobs:
|
||||||
uses: actions/checkout@v4.1.1
|
uses: actions/checkout@v4.1.1
|
||||||
|
|
||||||
- name: Set up Flutter
|
- name: Set up Flutter
|
||||||
uses: subosito/flutter-action@v2.12.0
|
uses: subosito/flutter-action@v2.16.0
|
||||||
with:
|
with:
|
||||||
channel: "stable"
|
channel: ${{ vars.FLUTTER_CHANNEL }}
|
||||||
|
flutter-version: ${{ vars.FLUTTER_VERSION }}
|
||||||
cache: true
|
cache: true
|
||||||
cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:" # optional, change this to force refresh cache
|
cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:" # optional, change this to force refresh cache
|
||||||
cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:" # optional, change this to specify the cache path
|
cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:" # optional, change this to specify the cache path
|
||||||
|
|
@ -192,10 +248,16 @@ jobs:
|
||||||
run: flutter pub get
|
run: flutter pub get
|
||||||
|
|
||||||
- name: Build web app
|
- name: Build web app
|
||||||
run: flutter build web
|
run: |
|
||||||
|
APP_NAME=$(grep '^name:' pubspec.yaml | cut -d ':' -f2 | tr -d ' ')
|
||||||
|
VERSION_NAME=$(grep '^version:' pubspec.yaml | cut -d ':' -f2 | cut -d '+' -f1 | tr -d ' ')
|
||||||
|
echo "APP_NAME=$APP_NAME" >> $GITHUB_ENV
|
||||||
|
echo "VERSION_NAME=$VERSION_NAME" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
flutter build web
|
||||||
|
|
||||||
- name: Archive web artifact
|
- name: Archive web artifact
|
||||||
uses: actions/upload-artifact@v4.0.0
|
uses: actions/upload-artifact@v4.0.0
|
||||||
with:
|
with:
|
||||||
name: Web
|
name: Web-${{ env.VERSION_NAME }}
|
||||||
path: build/web
|
path: build/web
|
||||||
|
|
|
||||||
49
.github/workflows/checks.yaml
vendored
Normal file
49
.github/workflows/checks.yaml
vendored
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
name: Flutter checks
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- develop
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
linting:
|
||||||
|
name: Linting & Formatting
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4.1.1
|
||||||
|
|
||||||
|
- name: Set up Flutter
|
||||||
|
uses: subosito/flutter-action@v2.16.0
|
||||||
|
with:
|
||||||
|
channel: ${{ vars.FLUTTER_CHANNEL }}
|
||||||
|
flutter-version: ${{ vars.FLUTTER_VERSION }}
|
||||||
|
cache: true
|
||||||
|
cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:"
|
||||||
|
cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:"
|
||||||
|
|
||||||
|
- name: Get dependencies
|
||||||
|
run: flutter pub get
|
||||||
|
|
||||||
|
- name: Install arb_utils to check sorting of translations
|
||||||
|
run: dart pub global activate arb_utils
|
||||||
|
|
||||||
|
- name: Copy translation file
|
||||||
|
run: cp ./lib/l10n/app_en.arb ./lib/l10n/app_en_sorted.arb
|
||||||
|
|
||||||
|
- name: Sort translation file alphabetically
|
||||||
|
run: arb_utils sort ./lib/l10n/app_en.arb
|
||||||
|
|
||||||
|
- name: Check sorted translations against english base
|
||||||
|
run: |
|
||||||
|
# Check if the contents of the destination file match the reference file
|
||||||
|
if cmp -s "./lib/l10n/app_en.arb" "./lib/l10n/app_en_sorted.arb"; then
|
||||||
|
echo "Translation entries are in alphabetical order."
|
||||||
|
else
|
||||||
|
echo "Translation entries are not in alphabetical order."
|
||||||
|
exit 1 # Fail the workflow if files are not the same
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Linting
|
||||||
|
run: flutter analyze --no-fatal-infos --no-fatal-warnings
|
||||||
|
|
@ -1,7 +1,17 @@
|
||||||
include: package:lints/recommended.yaml
|
include: package:lints/recommended.yaml
|
||||||
|
|
||||||
analyzer:
|
analyzer:
|
||||||
exclude: [build/**, lib/jellyfin/**]
|
exclude:
|
||||||
|
- build/**
|
||||||
|
- lib/jellyfin/**
|
||||||
|
- lib/**/**.g.dart
|
||||||
|
- lib/**/**.freezed.dart
|
||||||
|
- lib/**/**.mapped.dart
|
||||||
|
- packages/**
|
||||||
|
- pubspec.yaml
|
||||||
|
strong-mode:
|
||||||
|
implicit-casts: false
|
||||||
|
implicit-dynamic: false
|
||||||
language:
|
language:
|
||||||
# strict-casts: false
|
# strict-casts: false
|
||||||
# strict-raw-types: true
|
# strict-raw-types: true
|
||||||
|
|
@ -17,3 +27,10 @@ linter:
|
||||||
prefer_relative_imports: false
|
prefer_relative_imports: false
|
||||||
avoid_relative_lib_imports: true
|
avoid_relative_lib_imports: true
|
||||||
eol_at_end_of_file: true
|
eol_at_end_of_file: true
|
||||||
|
prefer_final_fields: true
|
||||||
|
prefer_const_constructors: true
|
||||||
|
always_declare_return_types: true
|
||||||
|
type_init_formals: true
|
||||||
|
unnecessary_this: true
|
||||||
|
sort_pub_dependencies: true
|
||||||
|
use_key_in_widget_constructors: true
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ plugins {
|
||||||
}
|
}
|
||||||
|
|
||||||
def keystoreProperties = new Properties()
|
def keystoreProperties = new Properties()
|
||||||
def keystorePropertiesFile = rootProject.file('key.properties')
|
def keystorePropertiesFile = file('key.properties')
|
||||||
if (keystorePropertiesFile.exists()) {
|
if (keystorePropertiesFile.exists()) {
|
||||||
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
||||||
}
|
}
|
||||||
|
|
@ -55,9 +55,9 @@ android {
|
||||||
|
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
release {
|
release {
|
||||||
|
storeFile file('keystore.jks')
|
||||||
keyAlias keystoreProperties['keyAlias']
|
keyAlias keystoreProperties['keyAlias']
|
||||||
keyPassword keystoreProperties['keyPassword']
|
keyPassword keystoreProperties['keyPassword']
|
||||||
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
|
|
||||||
storePassword keystoreProperties['storePassword']
|
storePassword keystoreProperties['storePassword']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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>11.0</string>
|
<string>13.0</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
||||||
|
|
@ -343,7 +343,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 = 11.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SUPPORTED_PLATFORMS = iphoneos;
|
SUPPORTED_PLATFORMS = iphoneos;
|
||||||
|
|
@ -420,7 +420,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 = 11.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = YES;
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
|
|
@ -469,7 +469,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 = 11.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SUPPORTED_PLATFORMS = iphoneos;
|
SUPPORTED_PLATFORMS = iphoneos;
|
||||||
|
|
|
||||||
14
ios/exportOptions.plist
Normal file
14
ios/exportOptions.plist
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>method</key>
|
||||||
|
<string>release-testing</string>
|
||||||
|
<key>compileBitcode</key>
|
||||||
|
<false/>
|
||||||
|
<key>destination</key>
|
||||||
|
<string>export</string>
|
||||||
|
<key>signingStyle</key>
|
||||||
|
<string>manual</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
1110
lib/l10n/app_en.arb
1110
lib/l10n/app_en.arb
File diff suppressed because it is too large
Load diff
1124
lib/l10n/app_es.arb
1124
lib/l10n/app_es.arb
File diff suppressed because it is too large
Load diff
1124
lib/l10n/app_fr.arb
1124
lib/l10n/app_fr.arb
File diff suppressed because it is too large
Load diff
1124
lib/l10n/app_jp.arb
1124
lib/l10n/app_jp.arb
File diff suppressed because it is too large
Load diff
1110
lib/l10n/app_nl.arb
1110
lib/l10n/app_nl.arb
File diff suppressed because it is too large
Load diff
1124
lib/l10n/app_zh.arb
1124
lib/l10n/app_zh.arb
File diff suppressed because it is too large
Load diff
|
|
@ -302,7 +302,7 @@ class _MainState extends ConsumerState<Main> with WindowListener, WidgetsBinding
|
||||||
context: context,
|
context: context,
|
||||||
locale: AppLocalizations.supportedLocales.firstWhere(
|
locale: AppLocalizations.supportedLocales.firstWhere(
|
||||||
(element) => element.languageCode == language.languageCode,
|
(element) => element.languageCode == language.languageCode,
|
||||||
orElse: () => Locale('en', "GB"),
|
orElse: () => const Locale('en', "GB"),
|
||||||
),
|
),
|
||||||
child: ScaffoldMessenger(child: child ?? Container()),
|
child: ScaffoldMessenger(child: child ?? Container()),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ class ItemBaseModel with ItemBaseModelMappable {
|
||||||
SortingOptions.parentalRating => overview.parentalRating != null
|
SortingOptions.parentalRating => overview.parentalRating != null
|
||||||
? Row(
|
? Row(
|
||||||
children: [
|
children: [
|
||||||
Icon(
|
const Icon(
|
||||||
IconsaxBold.star_1,
|
IconsaxBold.star_1,
|
||||||
size: 14,
|
size: 14,
|
||||||
color: Colors.yellowAccent,
|
color: Colors.yellowAccent,
|
||||||
|
|
@ -85,7 +85,7 @@ class ItemBaseModel with ItemBaseModelMappable {
|
||||||
SortingOptions.communityRating => overview.communityRating != null
|
SortingOptions.communityRating => overview.communityRating != null
|
||||||
? Row(
|
? Row(
|
||||||
children: [
|
children: [
|
||||||
Icon(
|
const Icon(
|
||||||
IconsaxBold.star_1,
|
IconsaxBold.star_1,
|
||||||
size: 14,
|
size: 14,
|
||||||
color: Colors.yellowAccent,
|
color: Colors.yellowAccent,
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ class EpisodeModel extends ItemStreamModel with EpisodeModelMappable {
|
||||||
images: images,
|
images: images,
|
||||||
childCount: childCount,
|
childCount: childCount,
|
||||||
primaryRatio: primaryRatio,
|
primaryRatio: primaryRatio,
|
||||||
userData: UserData(),
|
userData: const UserData(),
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ class UserData with UserDataMappable {
|
||||||
|
|
||||||
factory UserData.fromDto(dto.UserItemDataDto? dto) {
|
factory UserData.fromDto(dto.UserItemDataDto? dto) {
|
||||||
if (dto == null) {
|
if (dto == null) {
|
||||||
return UserData();
|
return const UserData();
|
||||||
}
|
}
|
||||||
return UserData(
|
return UserData(
|
||||||
isFavourite: dto.isFavorite ?? false,
|
isFavourite: dto.isFavorite ?? false,
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ class SeasonModel extends ItemBaseModel with SeasonModelMappable {
|
||||||
images: images,
|
images: images,
|
||||||
childCount: childCount,
|
childCount: childCount,
|
||||||
primaryRatio: primaryRatio,
|
primaryRatio: primaryRatio,
|
||||||
userData: UserData(),
|
userData: const UserData(),
|
||||||
);
|
);
|
||||||
|
|
||||||
static List<SeasonModel> seasonsFromDto(List<dto.BaseItemDto>? dto, Ref ref) {
|
static List<SeasonModel> seasonsFromDto(List<dto.BaseItemDto>? dto, Ref ref) {
|
||||||
|
|
|
||||||
|
|
@ -113,5 +113,5 @@ class Vector2 {
|
||||||
@override
|
@override
|
||||||
int get hashCode => x.hashCode ^ y.hashCode;
|
int get hashCode => x.hashCode ^ y.hashCode;
|
||||||
|
|
||||||
static fromPosition(Offset windowPosition) => Vector2(x: windowPosition.dx, y: windowPosition.dy);
|
static Vector2 fromPosition(Offset windowPosition) => Vector2(x: windowPosition.dx, y: windowPosition.dy);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ class DashboardNotifier extends StateNotifier<HomeModel> {
|
||||||
final nextResponse = await api.showsNextUpGet(
|
final nextResponse = await api.showsNextUpGet(
|
||||||
limit: 16,
|
limit: 16,
|
||||||
nextUpDateCutoff: DateTime.now()
|
nextUpDateCutoff: DateTime.now()
|
||||||
.subtract(ref.read(clientSettingsProvider.select((value) => value.nextUpDateCutoff ?? Duration(days: 28)))),
|
.subtract(ref.read(clientSettingsProvider.select((value) => value.nextUpDateCutoff ?? const Duration(days: 28)))),
|
||||||
fields: [
|
fields: [
|
||||||
ItemFields.parentid,
|
ItemFields.parentid,
|
||||||
ItemFields.mediastreams,
|
ItemFields.mediastreams,
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ final librarySearchProvider =
|
||||||
});
|
});
|
||||||
|
|
||||||
class LibrarySearchNotifier extends StateNotifier<LibrarySearchModel> {
|
class LibrarySearchNotifier extends StateNotifier<LibrarySearchModel> {
|
||||||
LibrarySearchNotifier(this.ref) : super(LibrarySearchModel());
|
LibrarySearchNotifier(this.ref) : super(const LibrarySearchModel());
|
||||||
|
|
||||||
final Ref ref;
|
final Ref ref;
|
||||||
|
|
||||||
|
|
@ -379,7 +379,7 @@ class LibrarySearchNotifier extends StateNotifier<LibrarySearchModel> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
selectAll(bool select) => state = state.copyWith(selectedPosters: select ? state.posters : []);
|
LibrarySearchModel selectAll(bool select) => state = state.copyWith(selectedPosters: select ? state.posters : []);
|
||||||
|
|
||||||
Future<void> setSelectedAsFavorite(bool bool) async {
|
Future<void> setSelectedAsFavorite(bool bool) async {
|
||||||
final Map<String, UserData> updateInfo = {};
|
final Map<String, UserData> updateInfo = {};
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ class SessionInfo extends _$SessionInfo {
|
||||||
|
|
||||||
void _startTimer() {
|
void _startTimer() {
|
||||||
_fetchData();
|
_fetchData();
|
||||||
_timer = Timer.periodic(Duration(seconds: 2), (timer) async {
|
_timer = Timer.periodic(const Duration(seconds: 2), (timer) async {
|
||||||
await _fetchData();
|
await _fetchData();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,7 @@ class BookViewerSettingsNotifier extends StateNotifier<BookViewerSettingsModel>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setSavedBrightness() {
|
void setSavedBrightness() {
|
||||||
if (state.screenBrightness != null) {
|
if (state.screenBrightness != null) {
|
||||||
ScreenBrightness().setScreenBrightness(state.screenBrightness!);
|
ScreenBrightness().setScreenBrightness(state.screenBrightness!);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,5 +17,5 @@ class HomeSettingsNotifier extends StateNotifier<HomeSettingsModel> {
|
||||||
ref.read(sharedUtilityProvider).homeSettings = value;
|
ref.read(sharedUtilityProvider).homeSettings = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
update(HomeSettingsModel Function(HomeSettingsModel currentState) value) => state = value(state);
|
HomeSettingsModel update(HomeSettingsModel Function(HomeSettingsModel currentState) value) => state = value(state);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,14 +27,14 @@ class SubtitleSettingsNotifier extends StateNotifier<SubtitleSettingsModel> {
|
||||||
|
|
||||||
void setOutlineColor(Color e) => state = state.copyWith(outlineColor: e);
|
void setOutlineColor(Color e) => state = state.copyWith(outlineColor: e);
|
||||||
|
|
||||||
setOutlineThickness(double value) => state = state.copyWith(outlineSize: value);
|
SubtitleSettingsModel setOutlineThickness(double value) => state = state.copyWith(outlineSize: value);
|
||||||
|
|
||||||
void resetSettings({SubtitleSettingsModel? value}) => state = value ?? const SubtitleSettingsModel();
|
void resetSettings({SubtitleSettingsModel? value}) => state = value ?? const SubtitleSettingsModel();
|
||||||
|
|
||||||
void setFontWeight(FontWeight? value) => state = state.copyWith(fontWeight: value);
|
void setFontWeight(FontWeight? value) => state = state.copyWith(fontWeight: value);
|
||||||
|
|
||||||
setBackGroundOpacity(double value) =>
|
SubtitleSettingsModel setBackGroundOpacity(double value) =>
|
||||||
state = state.copyWith(backGroundColor: state.backGroundColor.withOpacity(value));
|
state = state.copyWith(backGroundColor: state.backGroundColor.withOpacity(value));
|
||||||
|
|
||||||
setShadowIntensity(double value) => state = state.copyWith(shadow: value);
|
SubtitleSettingsModel setShadowIntensity(double value) => state = state.copyWith(shadow: value);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ class VideoPlayerSettingsProviderNotifier extends StateNotifier<VideoPlayerSetti
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setSavedBrightness() {
|
void setSavedBrightness() {
|
||||||
if (state.screenBrightness != null) {
|
if (state.screenBrightness != null) {
|
||||||
ScreenBrightness().setScreenBrightness(state.screenBrightness!);
|
ScreenBrightness().setScreenBrightness(state.screenBrightness!);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,9 @@ FileDownloader backgroundDownloader(BackgroundDownloaderRef ref) {
|
||||||
return FileDownloader()
|
return FileDownloader()
|
||||||
..trackTasks()
|
..trackTasks()
|
||||||
..configureNotification(
|
..configureNotification(
|
||||||
running: TaskNotification('Downloading', 'file: {filename}'),
|
running: const TaskNotification('Downloading', 'file: {filename}'),
|
||||||
complete: TaskNotification('Download finished', 'file: {filename}'),
|
complete: const TaskNotification('Download finished', 'file: {filename}'),
|
||||||
paused: TaskNotification('Download paused', 'file: {filename}'),
|
paused: const TaskNotification('Download paused', 'file: {filename}'),
|
||||||
progressBar: true,
|
progressBar: true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -375,7 +375,7 @@ class SyncNotifier extends StateNotifier<SyncSettingsModel> {
|
||||||
Future<DownloadStream?> syncVideoFile(SyncedItem syncItem, bool skipDownload) async {
|
Future<DownloadStream?> syncVideoFile(SyncedItem syncItem, bool skipDownload) async {
|
||||||
final playbackResponse = await api.itemsItemIdPlaybackInfoPost(
|
final playbackResponse = await api.itemsItemIdPlaybackInfoPost(
|
||||||
itemId: syncItem.id,
|
itemId: syncItem.id,
|
||||||
body: PlaybackInfoDto(
|
body: const PlaybackInfoDto(
|
||||||
enableDirectPlay: true,
|
enableDirectPlay: true,
|
||||||
enableDirectStream: true,
|
enableDirectStream: true,
|
||||||
enableTranscoding: false,
|
enableTranscoding: false,
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ class VideoPlayerNotifier extends StateNotifier<MediaControlsWrapper> {
|
||||||
final lastPosition = ref.read(mediaPlaybackProvider.select((value) => value.lastPosition));
|
final lastPosition = ref.read(mediaPlaybackProvider.select((value) => value.lastPosition));
|
||||||
final diff = (position.inMilliseconds - lastPosition.inMilliseconds).abs();
|
final diff = (position.inMilliseconds - lastPosition.inMilliseconds).abs();
|
||||||
|
|
||||||
if (diff > Duration(seconds: 1, milliseconds: 500).inMilliseconds) {
|
if (diff > const Duration(seconds: 1, milliseconds: 500).inMilliseconds) {
|
||||||
mediaState.update((value) => value.copyWith(
|
mediaState.update((value) => value.copyWith(
|
||||||
position: event,
|
position: event,
|
||||||
playing: player.state.playing,
|
playing: player.state.playing,
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ class BookViewerReader extends ConsumerWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
return Container(
|
return Container(
|
||||||
child: Text("Web not supported."),
|
child: const Text("Web not supported."),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -159,14 +159,14 @@ class _BookViewerScreenState extends ConsumerState<BookViewerScreen> {
|
||||||
),
|
),
|
||||||
} else ...{
|
} else ...{
|
||||||
const SizedBox(height: 32),
|
const SizedBox(height: 32),
|
||||||
Card(
|
const Card(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(16),
|
padding: EdgeInsets.all(16),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Icon(Icons.info_rounded),
|
Icon(Icons.info_rounded),
|
||||||
const SizedBox(width: 16),
|
SizedBox(width: 16),
|
||||||
Text("No next chapter"),
|
Text("No next chapter"),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -211,14 +211,14 @@ class _BookViewerScreenState extends ConsumerState<BookViewerScreen> {
|
||||||
),
|
),
|
||||||
} else ...{
|
} else ...{
|
||||||
const SizedBox(height: 32),
|
const SizedBox(height: 32),
|
||||||
Card(
|
const Card(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(16),
|
padding: EdgeInsets.all(16),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Icon(Icons.info_rounded),
|
Icon(Icons.info_rounded),
|
||||||
const SizedBox(width: 16),
|
SizedBox(width: 16),
|
||||||
Text("First chapter"),
|
Text("First chapter"),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -120,9 +120,9 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
} else if (AdaptiveLayout.of(context).isDesktop)
|
} else if (AdaptiveLayout.of(context).isDesktop)
|
||||||
DefaultSliverTopBadding(),
|
const DefaultSliverTopBadding(),
|
||||||
if (AdaptiveLayout.of(context).isDesktop)
|
if (AdaptiveLayout.of(context).isDesktop)
|
||||||
SliverToBoxAdapter(
|
const SliverToBoxAdapter(
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -191,7 +191,7 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
||||||
posters: view.recentlyAdded,
|
posters: view.recentlyAdded,
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
].whereNotNull().toList().addInBetween(SliverToBoxAdapter(child: SizedBox(height: 16))),
|
].whereNotNull().toList().addInBetween(const SliverToBoxAdapter(child: SizedBox(height: 16))),
|
||||||
const DefautlSliverBottomPadding(),
|
const DefautlSliverBottomPadding(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ class OverviewHeader extends ConsumerWidget {
|
||||||
if (onTitleClicked != null)
|
if (onTitleClicked != null)
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: onTitleClicked,
|
onPressed: onTitleClicked,
|
||||||
icon: Transform.translate(offset: Offset(0, 1.5), child: Icon(Icons.read_more_rounded)))
|
icon: Transform.translate(offset: const Offset(0, 1.5), child: const Icon(Icons.read_more_rounded)))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ class _SeasonDetailScreenState extends ConsumerState<SeasonDetailScreen> {
|
||||||
crossAxisAlignment: WrapCrossAlignment.center,
|
crossAxisAlignment: WrapCrossAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
ConstrainedBox(
|
ConstrainedBox(
|
||||||
constraints: BoxConstraints(
|
constraints: const BoxConstraints(
|
||||||
maxWidth: 600,
|
maxWidth: 600,
|
||||||
),
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
|
|
@ -86,7 +86,7 @@ class _SeasonDetailScreenState extends ConsumerState<SeasonDetailScreen> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ConstrainedBox(
|
ConstrainedBox(
|
||||||
constraints: BoxConstraints(maxWidth: 300),
|
constraints: const BoxConstraints(maxWidth: 300),
|
||||||
child: Card(child: FladderImage(image: details.getPosters?.primary))),
|
child: Card(child: FladderImage(image: details.getPosters?.primary))),
|
||||||
],
|
],
|
||||||
).padding(padding),
|
).padding(padding),
|
||||||
|
|
@ -122,7 +122,7 @@ class _SeasonDetailScreenState extends ConsumerState<SeasonDetailScreen> {
|
||||||
Card(
|
Card(
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(200)),
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(200)),
|
||||||
child: SegmentedButton(
|
child: SegmentedButton(
|
||||||
style: ButtonStyle(
|
style: const ButtonStyle(
|
||||||
elevation: WidgetStatePropertyAll(5),
|
elevation: WidgetStatePropertyAll(5),
|
||||||
side: WidgetStatePropertyAll(BorderSide.none),
|
side: WidgetStatePropertyAll(BorderSide.none),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ class FavouritesScreen extends ConsumerWidget {
|
||||||
else
|
else
|
||||||
const DefaultSliverTopBadding(),
|
const DefaultSliverTopBadding(),
|
||||||
if (AdaptiveLayout.of(context).isDesktop)
|
if (AdaptiveLayout.of(context).isDesktop)
|
||||||
SliverToBoxAdapter(
|
const SliverToBoxAdapter(
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,7 @@ class _LibrarySearchScreenState extends ConsumerState<LibrarySearchScreen> {
|
||||||
floatingActionButtonLocation:
|
floatingActionButtonLocation:
|
||||||
playerState == VideoPlayerState.minimized ? FloatingActionButtonLocation.centerFloat : null,
|
playerState == VideoPlayerState.minimized ? FloatingActionButtonLocation.centerFloat : null,
|
||||||
floatingActionButton: switch (playerState) {
|
floatingActionButton: switch (playerState) {
|
||||||
VideoPlayerState.minimized => Padding(
|
VideoPlayerState.minimized => const Padding(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||||
child: FloatingPlayerBar(),
|
child: FloatingPlayerBar(),
|
||||||
),
|
),
|
||||||
|
|
@ -171,7 +171,7 @@ class _LibrarySearchScreenState extends ConsumerState<LibrarySearchScreen> {
|
||||||
label: Text(context.localized.viewPhotos),
|
label: Text(context.localized.viewPhotos),
|
||||||
icon: const Icon(IconsaxBold.gallery),
|
icon: const Icon(IconsaxBold.gallery),
|
||||||
)
|
)
|
||||||
].addInBetween(SizedBox(height: 10)),
|
].addInBetween(const SizedBox(height: 10)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
@ -251,12 +251,12 @@ class _LibrarySearchScreenState extends ConsumerState<LibrarySearchScreen> {
|
||||||
[];
|
[];
|
||||||
final itemCountWidget = ItemActionButton(
|
final itemCountWidget = ItemActionButton(
|
||||||
label: Text(context.localized.itemCount(librarySearchResults.totalItemCount)),
|
label: Text(context.localized.itemCount(librarySearchResults.totalItemCount)),
|
||||||
icon: Icon(IconsaxBold.document_1),
|
icon: const Icon(IconsaxBold.document_1),
|
||||||
);
|
);
|
||||||
final refreshAction = ItemActionButton(
|
final refreshAction = ItemActionButton(
|
||||||
label: Text(context.localized.forceRefresh),
|
label: Text(context.localized.forceRefresh),
|
||||||
action: () => refreshKey.currentState?.show(),
|
action: () => refreshKey.currentState?.show(),
|
||||||
icon: Icon(IconsaxOutline.refresh),
|
icon: const Icon(IconsaxOutline.refresh),
|
||||||
);
|
);
|
||||||
final itemViewAction = ItemActionButton(
|
final itemViewAction = ItemActionButton(
|
||||||
label: Text(context.localized.selectViewType),
|
label: Text(context.localized.selectViewType),
|
||||||
|
|
@ -279,7 +279,7 @@ class _LibrarySearchScreenState extends ConsumerState<LibrarySearchScreen> {
|
||||||
.map(
|
.map(
|
||||||
(e) => FilledButton.tonal(
|
(e) => FilledButton.tonal(
|
||||||
style: FilledButtonTheme.of(context).style?.copyWith(
|
style: FilledButtonTheme.of(context).style?.copyWith(
|
||||||
padding: WidgetStatePropertyAll(
|
padding: const WidgetStatePropertyAll(
|
||||||
EdgeInsets.symmetric(
|
EdgeInsets.symmetric(
|
||||||
horizontal: 12, vertical: 24)),
|
horizontal: 12, vertical: 24)),
|
||||||
backgroundColor: WidgetStateProperty.resolveWith(
|
backgroundColor: WidgetStateProperty.resolveWith(
|
||||||
|
|
@ -373,7 +373,7 @@ class _LibrarySearchScreenState extends ConsumerState<LibrarySearchScreen> {
|
||||||
}),
|
}),
|
||||||
if (AdaptiveLayout.of(context).layout == LayoutState.phone) ...[
|
if (AdaptiveLayout.of(context).layout == LayoutState.phone) ...[
|
||||||
const SizedBox(width: 6),
|
const SizedBox(width: 6),
|
||||||
SizedBox.square(dimension: 46, child: SettingsUserIcon()),
|
const SizedBox.square(dimension: 46, child: SettingsUserIcon()),
|
||||||
],
|
],
|
||||||
const SizedBox(width: 12)
|
const SizedBox(width: 12)
|
||||||
],
|
],
|
||||||
|
|
@ -421,7 +421,7 @@ class _LibrarySearchScreenState extends ConsumerState<LibrarySearchScreen> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Row(),
|
const Row(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -429,7 +429,7 @@ class _LibrarySearchScreenState extends ConsumerState<LibrarySearchScreen> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (AdaptiveLayout.of(context).isDesktop)
|
if (AdaptiveLayout.of(context).isDesktop)
|
||||||
SliverToBoxAdapter(
|
const SliverToBoxAdapter(
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -476,15 +476,15 @@ class _LibrarySearchScreenState extends ConsumerState<LibrarySearchScreen> {
|
||||||
borderRadius: BorderRadius.circular(16),
|
borderRadius: BorderRadius.circular(16),
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
CircularProgressIndicator.adaptive(),
|
const CircularProgressIndicator.adaptive(),
|
||||||
Text(context.localized.fetchingLibrary, style: Theme.of(context).textTheme.titleMedium),
|
Text(context.localized.fetchingLibrary, style: Theme.of(context).textTheme.titleMedium),
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () => libraryProvider.cancelFetch(),
|
onPressed: () => libraryProvider.cancelFetch(),
|
||||||
icon: Icon(IconsaxOutline.close_square),
|
icon: const Icon(IconsaxOutline.close_square),
|
||||||
)
|
)
|
||||||
].addInBetween(const SizedBox(width: 16)),
|
].addInBetween(const SizedBox(width: 16)),
|
||||||
),
|
),
|
||||||
|
|
@ -598,7 +598,7 @@ class _LibrarySearchBottomBar extends ConsumerWidget {
|
||||||
if (context.mounted) context.refreshData();
|
if (context.mounted) context.refreshData();
|
||||||
},
|
},
|
||||||
label: Text(context.localized.addToCollection),
|
label: Text(context.localized.addToCollection),
|
||||||
icon: Icon(
|
icon: const Icon(
|
||||||
IconsaxOutline.save_add,
|
IconsaxOutline.save_add,
|
||||||
size: 20,
|
size: 20,
|
||||||
),
|
),
|
||||||
|
|
@ -726,7 +726,7 @@ class _LibrarySearchBottomBar extends ConsumerWidget {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
icon: Icon(IconsaxOutline.more))
|
icon: const Icon(IconsaxOutline.more))
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -775,7 +775,7 @@ class _LibrarySearchBottomBar extends ConsumerWidget {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
if (AdaptiveLayout.of(context).isDesktop) SizedBox(height: 8),
|
if (AdaptiveLayout.of(context).isDesktop) const SizedBox(height: 8),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ class LibraryViews extends ConsumerWidget {
|
||||||
if (ref.watch(librarySearchProvider(key!).select((value) => value.nestedCurrentItem is BoxSetModel))) ...{
|
if (ref.watch(librarySearchProvider(key!).select((value) => value.nestedCurrentItem is BoxSetModel))) ...{
|
||||||
ItemActionButton(
|
ItemActionButton(
|
||||||
label: Text(context.localized.removeFromCollection),
|
label: Text(context.localized.removeFromCollection),
|
||||||
icon: Icon(IconsaxOutline.archive_slash),
|
icon: const Icon(IconsaxOutline.archive_slash),
|
||||||
action: () async {
|
action: () async {
|
||||||
await libraryProvider.removeFromCollection(items: [item]);
|
await libraryProvider.removeFromCollection(items: [item]);
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
|
|
@ -93,7 +93,7 @@ class LibraryViews extends ConsumerWidget {
|
||||||
if (ref.watch(librarySearchProvider(key!).select((value) => value.nestedCurrentItem is PlaylistModel))) ...{
|
if (ref.watch(librarySearchProvider(key!).select((value) => value.nestedCurrentItem is PlaylistModel))) ...{
|
||||||
ItemActionButton(
|
ItemActionButton(
|
||||||
label: Text(context.localized.removeFromPlaylist),
|
label: Text(context.localized.removeFromPlaylist),
|
||||||
icon: Icon(IconsaxOutline.archive_minus),
|
icon: const Icon(IconsaxOutline.archive_minus),
|
||||||
action: () async {
|
action: () async {
|
||||||
await libraryProvider.removeFromPlaylist(items: [item]);
|
await libraryProvider.removeFromPlaylist(items: [item]);
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
|
|
|
||||||
|
|
@ -98,8 +98,8 @@ class _SearchBarState extends ConsumerState<SuggestionSearchBar> {
|
||||||
},
|
},
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: widget.title ?? "${context.localized.search}...",
|
hintText: widget.title ?? "${context.localized.search}...",
|
||||||
prefixIcon: Icon(IconsaxOutline.search_normal),
|
prefixIcon: const Icon(IconsaxOutline.search_normal),
|
||||||
contentPadding: EdgeInsets.only(top: 13),
|
contentPadding: const EdgeInsets.only(top: 13),
|
||||||
suffixIcon: controller.text.isNotEmpty
|
suffixIcon: controller.text.isNotEmpty
|
||||||
? IconButton(
|
? IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,7 @@ class _LockScreenState extends ConsumerState<LockScreen> with WidgetsBindingObse
|
||||||
size: 38,
|
size: 38,
|
||||||
),
|
),
|
||||||
ConstrainedBox(
|
ConstrainedBox(
|
||||||
constraints: BoxConstraints(
|
constraints: const BoxConstraints(
|
||||||
maxHeight: 400,
|
maxHeight: 400,
|
||||||
maxWidth: 400,
|
maxWidth: 400,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ class LoginEditUser extends ConsumerWidget {
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Icon(IconsaxBold.clock),
|
const Icon(IconsaxBold.clock),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
Column(
|
Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
|
|
||||||
|
|
@ -79,13 +79,13 @@ class _LoginPageState extends ConsumerState<LoginScreen> {
|
||||||
children: [
|
children: [
|
||||||
if (!AdaptiveLayout.of(context).isDesktop)
|
if (!AdaptiveLayout.of(context).isDesktop)
|
||||||
FloatingActionButton(
|
FloatingActionButton(
|
||||||
key: Key("edit_button"),
|
key: const Key("edit_button"),
|
||||||
child: Icon(IconsaxOutline.edit_2),
|
child: const Icon(IconsaxOutline.edit_2),
|
||||||
onPressed: () => setState(() => editingUsers = !editingUsers),
|
onPressed: () => setState(() => editingUsers = !editingUsers),
|
||||||
),
|
),
|
||||||
FloatingActionButton(
|
FloatingActionButton(
|
||||||
key: Key("new_button"),
|
key: const Key("new_button"),
|
||||||
child: Icon(IconsaxOutline.add_square),
|
child: const Icon(IconsaxOutline.add_square),
|
||||||
onPressed: startAddingNewUser,
|
onPressed: startAddingNewUser,
|
||||||
),
|
),
|
||||||
].addInBetween(const SizedBox(width: 16)),
|
].addInBetween(const SizedBox(width: 16)),
|
||||||
|
|
@ -98,7 +98,7 @@ class _LoginPageState extends ConsumerState<LoginScreen> {
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 32),
|
padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 32),
|
||||||
children: [
|
children: [
|
||||||
Center(
|
const Center(
|
||||||
child: FladderLogo(),
|
child: FladderLogo(),
|
||||||
),
|
),
|
||||||
AnimatedFadeSize(
|
AnimatedFadeSize(
|
||||||
|
|
@ -369,7 +369,7 @@ class _LoginPageState extends ConsumerState<LoginScreen> {
|
||||||
children: [
|
children: [
|
||||||
Text(context.localized.login),
|
Text(context.localized.login),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
Icon(IconsaxBold.send_1),
|
const Icon(IconsaxBold.send_1),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -88,16 +88,16 @@ class LoginUserGrid extends ConsumerWidget {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
].addInBetween(SizedBox(width: 4, height: 4)),
|
].addInBetween(const SizedBox(width: 4, height: 4)),
|
||||||
),
|
),
|
||||||
if (editMode)
|
if (editMode)
|
||||||
Align(
|
Align(
|
||||||
alignment: Alignment.topRight,
|
alignment: Alignment.topRight,
|
||||||
child: Card(
|
child: Card(
|
||||||
color: Theme.of(context).colorScheme.errorContainer,
|
color: Theme.of(context).colorScheme.errorContainer,
|
||||||
child: Padding(
|
child: const Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: EdgeInsets.all(8.0),
|
||||||
child: const Icon(
|
child: Icon(
|
||||||
IconsaxBold.edit_2,
|
IconsaxBold.edit_2,
|
||||||
size: 14,
|
size: 14,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ class DiscoverServersWidget extends ConsumerWidget {
|
||||||
style: context.textTheme.bodyLarge,
|
style: context.textTheme.bodyLarge,
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
Opacity(opacity: 0.65, child: Icon(IconsaxOutline.bookmark, size: 16)),
|
const Opacity(opacity: 0.65, child: Icon(IconsaxOutline.bookmark, size: 16)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
|
|
@ -63,7 +63,7 @@ class DiscoverServersWidget extends ConsumerWidget {
|
||||||
style: context.textTheme.bodyLarge,
|
style: context.textTheme.bodyLarge,
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
Opacity(opacity: 0.65, child: Icon(IconsaxBold.airdrop, size: 16)),
|
const Opacity(opacity: 0.65, child: Icon(IconsaxBold.airdrop, size: 16)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
|
|
@ -92,7 +92,7 @@ class DiscoverServersWidget extends ConsumerWidget {
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
error: (error, stackTrace) => Text(context.localized.error),
|
error: (error, stackTrace) => Text(context.localized.error),
|
||||||
loading: () => Center(
|
loading: () => const Center(
|
||||||
child: SizedBox.square(
|
child: SizedBox.square(
|
||||||
dimension: 24.0,
|
dimension: 24.0,
|
||||||
child: CircularProgressIndicator.adaptive(strokeCap: StrokeCap.round),
|
child: CircularProgressIndicator.adaptive(strokeCap: StrokeCap.round),
|
||||||
|
|
@ -151,7 +151,7 @@ class _ServerInfoCard extends StatelessWidget {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Icon(IconsaxOutline.edit_2, size: 16)
|
const Icon(IconsaxOutline.edit_2, size: 16)
|
||||||
].addInBetween(const SizedBox(width: 12)),
|
].addInBetween(const SizedBox(width: 12)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ class LoginIcon extends ConsumerWidget {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
].addInBetween(SizedBox(width: 8, height: 8)),
|
].addInBetween(const SizedBox(width: 8, height: 8)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
FlatButton(
|
FlatButton(
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ Future<ItemBaseModel?> showEditItemPopup(
|
||||||
);
|
);
|
||||||
return AdaptiveLayout.of(context).inputDevice == InputDevice.pointer
|
return AdaptiveLayout.of(context).inputDevice == InputDevice.pointer
|
||||||
? Dialog(
|
? Dialog(
|
||||||
insetPadding: EdgeInsets.all(64),
|
insetPadding: const EdgeInsets.all(64),
|
||||||
child: editWidget(),
|
child: editWidget(),
|
||||||
)
|
)
|
||||||
: Dialog.fullscreen(
|
: Dialog.fullscreen(
|
||||||
|
|
@ -75,11 +75,11 @@ class _EditDialogSwitcherState extends ConsumerState<EditDialogSwitcher> with Ti
|
||||||
final advancedFields = ref.watch(editItemProvider.notifier).advancedFields ?? {};
|
final advancedFields = ref.watch(editItemProvider.notifier).advancedFields ?? {};
|
||||||
|
|
||||||
Map<Tab, Widget> widgets = {
|
Map<Tab, Widget> widgets = {
|
||||||
Tab(text: "General"): EditFields(fields: generalFields, json: state),
|
const Tab(text: "General"): EditFields(fields: generalFields, json: state),
|
||||||
Tab(text: "Primary"): EditImageContent(type: ImageType.primary),
|
const Tab(text: "Primary"): const EditImageContent(type: ImageType.primary),
|
||||||
Tab(text: "Logo"): EditImageContent(type: ImageType.logo),
|
const Tab(text: "Logo"): const EditImageContent(type: ImageType.logo),
|
||||||
Tab(text: "Backdrops"): EditImageContent(type: ImageType.backdrop),
|
const Tab(text: "Backdrops"): const EditImageContent(type: ImageType.backdrop),
|
||||||
Tab(text: "Advanced"): EditFields(fields: advancedFields, json: state),
|
const Tab(text: "Advanced"): EditFields(fields: advancedFields, json: state),
|
||||||
};
|
};
|
||||||
|
|
||||||
return Card(
|
return Card(
|
||||||
|
|
@ -103,7 +103,7 @@ class _EditDialogSwitcherState extends ConsumerState<EditDialogSwitcher> with Ti
|
||||||
style: Theme.of(context).textTheme.titleLarge,
|
style: Theme.of(context).textTheme.titleLarge,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
IconButton(onPressed: () => refreshEditor(), icon: Icon(IconsaxOutline.refresh))
|
IconButton(onPressed: () => refreshEditor(), icon: const Icon(IconsaxOutline.refresh))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ class _EditGeneralState extends ConsumerState<EditFields> {
|
||||||
children: [
|
children: [
|
||||||
Flexible(
|
Flexible(
|
||||||
child: ListView(
|
child: ListView(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 16),
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
children: [
|
children: [
|
||||||
if (widget.json != null)
|
if (widget.json != null)
|
||||||
|
|
@ -64,7 +64,7 @@ class _EditGeneralState extends ConsumerState<EditFields> {
|
||||||
current: map.entries.firstWhereOrNull((element) => element.value == true)?.key ?? "",
|
current: map.entries.firstWhereOrNull((element) => element.value == true)?.key ?? "",
|
||||||
itemBuilder: (context) => [
|
itemBuilder: (context) => [
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
child: Text(""),
|
child: const Text(""),
|
||||||
onTap: () => ref.read(editItemProvider.notifier).updateField(MapEntry(e.key, "")),
|
onTap: () => ref.read(editItemProvider.notifier).updateField(MapEntry(e.key, "")),
|
||||||
),
|
),
|
||||||
...map.entries.map(
|
...map.entries.map(
|
||||||
|
|
@ -119,7 +119,7 @@ class _EditGeneralState extends ConsumerState<EditFields> {
|
||||||
onPressed: () => ref.read(editItemProvider.notifier).updateField(
|
onPressed: () => ref.read(editItemProvider.notifier).updateField(
|
||||||
MapEntry(e.key, list..remove(genre)),
|
MapEntry(e.key, list..remove(genre)),
|
||||||
),
|
),
|
||||||
icon: Icon(Icons.remove_rounded))
|
icon: const Icon(Icons.remove_rounded))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -217,7 +217,7 @@ class _EditGeneralState extends ConsumerState<EditFields> {
|
||||||
ref.read(editItemProvider.notifier).updateField(
|
ref.read(editItemProvider.notifier).updateField(
|
||||||
MapEntry(e.key, listToMap(list..remove(person))));
|
MapEntry(e.key, listToMap(list..remove(person))));
|
||||||
},
|
},
|
||||||
icon: Icon(Icons.remove_rounded))
|
icon: const Icon(Icons.remove_rounded))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -272,7 +272,7 @@ class _EditGeneralState extends ConsumerState<EditFields> {
|
||||||
personRole.text = "";
|
personRole.text = "";
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
icon: Icon(Icons.add_rounded),
|
icon: const Icon(Icons.add_rounded),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -326,7 +326,7 @@ class _EditGeneralState extends ConsumerState<EditFields> {
|
||||||
message: "Open in browser",
|
message: "Open in browser",
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
onPressed: () => launchUrl(context, externalUrl.url),
|
onPressed: () => launchUrl(context, externalUrl.url),
|
||||||
icon: Icon(Icons.open_in_browser_rounded)),
|
icon: const Icon(Icons.open_in_browser_rounded)),
|
||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
|
@ -338,7 +338,7 @@ class _EditGeneralState extends ConsumerState<EditFields> {
|
||||||
.toList()),
|
.toList()),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
icon: Icon(Icons.remove_rounded))
|
icon: const Icon(Icons.remove_rounded))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -371,7 +371,7 @@ class _EditGeneralState extends ConsumerState<EditFields> {
|
||||||
.toList()),
|
.toList()),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
icon: Icon(Icons.add_rounded),
|
icon: const Icon(Icons.add_rounded),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -429,7 +429,7 @@ class _EditGeneralState extends ConsumerState<EditFields> {
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () => setMapping(list..remove(studio)),
|
onPressed: () => setMapping(list..remove(studio)),
|
||||||
icon: Icon(Icons.remove_rounded))
|
icon: const Icon(Icons.remove_rounded))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -557,7 +557,7 @@ class _EditGeneralState extends ConsumerState<EditFields> {
|
||||||
.read(editItemProvider.notifier)
|
.read(editItemProvider.notifier)
|
||||||
.updateField(MapEntry(e.key, newDate.toIso8601String()));
|
.updateField(MapEntry(e.key, newDate.toIso8601String()));
|
||||||
},
|
},
|
||||||
icon: Icon(IconsaxOutline.calendar_2))
|
icon: const Icon(IconsaxOutline.calendar_2))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
DisplayOrder _ => Builder(builder: (context) {
|
DisplayOrder _ => Builder(builder: (context) {
|
||||||
|
|
@ -580,8 +580,8 @@ class _EditGeneralState extends ConsumerState<EditFields> {
|
||||||
.toList(),
|
.toList(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
const Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||||
child: Text("Order episodes by air date, DVD order, or absolute numbering."),
|
child: Text("Order episodes by air date, DVD order, or absolute numbering."),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|
@ -656,7 +656,7 @@ class _EditGeneralState extends ConsumerState<EditFields> {
|
||||||
children: [
|
children: [
|
||||||
Text(keyLabel, style: Theme.of(context).textTheme.titleLarge),
|
Text(keyLabel, style: Theme.of(context).textTheme.titleLarge),
|
||||||
const SizedBox(height: 6),
|
const SizedBox(height: 6),
|
||||||
Text(
|
const Text(
|
||||||
"Uncheck a field to lock it and prevent its data from being changed.",
|
"Uncheck a field to lock it and prevent its data from being changed.",
|
||||||
),
|
),
|
||||||
const SizedBox(height: 6),
|
const SizedBox(height: 6),
|
||||||
|
|
@ -722,8 +722,8 @@ class _EditGeneralState extends ConsumerState<EditFields> {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
Padding(
|
const Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: EdgeInsets.all(8.0),
|
||||||
child: Center(
|
child: Center(
|
||||||
child: CircularProgressIndicator.adaptive(strokeCap: StrokeCap.round),
|
child: CircularProgressIndicator.adaptive(strokeCap: StrokeCap.round),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ class _EditImageContentState extends ConsumerState<EditImageContent> {
|
||||||
Align(
|
Align(
|
||||||
alignment: Alignment.bottomRight,
|
alignment: Alignment.bottomRight,
|
||||||
child: Transform.translate(
|
child: Transform.translate(
|
||||||
offset: Offset(2, 2),
|
offset: const Offset(2, 2),
|
||||||
child: IconButton.filledTonal(
|
child: IconButton.filledTonal(
|
||||||
style: FilledButton.styleFrom(
|
style: FilledButton.styleFrom(
|
||||||
backgroundColor: Theme.of(context).colorScheme.error,
|
backgroundColor: Theme.of(context).colorScheme.error,
|
||||||
|
|
@ -115,10 +115,10 @@ class _EditImageContentState extends ConsumerState<EditImageContent> {
|
||||||
await showDialog(
|
await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog.adaptive(
|
builder: (context) => AlertDialog.adaptive(
|
||||||
title: Text("Delete image"),
|
title: const Text("Delete image"),
|
||||||
content: Text("Deleting is permanent are you sure?"),
|
content: const Text("Deleting is permanent are you sure?"),
|
||||||
actions: [
|
actions: [
|
||||||
ElevatedButton(onPressed: () => Navigator.of(context).pop(), child: Text("Cancel")),
|
ElevatedButton(onPressed: () => Navigator.of(context).pop(), child: const Text("Cancel")),
|
||||||
FilledButton(
|
FilledButton(
|
||||||
style: FilledButton.styleFrom(
|
style: FilledButton.styleFrom(
|
||||||
backgroundColor: Theme.of(context).colorScheme.error,
|
backgroundColor: Theme.of(context).colorScheme.error,
|
||||||
|
|
@ -128,7 +128,7 @@ class _EditImageContentState extends ConsumerState<EditImageContent> {
|
||||||
await ref.read(editItemProvider.notifier).deleteImage(widget.type, image);
|
await ref.read(editItemProvider.notifier).deleteImage(widget.type, image);
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: Text(
|
child: const Text(
|
||||||
"Delete",
|
"Delete",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
@ -136,7 +136,7 @@ class _EditImageContentState extends ConsumerState<EditImageContent> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
icon: Icon(Icons.delete_rounded),
|
icon: const Icon(Icons.delete_rounded),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
@ -208,7 +208,7 @@ class _EditImageContentState extends ConsumerState<EditImageContent> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SettingsListTile(
|
SettingsListTile(
|
||||||
label: Text("Include all languages"),
|
label: const Text("Include all languages"),
|
||||||
trailing: Switch.adaptive(
|
trailing: Switch.adaptive(
|
||||||
value: includeAllImages,
|
value: includeAllImages,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
|
|
@ -231,7 +231,7 @@ class _EditImageContentState extends ConsumerState<EditImageContent> {
|
||||||
),
|
),
|
||||||
children: [...serverImageCards, ...imageCards],
|
children: [...serverImageCards, ...imageCards],
|
||||||
),
|
),
|
||||||
if (loading) Center(child: CircularProgressIndicator.adaptive(strokeCap: StrokeCap.round)),
|
if (loading) const Center(child: CircularProgressIndicator.adaptive(strokeCap: StrokeCap.round)),
|
||||||
if (!loading && [...serverImageCards, ...imageCards].isEmpty)
|
if (!loading && [...serverImageCards, ...imageCards].isEmpty)
|
||||||
Center(child: Text("No ${widget.type.value}s found"))
|
Center(child: Text("No ${widget.type.value}s found"))
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ class _IdentifyScreenState extends ConsumerState<IdentifyScreen> with TickerProv
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () async => await ref.read(provider.notifier).fetchInformation(),
|
onPressed: () async => await ref.read(provider.notifier).fetchInformation(),
|
||||||
icon: Icon(IconsaxOutline.refresh)),
|
icon: const Icon(IconsaxOutline.refresh)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -106,7 +106,7 @@ class _IdentifyScreenState extends ConsumerState<IdentifyScreen> with TickerProv
|
||||||
if (posters.isEmpty)
|
if (posters.isEmpty)
|
||||||
Center(
|
Center(
|
||||||
child: processing
|
child: processing
|
||||||
? CircularProgressIndicator.adaptive(strokeCap: StrokeCap.round)
|
? const CircularProgressIndicator.adaptive(strokeCap: StrokeCap.round)
|
||||||
: Text(context.localized.noResults),
|
: Text(context.localized.noResults),
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
|
|
@ -181,7 +181,7 @@ class _IdentifyScreenState extends ConsumerState<IdentifyScreen> with TickerProv
|
||||||
|
|
||||||
launchUrl(context, url ?? "");
|
launchUrl(context, url ?? "");
|
||||||
},
|
},
|
||||||
icon: Icon(Icons.launch_rounded)),
|
icon: const Icon(Icons.launch_rounded)),
|
||||||
),
|
),
|
||||||
Tooltip(
|
Tooltip(
|
||||||
message: "Select result",
|
message: "Select result",
|
||||||
|
|
@ -202,7 +202,7 @@ class _IdentifyScreenState extends ConsumerState<IdentifyScreen> with TickerProv
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
icon: Icon(Icons.save_alt_rounded),
|
icon: const Icon(Icons.save_alt_rounded),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,7 @@ class ItemInfoScreenState extends ConsumerState<ItemInfoScreen> {
|
||||||
style: Theme.of(context).textTheme.titleLarge,
|
style: Theme.of(context).textTheme.titleLarge,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Opacity(opacity: 0.3, child: const Divider()),
|
const Opacity(opacity: 0.3, child: Divider()),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Row(
|
child: Row(
|
||||||
|
|
|
||||||
|
|
@ -214,13 +214,13 @@ class _PhotoViewerControllsState extends ConsumerState<PhotoViewerControls> with
|
||||||
?.copyWith(fontWeight: FontWeight.bold),
|
?.copyWith(fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
if (widget.loadingMoreItems)
|
if (widget.loadingMoreItems)
|
||||||
SizedBox.square(
|
const SizedBox.square(
|
||||||
dimension: 16,
|
dimension: 16,
|
||||||
child: CircularProgressIndicator.adaptive(
|
child: CircularProgressIndicator.adaptive(
|
||||||
strokeCap: StrokeCap.round,
|
strokeCap: StrokeCap.round,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
].addInBetween(SizedBox(width: 6)),
|
].addInBetween(const SizedBox(width: 6)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Positioned.fill(
|
Positioned.fill(
|
||||||
|
|
@ -301,7 +301,7 @@ class _PhotoViewerControllsState extends ConsumerState<PhotoViewerControls> with
|
||||||
onPressed: widget.openOptions,
|
onPressed: widget.openOptions,
|
||||||
icon: IconsaxOutline.more_2,
|
icon: IconsaxOutline.more_2,
|
||||||
),
|
),
|
||||||
Spacer(),
|
const Spacer(),
|
||||||
ElevatedIconButton(
|
ElevatedIconButton(
|
||||||
onPressed: markAsFavourite,
|
onPressed: markAsFavourite,
|
||||||
color: widget.photo.userData.isFavourite ? Colors.red : null,
|
color: widget.photo.userData.isFavourite ? Colors.red : null,
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,7 @@ class _PhotoViewerScreenState extends ConsumerState<PhotoViewerScreen> with Widg
|
||||||
onExit: (event) => setState(() => _showOverlay(show: false)),
|
onExit: (event) => setState(() => _showOverlay(show: false)),
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
appBar: photos.isEmpty
|
appBar: photos.isEmpty
|
||||||
? FladderAppbar(
|
? const FladderAppbar(
|
||||||
automaticallyImplyLeading: true,
|
automaticallyImplyLeading: true,
|
||||||
)
|
)
|
||||||
: null,
|
: null,
|
||||||
|
|
@ -242,7 +242,7 @@ class _PhotoViewerScreenState extends ConsumerState<PhotoViewerScreen> with Widg
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
switch (state.extendedImageLoadState) {
|
switch (state.extendedImageLoadState) {
|
||||||
LoadState.loading => Center(
|
LoadState.loading => const Center(
|
||||||
child: CircularProgressIndicator.adaptive(strokeCap: StrokeCap.round),
|
child: CircularProgressIndicator.adaptive(strokeCap: StrokeCap.round),
|
||||||
),
|
),
|
||||||
LoadState.completed => switch (photo.internalType) {
|
LoadState.completed => switch (photo.internalType) {
|
||||||
|
|
@ -256,7 +256,7 @@ class _PhotoViewerScreenState extends ConsumerState<PhotoViewerScreen> with Widg
|
||||||
LoadState.failed || _ => Align(
|
LoadState.failed || _ => Align(
|
||||||
alignment: Alignment.topRight,
|
alignment: Alignment.topRight,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.all(24).copyWith(top: topPadding + 85),
|
padding: const EdgeInsets.all(24).copyWith(top: topPadding + 85),
|
||||||
child: Card(
|
child: Card(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(24),
|
padding: const EdgeInsets.all(24),
|
||||||
|
|
@ -426,7 +426,7 @@ class _PhotoViewerScreenState extends ConsumerState<PhotoViewerScreen> with Widg
|
||||||
controller: scrollController,
|
controller: scrollController,
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 12),
|
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
child: Consumer(builder: (context, ref, child) {
|
child: Consumer(builder: (context, ref, child) {
|
||||||
|
|
@ -474,7 +474,7 @@ class _PhotoViewerScreenState extends ConsumerState<PhotoViewerScreen> with Widg
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Divider(),
|
const Divider(),
|
||||||
...currentPhoto
|
...currentPhoto
|
||||||
.generateActions(
|
.generateActions(
|
||||||
context,
|
context,
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ class _ClientSettingsPageState extends ConsumerState<ClientSettingsPage> {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
icon: Icon(IconsaxOutline.folder_minus),
|
icon: const Icon(IconsaxOutline.folder_minus),
|
||||||
)
|
)
|
||||||
: null,
|
: null,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
Future<void> openQuickConnectDialog(
|
Future<void> openQuickConnectDialog(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
) async {
|
) async {
|
||||||
return showDialog(context: context, builder: (context) => QuickConnectDialog());
|
return showDialog(context: context, builder: (context) => const QuickConnectDialog());
|
||||||
}
|
}
|
||||||
|
|
||||||
class QuickConnectDialog extends ConsumerStatefulWidget {
|
class QuickConnectDialog extends ConsumerStatefulWidget {
|
||||||
|
|
@ -90,7 +90,7 @@ class _QuickConnectDialogState extends ConsumerState<QuickConnectDialog> {
|
||||||
success = context.localized.loggedIn;
|
success = context.localized.loggedIn;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
await Future.delayed(Duration(seconds: 2));
|
await Future.delayed(const Duration(seconds: 2));
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
} else {
|
} else {
|
||||||
if (controller.text.isEmpty) {
|
if (controller.text.isEmpty) {
|
||||||
|
|
@ -106,7 +106,7 @@ class _QuickConnectDialogState extends ConsumerState<QuickConnectDialog> {
|
||||||
controller.text = "";
|
controller.text = "";
|
||||||
},
|
},
|
||||||
child: loading
|
child: loading
|
||||||
? SizedBox.square(
|
? const SizedBox.square(
|
||||||
child: CircularProgressIndicator(),
|
child: CircularProgressIndicator(),
|
||||||
dimension: 16.0,
|
dimension: 16.0,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
|
||||||
},
|
},
|
||||||
icon: Padding(
|
icon: Padding(
|
||||||
padding: EdgeInsets.all(AdaptiveLayout.of(context).inputDevice == InputDevice.pointer ? 0 : 4),
|
padding: EdgeInsets.all(AdaptiveLayout.of(context).inputDevice == InputDevice.pointer ? 0 : 4),
|
||||||
child: Icon(IconsaxOutline.arrow_left_2),
|
child: const Icon(IconsaxOutline.arrow_left_2),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -126,7 +126,7 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
|
||||||
),
|
),
|
||||||
SettingsListTile(
|
SettingsListTile(
|
||||||
label: Text(context.localized.about),
|
label: Text(context.localized.about),
|
||||||
subLabel: Text("Fladder"),
|
subLabel: const Text("Fladder"),
|
||||||
suffix: Opacity(
|
suffix: Opacity(
|
||||||
opacity: 1,
|
opacity: 1,
|
||||||
child: FladderIconOutlined(
|
child: FladderIconOutlined(
|
||||||
|
|
@ -135,7 +135,7 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
|
||||||
)),
|
)),
|
||||||
onTap: () => showAboutDialog(
|
onTap: () => showAboutDialog(
|
||||||
context: context,
|
context: context,
|
||||||
applicationIcon: FladderIcon(size: 85),
|
applicationIcon: const FladderIcon(size: 85),
|
||||||
applicationVersion: ref.watch(applicationInfoProvider).versionAndPlatform,
|
applicationVersion: ref.watch(applicationInfoProvider).versionAndPlatform,
|
||||||
applicationLegalese: "Donut Factory",
|
applicationLegalese: "Donut Factory",
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import 'package:fladder/util/list_padding.dart';
|
||||||
import 'package:fladder/util/localization_helper.dart';
|
import 'package:fladder/util/localization_helper.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
showAuthOptionsDialogue(
|
void showAuthOptionsDialogue(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
AccountModel currentUser,
|
AccountModel currentUser,
|
||||||
Function(AccountModel) setMethod,
|
Function(AccountModel) setMethod,
|
||||||
|
|
|
||||||
|
|
@ -225,7 +225,7 @@ class _CategoryChipEditorState<T> extends State<CategoryChipEditor<T>> {
|
||||||
onChanged: (value) => updateKey(MapEntry(element.key, value == null ? null : element.value)),
|
onChanged: (value) => updateKey(MapEntry(element.key, value == null ? null : element.value)),
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
Divider(),
|
const Divider(),
|
||||||
},
|
},
|
||||||
...otherItems.mapIndexed((index, element) {
|
...otherItems.mapIndexed((index, element) {
|
||||||
return CheckboxListTile.adaptive(
|
return CheckboxListTile.adaptive(
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ class _DefaultTitleBarState extends ConsumerState<DefaultTitleBar> with WindowLi
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
icon: Transform.translate(
|
icon: Transform.translate(
|
||||||
offset: Offset(0, -2),
|
offset: const Offset(0, -2),
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.minimize_rounded,
|
Icons.minimize_rounded,
|
||||||
color: iconColor,
|
color: iconColor,
|
||||||
|
|
@ -126,7 +126,7 @@ class _DefaultTitleBarState extends ConsumerState<DefaultTitleBar> with WindowLi
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
icon: Transform.translate(
|
icon: Transform.translate(
|
||||||
offset: Offset(0, 0),
|
offset: const Offset(0, 0),
|
||||||
child: Icon(
|
child: Icon(
|
||||||
maximized ? Icons.maximize_rounded : Icons.crop_square_rounded,
|
maximized ? Icons.maximize_rounded : Icons.crop_square_rounded,
|
||||||
color: iconColor,
|
color: iconColor,
|
||||||
|
|
@ -148,7 +148,7 @@ class _DefaultTitleBarState extends ConsumerState<DefaultTitleBar> with WindowLi
|
||||||
windowManager.close();
|
windowManager.close();
|
||||||
},
|
},
|
||||||
icon: Transform.translate(
|
icon: Transform.translate(
|
||||||
offset: Offset(0, -2),
|
offset: const Offset(0, -2),
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.close_rounded,
|
Icons.close_rounded,
|
||||||
color: iconColor,
|
color: iconColor,
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ class _DetailScreenState extends ConsumerState<DetailScreen> {
|
||||||
),
|
),
|
||||||
//Small offset to match detailscaffold
|
//Small offset to match detailscaffold
|
||||||
child: Transform.translate(
|
child: Transform.translate(
|
||||||
offset: Offset(0, -5), child: FladderImage(image: widget.item?.getPosters?.primary)),
|
offset: const Offset(0, -5), child: FladderImage(image: widget.item?.getPosters?.primary)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
AnimatedFadeSize(
|
AnimatedFadeSize(
|
||||||
|
|
@ -140,8 +140,8 @@ class _DetailScaffoldState extends ConsumerState<DetailScaffold> {
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
|
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
|
||||||
floatingActionButton: switch (playerState) {
|
floatingActionButton: switch (playerState) {
|
||||||
VideoPlayerState.minimized => Padding(
|
VideoPlayerState.minimized => const Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: EdgeInsets.all(8.0),
|
||||||
child: FloatingPlayerBar(),
|
child: FloatingPlayerBar(),
|
||||||
),
|
),
|
||||||
_ => null,
|
_ => null,
|
||||||
|
|
@ -204,11 +204,11 @@ class _DetailScaffoldState extends ConsumerState<DetailScaffold> {
|
||||||
IconTheme(
|
IconTheme(
|
||||||
data: IconThemeData(color: Theme.of(context).colorScheme.onSurface),
|
data: IconThemeData(color: Theme.of(context).colorScheme.onSurface),
|
||||||
child: Transform.translate(
|
child: Transform.translate(
|
||||||
offset: Offset(0, kToolbarHeight),
|
offset: const Offset(0, kToolbarHeight),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(left: 16),
|
padding: const EdgeInsets.only(left: 16),
|
||||||
child: IconButton.filledTonal(
|
child: IconButton.filledTonal(
|
||||||
style: IconButton.styleFrom(
|
style: IconButton.styleFrom(
|
||||||
backgroundColor: backGroundColor,
|
backgroundColor: backGroundColor,
|
||||||
|
|
@ -223,7 +223,7 @@ class _DetailScaffoldState extends ConsumerState<DetailScaffold> {
|
||||||
icon: Padding(
|
icon: Padding(
|
||||||
padding:
|
padding:
|
||||||
EdgeInsets.all(AdaptiveLayout.of(context).inputDevice == InputDevice.pointer ? 0 : 4),
|
EdgeInsets.all(AdaptiveLayout.of(context).inputDevice == InputDevice.pointer ? 0 : 4),
|
||||||
child: Icon(IconsaxOutline.arrow_left_2),
|
child: const Icon(IconsaxOutline.arrow_left_2),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -273,17 +273,17 @@ class _DetailScaffoldState extends ConsumerState<DetailScaffold> {
|
||||||
message: context.localized.refresh,
|
message: context.localized.refresh,
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
onPressed: () => context.refreshData(),
|
onPressed: () => context.refreshData(),
|
||||||
icon: Icon(IconsaxOutline.refresh),
|
icon: const Icon(IconsaxOutline.refresh),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
SizedBox(height: 30, width: 30, child: SettingsUserIcon()),
|
const SizedBox(height: 30, width: 30, child: SettingsUserIcon()),
|
||||||
Tooltip(
|
Tooltip(
|
||||||
message: context.localized.home,
|
message: context.localized.home,
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
onPressed: () => context.routeGo(DashboardRoute()),
|
onPressed: () => context.routeGo(DashboardRoute()),
|
||||||
icon: Icon(IconsaxOutline.home),
|
icon: const Icon(IconsaxOutline.home),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ class _FilePickerBarState extends ConsumerState<FilePickerBar> {
|
||||||
},
|
},
|
||||||
onDragExited: (details) => setState(() => dragStart = false),
|
onDragExited: (details) => setState(() => dragStart = false),
|
||||||
child: Container(
|
child: Container(
|
||||||
constraints: BoxConstraints(minHeight: 50, minWidth: 50),
|
constraints: const BoxConstraints(minHeight: 50, minWidth: 50),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
gradient: LinearGradient(
|
gradient: LinearGradient(
|
||||||
|
|
@ -106,7 +106,7 @@ class _FilePickerBarState extends ConsumerState<FilePickerBar> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: AnimatedSwitcher(
|
child: AnimatedSwitcher(
|
||||||
duration: Duration(milliseconds: 250),
|
duration: const Duration(milliseconds: 250),
|
||||||
child: inputField
|
child: inputField
|
||||||
? OutlinedTextField(
|
? OutlinedTextField(
|
||||||
controller: controller,
|
controller: controller,
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ void fladderSnackbar(
|
||||||
clipBehavior: Clip.none,
|
clipBehavior: Clip.none,
|
||||||
showCloseIcon: showCloseButton,
|
showCloseIcon: showCloseButton,
|
||||||
duration: duration,
|
duration: duration,
|
||||||
padding: EdgeInsets.all(18),
|
padding: const EdgeInsets.all(18),
|
||||||
action: action,
|
action: action,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ class IntInputField extends ConsumerWidget {
|
||||||
onSubmitted: (value) => onSubmitted?.call(int.tryParse(value)),
|
onSubmitted: (value) => onSubmitted?.call(int.tryParse(value)),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
contentPadding: EdgeInsets.all(0),
|
contentPadding: const EdgeInsets.all(0),
|
||||||
hintText: placeHolder,
|
hintText: placeHolder,
|
||||||
suffixText: suffix,
|
suffixText: suffix,
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ class _CarouselBannerState extends ConsumerState<CarouselBanner> {
|
||||||
double dragIntensity = 1;
|
double dragIntensity = 1;
|
||||||
double slidePosition = 1;
|
double slidePosition = 1;
|
||||||
|
|
||||||
late final RestartableTimer timer = RestartableTimer(Duration(seconds: 8), () => nextSlide());
|
late final RestartableTimer timer = RestartableTimer(const Duration(seconds: 8), () => nextSlide());
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
|
@ -121,7 +121,7 @@ class _CarouselBannerState extends ConsumerState<CarouselBanner> {
|
||||||
fit: StackFit.expand,
|
fit: StackFit.expand,
|
||||||
children: [
|
children: [
|
||||||
Dismissible(
|
Dismissible(
|
||||||
key: Key("Dismissable"),
|
key: const Key("Dismissable"),
|
||||||
direction: DismissDirection.horizontal,
|
direction: DismissDirection.horizontal,
|
||||||
onUpdate: (details) {
|
onUpdate: (details) {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
|
@ -137,10 +137,10 @@ class _CarouselBannerState extends ConsumerState<CarouselBanner> {
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
child: AnimatedOpacity(
|
child: AnimatedOpacity(
|
||||||
duration: Duration(milliseconds: 125),
|
duration: const Duration(milliseconds: 125),
|
||||||
opacity: dragOpacity.abs(),
|
opacity: dragOpacity.abs(),
|
||||||
child: AnimatedSwitcher(
|
child: AnimatedSwitcher(
|
||||||
duration: Duration(milliseconds: 125),
|
duration: const Duration(milliseconds: 125),
|
||||||
child: Container(
|
child: Container(
|
||||||
key: Key(currentItem.id),
|
key: Key(currentItem.id),
|
||||||
clipBehavior: Clip.hardEdge,
|
clipBehavior: Clip.hardEdge,
|
||||||
|
|
@ -228,7 +228,7 @@ class _CarouselBannerState extends ConsumerState<CarouselBanner> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
].addInBetween(SizedBox(height: 6)),
|
].addInBetween(const SizedBox(height: 6)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -248,7 +248,7 @@ class _CarouselBannerState extends ConsumerState<CarouselBanner> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
].addInBetween(SizedBox(height: 16)),
|
].addInBetween(const SizedBox(height: 16)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -256,13 +256,13 @@ class _CarouselBannerState extends ConsumerState<CarouselBanner> {
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||||
child: AnimatedOpacity(
|
child: AnimatedOpacity(
|
||||||
opacity: showControls ? 1 : 0,
|
opacity: showControls ? 1 : 0,
|
||||||
duration: Duration(milliseconds: 250),
|
duration: const Duration(milliseconds: 250),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
IconButton.filledTonal(
|
IconButton.filledTonal(
|
||||||
onPressed: () => nextSlide(),
|
onPressed: () => nextSlide(),
|
||||||
icon: Icon(IconsaxOutline.arrow_right_3),
|
icon: const Icon(IconsaxOutline.arrow_right_3),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -335,7 +335,7 @@ class _CarouselBannerState extends ConsumerState<CarouselBanner> {
|
||||||
width: 28,
|
width: 28,
|
||||||
height: 28,
|
height: 28,
|
||||||
child: AnimatedContainer(
|
child: AnimatedContainer(
|
||||||
duration: Duration(milliseconds: 125),
|
duration: const Duration(milliseconds: 125),
|
||||||
width: currentItem == e ? 22 : 6,
|
width: currentItem == e ? 22 : 6,
|
||||||
height: currentItem == e ? 10 : 6,
|
height: currentItem == e ? 10 : 6,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ class _PosterImageState extends ConsumerState<PosterImage> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final poster = widget.poster;
|
final poster = widget.poster;
|
||||||
final padding = EdgeInsets.all(5);
|
final padding = const EdgeInsets.all(5);
|
||||||
return Hero(
|
return Hero(
|
||||||
tag: currentTag,
|
tag: currentTag,
|
||||||
child: MouseRegion(
|
child: MouseRegion(
|
||||||
|
|
@ -169,7 +169,7 @@ class _PosterImageState extends ConsumerState<PosterImage> {
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
if (widget.poster.userData.isFavourite)
|
if (widget.poster.userData.isFavourite)
|
||||||
Row(
|
const Row(
|
||||||
children: [
|
children: [
|
||||||
StatusCard(
|
StatusCard(
|
||||||
color: Colors.red,
|
color: Colors.red,
|
||||||
|
|
@ -327,7 +327,7 @@ class _PosterImageState extends ConsumerState<PosterImage> {
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(10),
|
padding: const EdgeInsets.all(10),
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
color: Colors.amber,
|
color: Colors.amber,
|
||||||
),
|
),
|
||||||
|
|
@ -347,8 +347,8 @@ class _PosterImageState extends ConsumerState<PosterImage> {
|
||||||
.textTheme
|
.textTheme
|
||||||
.labelLarge
|
.labelLarge
|
||||||
?.copyWith(fontSize: 20, fontWeight: FontWeight.bold, shadows: [
|
?.copyWith(fontSize: 20, fontWeight: FontWeight.bold, shadows: [
|
||||||
BoxShadow(blurRadius: 8, spreadRadius: 16),
|
const BoxShadow(blurRadius: 8, spreadRadius: 16),
|
||||||
BoxShadow(blurRadius: 2, spreadRadius: 16),
|
const BoxShadow(blurRadius: 2, spreadRadius: 16),
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ class EpisodeDetailsList extends ConsumerWidget {
|
||||||
ref.watch(clientSettingsProvider.select((value) => value.posterSize)));
|
ref.watch(clientSettingsProvider.select((value) => value.posterSize)));
|
||||||
final decimals = size - size.toInt();
|
final decimals = size - size.toInt();
|
||||||
return AnimatedSwitcher(
|
return AnimatedSwitcher(
|
||||||
duration: Duration(milliseconds: 250),
|
duration: const Duration(milliseconds: 250),
|
||||||
child: switch (viewType) {
|
child: switch (viewType) {
|
||||||
EpisodeDetailsViewType.list => ListView.builder(
|
EpisodeDetailsViewType.list => ListView.builder(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ class _EpisodePosterState extends ConsumerState<EpisodePosters> {
|
||||||
label: widget.label,
|
label: widget.label,
|
||||||
titleActions: [
|
titleActions: [
|
||||||
if (episodesBySeason.isNotEmpty && episodesBySeason.length > 1) ...{
|
if (episodesBySeason.isNotEmpty && episodesBySeason.length > 1) ...{
|
||||||
SizedBox(width: 12),
|
const SizedBox(width: 12),
|
||||||
EnumBox(
|
EnumBox(
|
||||||
current: selectedSeason != null ? "${context.localized.season(1)} $selectedSeason" : context.localized.all,
|
current: selectedSeason != null ? "${context.localized.season(1)} $selectedSeason" : context.localized.all,
|
||||||
itemBuilder: (context) => [
|
itemBuilder: (context) => [
|
||||||
|
|
@ -210,7 +210,7 @@ class EpisodePoster extends ConsumerWidget {
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
if (episode.userData.isFavourite)
|
if (episode.userData.isFavourite)
|
||||||
StatusCard(
|
const StatusCard(
|
||||||
color: Colors.red,
|
color: Colors.red,
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.favorite_rounded,
|
Icons.favorite_rounded,
|
||||||
|
|
@ -219,7 +219,7 @@ class EpisodePoster extends ConsumerWidget {
|
||||||
if (episode.userData.played)
|
if (episode.userData.played)
|
||||||
StatusCard(
|
StatusCard(
|
||||||
color: Theme.of(context).colorScheme.primary,
|
color: Theme.of(context).colorScheme.primary,
|
||||||
child: Icon(
|
child: const Icon(
|
||||||
Icons.check_rounded,
|
Icons.check_rounded,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ class PosterListItem extends ConsumerWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: EdgeInsets.symmetric(vertical: 2),
|
padding: const EdgeInsets.symmetric(vertical: 2),
|
||||||
child: Card(
|
child: Card(
|
||||||
color: Theme.of(context).colorScheme.surface,
|
color: Theme.of(context).colorScheme.surface,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
|
|
@ -151,7 +151,7 @@ class PosterListItem extends ConsumerWidget {
|
||||||
children: [
|
children: [
|
||||||
if (subTitle != null) ...[
|
if (subTitle != null) ...[
|
||||||
subTitle!,
|
subTitle!,
|
||||||
Spacer(),
|
const Spacer(),
|
||||||
],
|
],
|
||||||
if (poster.subText != null && poster.subText != poster.name)
|
if (poster.subText != null && poster.subText != poster.name)
|
||||||
ClickableText(
|
ClickableText(
|
||||||
|
|
@ -180,7 +180,7 @@ class PosterListItem extends ConsumerWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (poster.userData.isFavourite)
|
if (poster.userData.isFavourite)
|
||||||
Icon(
|
const Icon(
|
||||||
IconsaxBold.heart,
|
IconsaxBold.heart,
|
||||||
color: Colors.red,
|
color: Colors.red,
|
||||||
),
|
),
|
||||||
|
|
@ -206,7 +206,7 @@ class PosterListItem extends ConsumerWidget {
|
||||||
.popupMenuItems(useIcons: true),
|
.popupMenuItems(useIcons: true),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
].addInBetween(SizedBox(width: 8)),
|
].addInBetween(const SizedBox(width: 8)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ class PosterWidget extends ConsumerWidget {
|
||||||
opacity: opacity,
|
opacity: opacity,
|
||||||
child: subTitle!,
|
child: subTitle!,
|
||||||
),
|
),
|
||||||
Spacer()
|
const Spacer()
|
||||||
],
|
],
|
||||||
if (poster.subText?.isNotEmpty ?? false)
|
if (poster.subText?.isNotEmpty ?? false)
|
||||||
Flexible(
|
Flexible(
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ class SeasonPoster extends ConsumerWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
placeHolder(String title) {
|
Padding placeHolder(String title) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.all(4),
|
padding: const EdgeInsets.all(4),
|
||||||
child: Container(
|
child: Container(
|
||||||
|
|
@ -104,7 +104,7 @@ class SeasonPoster extends ConsumerWidget {
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
season.userData.unPlayedItemCount.toString(),
|
season.userData.unPlayedItemCount.toString(),
|
||||||
style: TextStyle(fontWeight: FontWeight.w700, fontSize: 14),
|
style: const TextStyle(fontWeight: FontWeight.w700, fontSize: 14),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -114,7 +114,7 @@ class SeasonPoster extends ConsumerWidget {
|
||||||
alignment: Alignment.topRight,
|
alignment: Alignment.topRight,
|
||||||
child: StatusCard(
|
child: StatusCard(
|
||||||
color: Theme.of(context).colorScheme.primary,
|
color: Theme.of(context).colorScheme.primary,
|
||||||
child: Icon(
|
child: const Icon(
|
||||||
Icons.check_rounded,
|
Icons.check_rounded,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,8 @@ class NestedScaffold extends ConsumerWidget {
|
||||||
floatingActionButton: switch (AdaptiveLayout.layoutOf(context)) {
|
floatingActionButton: switch (AdaptiveLayout.layoutOf(context)) {
|
||||||
LayoutState.phone => null,
|
LayoutState.phone => null,
|
||||||
_ => switch (playerState) {
|
_ => switch (playerState) {
|
||||||
VideoPlayerState.minimized => Padding(
|
VideoPlayerState.minimized => const Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||||
child: FloatingPlayerBar(),
|
child: FloatingPlayerBar(),
|
||||||
),
|
),
|
||||||
_ => null,
|
_ => null,
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ class NestedSliverAppBar extends ConsumerWidget {
|
||||||
backgroundColor: WidgetStatePropertyAll(Theme.of(context).colorScheme.surface),
|
backgroundColor: WidgetStatePropertyAll(Theme.of(context).colorScheme.surface),
|
||||||
),
|
),
|
||||||
onPressed: () => Scaffold.of(parent).openDrawer(),
|
onPressed: () => Scaffold.of(parent).openDrawer(),
|
||||||
icon: Icon(
|
icon: const Icon(
|
||||||
IconsaxBold.menu,
|
IconsaxBold.menu,
|
||||||
size: 28,
|
size: 28,
|
||||||
),
|
),
|
||||||
|
|
@ -59,10 +59,10 @@ class NestedSliverAppBar extends ConsumerWidget {
|
||||||
child: Row(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Icon(IconsaxOutline.search_normal),
|
const Icon(IconsaxOutline.search_normal),
|
||||||
const SizedBox(width: 16),
|
const SizedBox(width: 16),
|
||||||
Transform.translate(
|
Transform.translate(
|
||||||
offset: Offset(0, 2.5), child: Text(searchTitle ?? "${context.localized.search}...")),
|
offset: const Offset(0, 2.5), child: Text(searchTitle ?? "${context.localized.search}...")),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -71,7 +71,7 @@ class NestedSliverAppBar extends ConsumerWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SettingsUserIcon()
|
const SettingsUserIcon()
|
||||||
].addInBetween(const SizedBox(width: 16)),
|
].addInBetween(const SizedBox(width: 16)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ class _OutlinedTextFieldState extends ConsumerState<OutlinedTextField> {
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 6),
|
padding: const EdgeInsets.symmetric(vertical: 6),
|
||||||
child: AnimatedContainer(
|
child: AnimatedContainer(
|
||||||
duration: Duration(milliseconds: 250),
|
duration: const Duration(milliseconds: 250),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: widget.fillColor ?? getColor(),
|
color: widget.fillColor ?? getColor(),
|
||||||
borderRadius: FladderTheme.defaultShape.borderRadius,
|
borderRadius: FladderTheme.defaultShape.borderRadius,
|
||||||
|
|
|
||||||
|
|
@ -44,11 +44,11 @@ class _SplashScreenState extends ConsumerState<SplashScreen> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return const Scaffold(
|
||||||
body: Center(
|
body: Center(
|
||||||
child: FractionallySizedBox(
|
child: FractionallySizedBox(
|
||||||
heightFactor: 0.4,
|
heightFactor: 0.4,
|
||||||
child: const FladderLogo(),
|
child: FladderLogo(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ class _SyncButtonState extends ConsumerState<SyncButton> {
|
||||||
if ((progress?.progress ?? 0) > 0)
|
if ((progress?.progress ?? 0) > 0)
|
||||||
IgnorePointer(
|
IgnorePointer(
|
||||||
child: SizedBox.fromSize(
|
child: SizedBox.fromSize(
|
||||||
size: Size.fromRadius(10),
|
size: const Size.fromRadius(10),
|
||||||
child: CircularProgressIndicator(
|
child: CircularProgressIndicator(
|
||||||
strokeCap: StrokeCap.round,
|
strokeCap: StrokeCap.round,
|
||||||
strokeWidth: 2,
|
strokeWidth: 2,
|
||||||
|
|
|
||||||
|
|
@ -76,12 +76,12 @@ class _SyncItemDetailsState extends ConsumerState<SyncItemDetails> {
|
||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () => Navigator.pop(context),
|
onPressed: () => Navigator.pop(context),
|
||||||
icon: Icon(IconsaxBold.close_circle),
|
icon: const Icon(IconsaxBold.close_circle),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
if (baseItem != null) ...{
|
if (baseItem != null) ...{
|
||||||
Divider(),
|
const Divider(),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||||
child: Row(
|
child: Row(
|
||||||
|
|
@ -128,24 +128,24 @@ class _SyncItemDetailsState extends ConsumerState<SyncItemDetails> {
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () =>
|
onPressed: () =>
|
||||||
ref.read(backgroundDownloaderProvider).pause(combinedStream!.task!),
|
ref.read(backgroundDownloaderProvider).pause(combinedStream!.task!),
|
||||||
icon: Icon(IconsaxBold.pause),
|
icon: const Icon(IconsaxBold.pause),
|
||||||
),
|
),
|
||||||
if (combinedStream?.status == TaskStatus.paused) ...[
|
if (combinedStream?.status == TaskStatus.paused) ...[
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () =>
|
onPressed: () =>
|
||||||
ref.read(backgroundDownloaderProvider).resume(combinedStream!.task!),
|
ref.read(backgroundDownloaderProvider).resume(combinedStream!.task!),
|
||||||
icon: Icon(IconsaxBold.play),
|
icon: const Icon(IconsaxBold.play),
|
||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () => ref.read(syncProvider.notifier).deleteFullSyncFiles(syncedItem),
|
onPressed: () => ref.read(syncProvider.notifier).deleteFullSyncFiles(syncedItem),
|
||||||
icon: Icon(IconsaxBold.stop),
|
icon: const Icon(IconsaxBold.stop),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
const SizedBox(width: 16)
|
const SizedBox(width: 16)
|
||||||
},
|
},
|
||||||
if (combinedStream != null && combinedStream.hasDownload)
|
if (combinedStream != null && combinedStream.hasDownload)
|
||||||
SizedBox.fromSize(
|
SizedBox.fromSize(
|
||||||
size: Size.fromRadius(35),
|
size: const Size.fromRadius(35),
|
||||||
child: Stack(
|
child: Stack(
|
||||||
fit: StackFit.expand,
|
fit: StackFit.expand,
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
|
|
@ -168,7 +168,7 @@ class _SyncItemDetailsState extends ConsumerState<SyncItemDetails> {
|
||||||
if (!hasFile && !downloadTask.hasDownload && syncedItem.hasVideoFile)
|
if (!hasFile && !downloadTask.hasDownload && syncedItem.hasVideoFile)
|
||||||
IconButtonAwait(
|
IconButtonAwait(
|
||||||
onPressed: () async => await ref.read(syncProvider.notifier).syncVideoFile(syncedItem, false),
|
onPressed: () async => await ref.read(syncProvider.notifier).syncVideoFile(syncedItem, false),
|
||||||
icon: Icon(IconsaxOutline.cloud_change),
|
icon: const Icon(IconsaxOutline.cloud_change),
|
||||||
)
|
)
|
||||||
else if (hasFile)
|
else if (hasFile)
|
||||||
IconButtonAwait(
|
IconButtonAwait(
|
||||||
|
|
@ -187,13 +187,13 @@ class _SyncItemDetailsState extends ConsumerState<SyncItemDetails> {
|
||||||
context.localized.cancel,
|
context.localized.cancel,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
icon: Icon(IconsaxOutline.trash),
|
icon: const Icon(IconsaxOutline.trash),
|
||||||
),
|
),
|
||||||
].addInBetween(const SizedBox(width: 16)),
|
].addInBetween(const SizedBox(width: 16)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
Divider(),
|
const Divider(),
|
||||||
if (syncChildren.isNotEmpty == true)
|
if (syncChildren.isNotEmpty == true)
|
||||||
Flexible(
|
Flexible(
|
||||||
child: ListView(
|
child: ListView(
|
||||||
|
|
|
||||||
|
|
@ -38,8 +38,8 @@ class SyncListItemState extends ConsumerState<SyncListItem> {
|
||||||
child: Dismissible(
|
child: Dismissible(
|
||||||
background: Container(
|
background: Container(
|
||||||
color: Theme.of(context).colorScheme.errorContainer,
|
color: Theme.of(context).colorScheme.errorContainer,
|
||||||
child: Padding(
|
child: const Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: EdgeInsets.all(8.0),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [Icon(IconsaxBold.trash)],
|
children: [Icon(IconsaxBold.trash)],
|
||||||
),
|
),
|
||||||
|
|
@ -130,11 +130,11 @@ class SyncListItemState extends ConsumerState<SyncListItem> {
|
||||||
)),
|
)),
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () => showSyncItemDetails(context, syncedItem, ref),
|
onPressed: () => showSyncItemDetails(context, syncedItem, ref),
|
||||||
icon: Icon(IconsaxOutline.more_square),
|
icon: const Icon(IconsaxOutline.more_square),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
].addInBetween(SizedBox(width: 16)),
|
].addInBetween(const SizedBox(width: 16)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ class SyncProgressBar extends ConsumerWidget {
|
||||||
final downloadProgress = task.progress;
|
final downloadProgress = task.progress;
|
||||||
final downloadTask = task.task;
|
final downloadTask = task.task;
|
||||||
if (!task.hasDownload) {
|
if (!task.hasDownload) {
|
||||||
return SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
}
|
}
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
|
@ -73,20 +73,20 @@ class SyncProgressBar extends ConsumerWidget {
|
||||||
if (downloadStatus != TaskStatus.paused)
|
if (downloadStatus != TaskStatus.paused)
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () => ref.read(backgroundDownloaderProvider).pause(downloadTask),
|
onPressed: () => ref.read(backgroundDownloaderProvider).pause(downloadTask),
|
||||||
icon: Icon(IconsaxBold.pause),
|
icon: const Icon(IconsaxBold.pause),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
if (downloadStatus == TaskStatus.paused && downloadTask != null) ...[
|
if (downloadStatus == TaskStatus.paused && downloadTask != null) ...[
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () => ref.read(backgroundDownloaderProvider).resume(downloadTask),
|
onPressed: () => ref.read(backgroundDownloaderProvider).resume(downloadTask),
|
||||||
icon: Icon(IconsaxBold.play),
|
icon: const Icon(IconsaxBold.play),
|
||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () => ref.read(syncProvider.notifier).deleteFullSyncFiles(item),
|
onPressed: () => ref.read(syncProvider.notifier).deleteFullSyncFiles(item),
|
||||||
icon: Icon(IconsaxBold.stop),
|
icon: const Icon(IconsaxBold.stop),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
].addInBetween(SizedBox(width: 8)),
|
].addInBetween(const SizedBox(width: 8)),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 6),
|
const SizedBox(width: 6),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ class _SyncedScreenState extends ConsumerState<SyncedScreen> {
|
||||||
const DefaultSliverTopBadding(),
|
const DefaultSliverTopBadding(),
|
||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 16),
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
child: Text(
|
child: Text(
|
||||||
context.localized.syncedItems,
|
context.localized.syncedItems,
|
||||||
style: Theme.of(context).textTheme.titleLarge,
|
style: Theme.of(context).textTheme.titleLarge,
|
||||||
|
|
@ -56,7 +56,7 @@ class _SyncedScreenState extends ConsumerState<SyncedScreen> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SliverPadding(
|
SliverPadding(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 16),
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
sliver: SliverList.builder(
|
sliver: SliverList.builder(
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final item = items[index];
|
final item = items[index];
|
||||||
|
|
@ -78,7 +78,7 @@ class _SyncedScreenState extends ConsumerState<SyncedScreen> {
|
||||||
style: Theme.of(context).textTheme.titleMedium,
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 16),
|
const SizedBox(width: 16),
|
||||||
Icon(
|
const Icon(
|
||||||
IconsaxOutline.cloud_cross,
|
IconsaxOutline.cloud_cross,
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,9 @@ class SyncMarkedForDelete extends ConsumerWidget {
|
||||||
strokeCap: StrokeCap.round,
|
strokeCap: StrokeCap.round,
|
||||||
valueColor: AlwaysStoppedAnimation(Theme.of(context).colorScheme.error),
|
valueColor: AlwaysStoppedAnimation(Theme.of(context).colorScheme.error),
|
||||||
),
|
),
|
||||||
Text("Deleting"),
|
const Text("Deleting"),
|
||||||
Icon(IconsaxOutline.trash)
|
const Icon(IconsaxOutline.trash)
|
||||||
].addPadding(EdgeInsets.symmetric(horizontal: 16)),
|
].addPadding(const EdgeInsets.symmetric(horizontal: 16)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ class _SyncedEpisodeItemState extends ConsumerState<SyncedEpisodeItem> {
|
||||||
if (!hasFile && !downloadTask.hasDownload)
|
if (!hasFile && !downloadTask.hasDownload)
|
||||||
IconButtonAwait(
|
IconButtonAwait(
|
||||||
onPressed: () async => await ref.read(syncProvider.notifier).syncVideoFile(syncedItem, false),
|
onPressed: () async => await ref.read(syncProvider.notifier).syncVideoFile(syncedItem, false),
|
||||||
icon: Icon(IconsaxOutline.cloud_change),
|
icon: const Icon(IconsaxOutline.cloud_change),
|
||||||
)
|
)
|
||||||
else if (hasFile)
|
else if (hasFile)
|
||||||
IconButtonAwait(
|
IconButtonAwait(
|
||||||
|
|
@ -114,7 +114,7 @@ class _SyncedEpisodeItemState extends ConsumerState<SyncedEpisodeItem> {
|
||||||
context.localized.cancel,
|
context.localized.cancel,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
icon: Icon(IconsaxOutline.trash),
|
icon: const Icon(IconsaxOutline.trash),
|
||||||
)
|
)
|
||||||
].addInBetween(const SizedBox(width: 16)),
|
].addInBetween(const SizedBox(width: 16)),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ class _SyncedSeasonPosterState extends ConsumerState<SyncedSeasonPoster> {
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Spacer(),
|
const Spacer(),
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
|
@ -63,16 +63,16 @@ class _SyncedSeasonPosterState extends ConsumerState<SyncedSeasonPoster> {
|
||||||
},
|
},
|
||||||
icon: Icon(!expanded ? Icons.keyboard_arrow_down_rounded : Icons.keyboard_arrow_up_rounded),
|
icon: Icon(!expanded ? Icons.keyboard_arrow_down_rounded : Icons.keyboard_arrow_up_rounded),
|
||||||
)
|
)
|
||||||
].addPadding(EdgeInsets.symmetric(horizontal: 6)),
|
].addPadding(const EdgeInsets.symmetric(horizontal: 6)),
|
||||||
),
|
),
|
||||||
AnimatedFadeSize(
|
AnimatedFadeSize(
|
||||||
duration: const Duration(milliseconds: 250),
|
duration: const Duration(milliseconds: 250),
|
||||||
child: expanded && children.isNotEmpty
|
child: expanded && children.isNotEmpty
|
||||||
? ListView(
|
? ListView(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
physics: NeverScrollableScrollPhysics(),
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Divider(),
|
const Divider(),
|
||||||
...children.map(
|
...children.map(
|
||||||
(item) {
|
(item) {
|
||||||
final baseItem = ref.read(syncProvider.notifier).getItem(item);
|
final baseItem = ref.read(syncProvider.notifier).getItem(item);
|
||||||
|
|
@ -85,7 +85,7 @@ class _SyncedSeasonPosterState extends ConsumerState<SyncedSeasonPoster> {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
].addPadding(EdgeInsets.symmetric(vertical: 10)),
|
].addPadding(const EdgeInsets.symmetric(vertical: 10)),
|
||||||
)
|
)
|
||||||
: Container(),
|
: Container(),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
Future<void> showVideoPlaybackInformation(BuildContext context) {
|
Future<void> showVideoPlaybackInformation(BuildContext context) {
|
||||||
return showDialog(
|
return showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => _VideoPlaybackInformation(),
|
builder: (context) => const _VideoPlaybackInformation(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -28,11 +28,11 @@ class _VideoPlaybackInformation extends ConsumerWidget {
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text("Playback information", style: Theme.of(context).textTheme.titleMedium),
|
Text("Playback information", style: Theme.of(context).textTheme.titleMedium),
|
||||||
Divider(),
|
const Divider(),
|
||||||
...[
|
...[
|
||||||
Row(
|
Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [Text('type: '), Text(playbackModel.label ?? "")],
|
children: [const Text('type: '), Text(playbackModel.label ?? "")],
|
||||||
),
|
),
|
||||||
if (sessionInfo.transCodeInfo != null) ...[
|
if (sessionInfo.transCodeInfo != null) ...[
|
||||||
const SizedBox(height: 6),
|
const SizedBox(height: 6),
|
||||||
|
|
@ -40,34 +40,34 @@ class _VideoPlaybackInformation extends ConsumerWidget {
|
||||||
if (sessionInfo.transCodeInfo?.transcodeReasons?.isNotEmpty == true)
|
if (sessionInfo.transCodeInfo?.transcodeReasons?.isNotEmpty == true)
|
||||||
Row(
|
Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [Text('reason: '), Text(sessionInfo.transCodeInfo?.transcodeReasons.toString() ?? "")],
|
children: [const Text('reason: '), Text(sessionInfo.transCodeInfo?.transcodeReasons.toString() ?? "")],
|
||||||
),
|
),
|
||||||
if (sessionInfo.transCodeInfo?.completionPercentage != null)
|
if (sessionInfo.transCodeInfo?.completionPercentage != null)
|
||||||
Row(
|
Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Text('transcode progress: '),
|
const Text('transcode progress: '),
|
||||||
Text("${sessionInfo.transCodeInfo?.completionPercentage?.toStringAsFixed(2)} %")
|
Text("${sessionInfo.transCodeInfo?.completionPercentage?.toStringAsFixed(2)} %")
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
if (sessionInfo.transCodeInfo?.container != null)
|
if (sessionInfo.transCodeInfo?.container != null)
|
||||||
Row(
|
Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [Text('container: '), Text(sessionInfo.transCodeInfo!.container.toString())],
|
children: [const Text('container: '), Text(sessionInfo.transCodeInfo!.container.toString())],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
Row(
|
Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [Text('resolution: '), Text(playbackModel?.item.streamModel?.resolutionText ?? "")],
|
children: [const Text('resolution: '), Text(playbackModel?.item.streamModel?.resolutionText ?? "")],
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Text('container: '),
|
const Text('container: '),
|
||||||
Text(playbackModel?.playbackInfo?.mediaSources?.firstOrNull?.container ?? "")
|
Text(playbackModel?.playbackInfo?.mediaSources?.firstOrNull?.container ?? "")
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
].addPadding(EdgeInsets.symmetric(vertical: 3))
|
].addPadding(const EdgeInsets.symmetric(vertical: 3))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import 'package:fladder/widgets/shared/horizontal_list.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
|
||||||
showPlayerChapterDialogue(
|
void showPlayerChapterDialogue(
|
||||||
BuildContext context, {
|
BuildContext context, {
|
||||||
required List<Chapter> chapters,
|
required List<Chapter> chapters,
|
||||||
required Function(Chapter chapter) onChapterTapped,
|
required Function(Chapter chapter) onChapterTapped,
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ class _VideoOptionsMobileState extends ConsumerState<VideoOptions> {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
Opacity(opacity: 0.1, child: Icon(Icons.info_outline_rounded))
|
const Opacity(opacity: 0.1, child: Icon(Icons.info_outline_rounded))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -93,7 +93,7 @@ class _VideoOptionsMobileState extends ConsumerState<VideoOptions> {
|
||||||
title: Row(
|
title: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Flexible(flex: 1, child: const Text("Screen Brightness")),
|
const Flexible(flex: 1, child: Text("Screen Brightness")),
|
||||||
Flexible(
|
Flexible(
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -250,7 +250,7 @@ class _VideoOptionsMobileState extends ConsumerState<VideoOptions> {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
showInfoScreen(context, currentItem);
|
showInfoScreen(context, currentItem);
|
||||||
},
|
},
|
||||||
title: Text('Media info'),
|
title: const Text('Media info'),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
@ -337,7 +337,7 @@ Future<void> showSubSelection(BuildContext context) {
|
||||||
final playbackModel = ref.watch(playBackModel);
|
final playbackModel = ref.watch(playBackModel);
|
||||||
final player = ref.watch(videoPlayerProvider);
|
final player = ref.watch(videoPlayerProvider);
|
||||||
return SimpleDialog(
|
return SimpleDialog(
|
||||||
contentPadding: EdgeInsets.only(top: 8, bottom: 24),
|
contentPadding: const EdgeInsets.only(top: 8, bottom: 24),
|
||||||
title: Row(
|
title: Row(
|
||||||
children: [
|
children: [
|
||||||
const Text("Subtitle"),
|
const Text("Subtitle"),
|
||||||
|
|
@ -388,7 +388,7 @@ Future<void> showAudioSelection(BuildContext context) {
|
||||||
final playbackModel = ref.watch(playBackModel);
|
final playbackModel = ref.watch(playBackModel);
|
||||||
final player = ref.watch(videoPlayerProvider);
|
final player = ref.watch(videoPlayerProvider);
|
||||||
return SimpleDialog(
|
return SimpleDialog(
|
||||||
contentPadding: EdgeInsets.only(top: 8, bottom: 24),
|
contentPadding: const EdgeInsets.only(top: 8, bottom: 24),
|
||||||
title: Row(
|
title: Row(
|
||||||
children: [
|
children: [
|
||||||
const Text("Subtitle"),
|
const Text("Subtitle"),
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import 'package:fladder/widgets/navigation_scaffold/components/fladder_appbar.da
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
|
||||||
showFullScreenItemQueue(
|
void showFullScreenItemQueue(
|
||||||
BuildContext context, {
|
BuildContext context, {
|
||||||
required List<ItemBaseModel> items,
|
required List<ItemBaseModel> items,
|
||||||
ValueChanged<List<ItemBaseModel>>? onListChanged,
|
ValueChanged<List<ItemBaseModel>>? onListChanged,
|
||||||
|
|
|
||||||
|
|
@ -304,7 +304,7 @@ class _ChapterProgressSliderState extends ConsumerState<ChapterProgressSlider> {
|
||||||
AnimatedContainer(
|
AnimatedContainer(
|
||||||
duration: const Duration(milliseconds: 250),
|
duration: const Duration(milliseconds: 250),
|
||||||
child: ConstrainedBox(
|
child: ConstrainedBox(
|
||||||
constraints: BoxConstraints(maxHeight: 250),
|
constraints: const BoxConstraints(maxHeight: 250),
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||||
child: trickPlay == null || trickPlay.images.isEmpty
|
child: trickPlay == null || trickPlay.images.isEmpty
|
||||||
|
|
@ -313,7 +313,7 @@ class _ChapterProgressSliderState extends ConsumerState<ChapterProgressSlider> {
|
||||||
image: chapter.imageProvider,
|
image: chapter.imageProvider,
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
)
|
)
|
||||||
: SizedBox.shrink()
|
: const SizedBox.shrink()
|
||||||
: AspectRatio(
|
: AspectRatio(
|
||||||
aspectRatio: trickPlay.width.toDouble() / trickPlay.height.toDouble(),
|
aspectRatio: trickPlay.width.toDouble() / trickPlay.height.toDouble(),
|
||||||
child: TrickplayImage(
|
child: TrickplayImage(
|
||||||
|
|
|
||||||
|
|
@ -108,15 +108,15 @@ class _VideoSubtitleControlsState extends ConsumerState<VideoSubtitleControls> {
|
||||||
multiSelectionEnabled: false,
|
multiSelectionEnabled: false,
|
||||||
segments: [
|
segments: [
|
||||||
ButtonSegment(
|
ButtonSegment(
|
||||||
label: Text(context.localized.light, style: TextStyle(fontWeight: FontWeight.w100)),
|
label: Text(context.localized.light, style: const TextStyle(fontWeight: FontWeight.w100)),
|
||||||
value: FontWeight.w100,
|
value: FontWeight.w100,
|
||||||
),
|
),
|
||||||
ButtonSegment(
|
ButtonSegment(
|
||||||
label: Text(context.localized.normal, style: TextStyle(fontWeight: FontWeight.w500)),
|
label: Text(context.localized.normal, style: const TextStyle(fontWeight: FontWeight.w500)),
|
||||||
value: FontWeight.normal,
|
value: FontWeight.normal,
|
||||||
),
|
),
|
||||||
ButtonSegment(
|
ButtonSegment(
|
||||||
label: Text(context.localized.bold, style: TextStyle(fontWeight: FontWeight.w900)),
|
label: Text(context.localized.bold, style: const TextStyle(fontWeight: FontWeight.w900)),
|
||||||
value: FontWeight.bold,
|
value: FontWeight.bold,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ class _VideoVolumeSliderState extends ConsumerState<VideoVolumeSlider> {
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
].addInBetween(SizedBox(width: 6)),
|
].addInBetween(const SizedBox(width: 6)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@ class _VideoPlayerState extends ConsumerState<VideoPlayer> with WidgetsBindingOb
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
DesktopControls(),
|
const DesktopControls(),
|
||||||
if (errorPlaying) const _VideoErrorWidget(),
|
if (errorPlaying) const _VideoErrorWidget(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -242,7 +242,7 @@ class _DesktopControlsState extends ConsumerState<DesktopControls> {
|
||||||
.update((state) => state.copyWith(state: VideoPlayerState.minimized));
|
.update((state) => state.copyWith(state: VideoPlayerState.minimized));
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
icon: Icon(
|
icon: const Icon(
|
||||||
IconsaxOutline.arrow_down_1,
|
IconsaxOutline.arrow_down_1,
|
||||||
size: 24,
|
size: 24,
|
||||||
),
|
),
|
||||||
|
|
@ -256,7 +256,7 @@ class _DesktopControlsState extends ConsumerState<DesktopControls> {
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
Flexible(child: Align(alignment: Alignment.topRight, child: DefaultTitleBar()))
|
const Flexible(child: Align(alignment: Alignment.topRight, child: DefaultTitleBar()))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -279,7 +279,7 @@ class _DesktopControlsState extends ConsumerState<DesktopControls> {
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.only(bottom: bottomPadding)
|
padding: EdgeInsets.only(bottom: bottomPadding)
|
||||||
.copyWith(bottom: 21)
|
.copyWith(bottom: 21)
|
||||||
.add(EdgeInsets.symmetric(vertical: 16))
|
.add(const EdgeInsets.symmetric(vertical: 16))
|
||||||
.add(EdgeInsets.symmetric(horizontal: AdaptiveLayout.of(context).isDesktop ? 32 : 0)),
|
.add(EdgeInsets.symmetric(horizontal: AdaptiveLayout.of(context).isDesktop ? 32 : 0)),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -362,7 +362,7 @@ class _DesktopControlsState extends ConsumerState<DesktopControls> {
|
||||||
children: [
|
children: [
|
||||||
Tooltip(
|
Tooltip(
|
||||||
message: "Stop",
|
message: "Stop",
|
||||||
child: IconButton(onPressed: () => closePlayer(), icon: Icon(IconsaxOutline.stop))),
|
child: IconButton(onPressed: () => closePlayer(), icon: const Icon(IconsaxOutline.stop))),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
if (AdaptiveLayout.of(context).isDesktop && ref.read(videoPlayerProvider).player != null) ...{
|
if (AdaptiveLayout.of(context).isDesktop && ref.read(videoPlayerProvider).player != null) ...{
|
||||||
// OpenQueueButton(x),
|
// OpenQueueButton(x),
|
||||||
|
|
@ -457,7 +457,7 @@ class _DesktopControlsState extends ConsumerState<DesktopControls> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
].addPadding(EdgeInsets.symmetric(horizontal: 4)),
|
].addPadding(const EdgeInsets.symmetric(horizontal: 4)),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
|
|
@ -558,9 +558,9 @@ class _DesktopControlsState extends ConsumerState<DesktopControls> {
|
||||||
onPressed: () => seekForward(mediaPlaybackModel),
|
onPressed: () => seekForward(mediaPlaybackModel),
|
||||||
tooltip: "15",
|
tooltip: "15",
|
||||||
iconSize: 40,
|
iconSize: 40,
|
||||||
icon: Stack(
|
icon: const Stack(
|
||||||
children: [
|
children: [
|
||||||
const Icon(IconsaxOutline.forward_15_seconds),
|
Icon(IconsaxOutline.forward_15_seconds),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,8 @@ class FladderTheme {
|
||||||
static RoundedRectangleBorder get defaultShape => RoundedRectangleBorder(borderRadius: BorderRadius.circular(8));
|
static RoundedRectangleBorder get defaultShape => RoundedRectangleBorder(borderRadius: BorderRadius.circular(8));
|
||||||
static RoundedRectangleBorder get largeShape => RoundedRectangleBorder(borderRadius: BorderRadius.circular(16));
|
static RoundedRectangleBorder get largeShape => RoundedRectangleBorder(borderRadius: BorderRadius.circular(16));
|
||||||
|
|
||||||
static Color get darkBackgroundColor => Color.fromARGB(255, 10, 10, 10);
|
static Color get darkBackgroundColor => const Color.fromARGB(255, 10, 10, 10);
|
||||||
static Color get lightBackgroundColor => Color.fromARGB(237, 255, 255, 255);
|
static Color get lightBackgroundColor => const Color.fromARGB(237, 255, 255, 255);
|
||||||
|
|
||||||
static ThemeData theme(ColorScheme? colorScheme) {
|
static ThemeData theme(ColorScheme? colorScheme) {
|
||||||
final ColorScheme? scheme = generateDynamicColourSchemes(colorScheme);
|
final ColorScheme? scheme = generateDynamicColourSchemes(colorScheme);
|
||||||
|
|
@ -50,7 +50,7 @@ class FladderTheme {
|
||||||
margin: EdgeInsets.zero,
|
margin: EdgeInsets.zero,
|
||||||
shape: defaultShape,
|
shape: defaultShape,
|
||||||
),
|
),
|
||||||
progressIndicatorTheme: ProgressIndicatorThemeData(),
|
progressIndicatorTheme: const ProgressIndicatorThemeData(),
|
||||||
floatingActionButtonTheme: FloatingActionButtonThemeData(
|
floatingActionButtonTheme: FloatingActionButtonThemeData(
|
||||||
backgroundColor: scheme?.secondaryContainer,
|
backgroundColor: scheme?.secondaryContainer,
|
||||||
foregroundColor: scheme?.onSecondaryContainer,
|
foregroundColor: scheme?.onSecondaryContainer,
|
||||||
|
|
@ -65,7 +65,7 @@ class FladderTheme {
|
||||||
),
|
),
|
||||||
tooltipTheme: TooltipThemeData(
|
tooltipTheme: TooltipThemeData(
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
waitDuration: Duration(milliseconds: 500),
|
waitDuration: const Duration(milliseconds: 500),
|
||||||
textStyle: TextStyle(
|
textStyle: TextStyle(
|
||||||
color: scheme?.onSurface,
|
color: scheme?.onSurface,
|
||||||
),
|
),
|
||||||
|
|
@ -77,21 +77,21 @@ class FladderTheme {
|
||||||
switchTheme: SwitchThemeData(
|
switchTheme: SwitchThemeData(
|
||||||
thumbIcon: WidgetStateProperty.resolveWith((states) {
|
thumbIcon: WidgetStateProperty.resolveWith((states) {
|
||||||
if (states.contains(WidgetState.selected)) {
|
if (states.contains(WidgetState.selected)) {
|
||||||
return Icon(Icons.check_rounded);
|
return const Icon(Icons.check_rounded);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}),
|
}),
|
||||||
trackOutlineWidth: WidgetStatePropertyAll(1),
|
trackOutlineWidth: const WidgetStatePropertyAll(1),
|
||||||
),
|
),
|
||||||
iconButtonTheme: IconButtonThemeData(
|
iconButtonTheme: IconButtonThemeData(
|
||||||
style: ButtonStyle(
|
style: ButtonStyle(
|
||||||
shape: WidgetStatePropertyAll(defaultShape),
|
shape: WidgetStatePropertyAll(defaultShape),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
navigationBarTheme: NavigationBarThemeData(),
|
navigationBarTheme: const NavigationBarThemeData(),
|
||||||
dialogTheme: DialogTheme(shape: defaultShape),
|
dialogTheme: DialogTheme(shape: defaultShape),
|
||||||
scrollbarTheme: ScrollbarThemeData(
|
scrollbarTheme: ScrollbarThemeData(
|
||||||
radius: Radius.circular(16),
|
radius: const Radius.circular(16),
|
||||||
thumbColor: WidgetStateProperty.resolveWith((states) {
|
thumbColor: WidgetStateProperty.resolveWith((states) {
|
||||||
if (states.contains(WidgetState.hovered)) {
|
if (states.contains(WidgetState.hovered)) {
|
||||||
return colorScheme?.primary;
|
return colorScheme?.primary;
|
||||||
|
|
|
||||||
|
|
@ -183,9 +183,9 @@ class _AdaptiveLayoutBuilderState extends ConsumerState<AdaptiveLayoutBuilder> {
|
||||||
isDesktop: isDesktop,
|
isDesktop: isDesktop,
|
||||||
router: router,
|
router: router,
|
||||||
posterDefaults: switch (layout) {
|
posterDefaults: switch (layout) {
|
||||||
LayoutState.phone => PosterDefaults(size: 300, ratio: 0.55),
|
LayoutState.phone => const PosterDefaults(size: 300, ratio: 0.55),
|
||||||
LayoutState.tablet => PosterDefaults(size: 350, ratio: 0.55),
|
LayoutState.tablet => const PosterDefaults(size: 350, ratio: 0.55),
|
||||||
LayoutState.desktop => PosterDefaults(size: 400, ratio: 0.55),
|
LayoutState.desktop => const PosterDefaults(size: 400, ratio: 0.55),
|
||||||
},
|
},
|
||||||
child: widget.child,
|
child: widget.child,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ class FloatingActionButtonAnimated extends ConsumerWidget {
|
||||||
onPressed: onPressed,
|
onPressed: onPressed,
|
||||||
foregroundColor: alternate ? Theme.of(context).colorScheme.onSecondary : null,
|
foregroundColor: alternate ? Theme.of(context).colorScheme.onSecondary : null,
|
||||||
backgroundColor: alternate ? Theme.of(context).colorScheme.secondary : null,
|
backgroundColor: alternate ? Theme.of(context).colorScheme.secondary : null,
|
||||||
extendedPadding: EdgeInsets.all(14),
|
extendedPadding: const EdgeInsets.all(14),
|
||||||
label: AnimatedSize(
|
label: AnimatedSize(
|
||||||
duration: const Duration(milliseconds: 250),
|
duration: const Duration(milliseconds: 250),
|
||||||
child: isExtended
|
child: isExtended
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ extension ItemBaseModelExtensions on ItemBaseModel {
|
||||||
if (playAble)
|
if (playAble)
|
||||||
ItemActionButton(
|
ItemActionButton(
|
||||||
action: () => play(context, ref),
|
action: () => play(context, ref),
|
||||||
icon: Icon(IconsaxOutline.play),
|
icon: const Icon(IconsaxOutline.play),
|
||||||
label: Text(playButtonLabel(context)),
|
label: Text(playButtonLabel(context)),
|
||||||
),
|
),
|
||||||
if (parentId?.isNotEmpty == true) ...[
|
if (parentId?.isNotEmpty == true) ...[
|
||||||
|
|
@ -99,7 +99,7 @@ extension ItemBaseModelExtensions on ItemBaseModel {
|
||||||
if (!galleryItem && !exclude.contains(ItemActions.details))
|
if (!galleryItem && !exclude.contains(ItemActions.details))
|
||||||
ItemActionButton(
|
ItemActionButton(
|
||||||
action: () async => await navigateTo(context),
|
action: () async => await navigateTo(context),
|
||||||
icon: Icon(IconsaxOutline.main_component),
|
icon: const Icon(IconsaxOutline.main_component),
|
||||||
label: Text(context.localized.showDetails),
|
label: Text(context.localized.showDetails),
|
||||||
)
|
)
|
||||||
else if (!exclude.contains(ItemActions.showAlbum) && galleryItem)
|
else if (!exclude.contains(ItemActions.showAlbum) && galleryItem)
|
||||||
|
|
@ -111,7 +111,7 @@ extension ItemBaseModelExtensions on ItemBaseModel {
|
||||||
if (!exclude.contains(ItemActions.playFromStart))
|
if (!exclude.contains(ItemActions.playFromStart))
|
||||||
if ((userData.progress) > 0)
|
if ((userData.progress) > 0)
|
||||||
ItemActionButton(
|
ItemActionButton(
|
||||||
icon: Icon(IconsaxOutline.refresh),
|
icon: const Icon(IconsaxOutline.refresh),
|
||||||
action: (this is BookModel)
|
action: (this is BookModel)
|
||||||
? () => ((this as BookModel).play(context, ref, currentPage: 0))
|
? () => ((this as BookModel).play(context, ref, currentPage: 0))
|
||||||
: () => play(context, ref, startPosition: Duration.zero),
|
: () => play(context, ref, startPosition: Duration.zero),
|
||||||
|
|
@ -123,7 +123,7 @@ extension ItemBaseModelExtensions on ItemBaseModel {
|
||||||
if (!exclude.contains(ItemActions.addCollection))
|
if (!exclude.contains(ItemActions.addCollection))
|
||||||
if (type != FladderItemType.boxset)
|
if (type != FladderItemType.boxset)
|
||||||
ItemActionButton(
|
ItemActionButton(
|
||||||
icon: Icon(IconsaxOutline.archive_add),
|
icon: const Icon(IconsaxOutline.archive_add),
|
||||||
action: () async {
|
action: () async {
|
||||||
await addItemToCollection(context, [this]);
|
await addItemToCollection(context, [this]);
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
|
|
@ -135,7 +135,7 @@ extension ItemBaseModelExtensions on ItemBaseModel {
|
||||||
if (!exclude.contains(ItemActions.addPlaylist))
|
if (!exclude.contains(ItemActions.addPlaylist))
|
||||||
if (type != FladderItemType.playlist)
|
if (type != FladderItemType.playlist)
|
||||||
ItemActionButton(
|
ItemActionButton(
|
||||||
icon: Icon(IconsaxOutline.archive_add),
|
icon: const Icon(IconsaxOutline.archive_add),
|
||||||
action: () async {
|
action: () async {
|
||||||
await addItemToPlaylist(context, [this]);
|
await addItemToPlaylist(context, [this]);
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
|
|
@ -146,7 +146,7 @@ extension ItemBaseModelExtensions on ItemBaseModel {
|
||||||
),
|
),
|
||||||
if (!exclude.contains(ItemActions.markPlayed))
|
if (!exclude.contains(ItemActions.markPlayed))
|
||||||
ItemActionButton(
|
ItemActionButton(
|
||||||
icon: Icon(IconsaxOutline.eye),
|
icon: const Icon(IconsaxOutline.eye),
|
||||||
action: () async {
|
action: () async {
|
||||||
final userData = await ref.read(userProvider.notifier).markAsPlayed(true, id);
|
final userData = await ref.read(userProvider.notifier).markAsPlayed(true, id);
|
||||||
onUserDataChanged?.call(userData?.bodyOrThrow);
|
onUserDataChanged?.call(userData?.bodyOrThrow);
|
||||||
|
|
@ -156,7 +156,7 @@ extension ItemBaseModelExtensions on ItemBaseModel {
|
||||||
),
|
),
|
||||||
if (!exclude.contains(ItemActions.markUnplayed))
|
if (!exclude.contains(ItemActions.markUnplayed))
|
||||||
ItemActionButton(
|
ItemActionButton(
|
||||||
icon: Icon(IconsaxOutline.eye_slash),
|
icon: const Icon(IconsaxOutline.eye_slash),
|
||||||
label: Text(context.localized.markAsUnwatched),
|
label: Text(context.localized.markAsUnwatched),
|
||||||
action: () async {
|
action: () async {
|
||||||
final userData = await ref.read(userProvider.notifier).markAsPlayed(false, id);
|
final userData = await ref.read(userProvider.notifier).markAsPlayed(false, id);
|
||||||
|
|
@ -178,7 +178,7 @@ extension ItemBaseModelExtensions on ItemBaseModel {
|
||||||
ItemActionDivider(),
|
ItemActionDivider(),
|
||||||
if (!exclude.contains(ItemActions.editMetaData) && isAdmin)
|
if (!exclude.contains(ItemActions.editMetaData) && isAdmin)
|
||||||
ItemActionButton(
|
ItemActionButton(
|
||||||
icon: Icon(IconsaxOutline.edit),
|
icon: const Icon(IconsaxOutline.edit),
|
||||||
action: () async {
|
action: () async {
|
||||||
final newItem = await showEditItemPopup(context, id);
|
final newItem = await showEditItemPopup(context, id);
|
||||||
if (newItem != null) {
|
if (newItem != null) {
|
||||||
|
|
@ -189,7 +189,7 @@ extension ItemBaseModelExtensions on ItemBaseModel {
|
||||||
),
|
),
|
||||||
if (!exclude.contains(ItemActions.refreshMetaData) && isAdmin)
|
if (!exclude.contains(ItemActions.refreshMetaData) && isAdmin)
|
||||||
ItemActionButton(
|
ItemActionButton(
|
||||||
icon: Icon(IconsaxOutline.global_refresh),
|
icon: const Icon(IconsaxOutline.global_refresh),
|
||||||
action: () async {
|
action: () async {
|
||||||
showRefreshPopup(context, id, detailedName(context) ?? name);
|
showRefreshPopup(context, id, detailedName(context) ?? name);
|
||||||
},
|
},
|
||||||
|
|
@ -198,7 +198,7 @@ extension ItemBaseModelExtensions on ItemBaseModel {
|
||||||
if (!exclude.contains(ItemActions.download) && downloadEnabled) ...{
|
if (!exclude.contains(ItemActions.download) && downloadEnabled) ...{
|
||||||
if (syncedItem == null)
|
if (syncedItem == null)
|
||||||
ItemActionButton(
|
ItemActionButton(
|
||||||
icon: Icon(IconsaxOutline.arrow_down_2),
|
icon: const Icon(IconsaxOutline.arrow_down_2),
|
||||||
label: Text(context.localized.sync),
|
label: Text(context.localized.sync),
|
||||||
action: () => ref.read(syncProvider.notifier).addSyncItem(context, this),
|
action: () => ref.read(syncProvider.notifier).addSyncItem(context, this),
|
||||||
)
|
)
|
||||||
|
|
@ -212,7 +212,7 @@ extension ItemBaseModelExtensions on ItemBaseModel {
|
||||||
if (canDelete == true)
|
if (canDelete == true)
|
||||||
ItemActionButton(
|
ItemActionButton(
|
||||||
icon: Container(
|
icon: Container(
|
||||||
child: Icon(
|
child: const Icon(
|
||||||
IconsaxOutline.trash,
|
IconsaxOutline.trash,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -231,7 +231,7 @@ extension ItemBaseModelExtensions on ItemBaseModel {
|
||||||
),
|
),
|
||||||
if (!exclude.contains(ItemActions.identify) && identifiable && isAdmin)
|
if (!exclude.contains(ItemActions.identify) && identifiable && isAdmin)
|
||||||
ItemActionButton(
|
ItemActionButton(
|
||||||
icon: Icon(IconsaxOutline.search_normal),
|
icon: const Icon(IconsaxOutline.search_normal),
|
||||||
action: () async {
|
action: () async {
|
||||||
showIdentifyScreen(context, this);
|
showIdentifyScreen(context, this);
|
||||||
},
|
},
|
||||||
|
|
@ -239,7 +239,7 @@ extension ItemBaseModelExtensions on ItemBaseModel {
|
||||||
),
|
),
|
||||||
if (!exclude.contains(ItemActions.mediaInfo))
|
if (!exclude.contains(ItemActions.mediaInfo))
|
||||||
ItemActionButton(
|
ItemActionButton(
|
||||||
icon: Icon(IconsaxOutline.info_circle),
|
icon: const Icon(IconsaxOutline.info_circle),
|
||||||
action: () async {
|
action: () async {
|
||||||
showInfoScreen(context, this);
|
showInfoScreen(context, this);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -320,7 +320,7 @@ class PlaybackDialogue extends StatelessWidget {
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16).add(EdgeInsets.only(top: 16, bottom: 8)),
|
padding: const EdgeInsets.symmetric(horizontal: 16).add(const EdgeInsets.only(top: 16, bottom: 8)),
|
||||||
child: Text(
|
child: Text(
|
||||||
"Playback type",
|
"Playback type",
|
||||||
style: Theme.of(context).textTheme.titleLarge,
|
style: Theme.of(context).textTheme.titleLarge,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
String get jellyId {
|
String get jellyId {
|
||||||
var uuid = Uuid();
|
var uuid = const Uuid();
|
||||||
var guid = uuid.v4().replaceAll('-', ''); // Remove hyphens
|
var guid = uuid.v4().replaceAll('-', ''); // Remove hyphens
|
||||||
return guid.substring(0, 32); // Take only the first 32 characters
|
return guid.substring(0, 32); // Take only the first 32 characters
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import 'package:collection/collection.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
extension ListExtensions on List<Widget> {
|
extension ListExtensions on List<Widget> {
|
||||||
addInBetween(Widget widget) {
|
List<Widget> addInBetween(Widget widget) {
|
||||||
return mapIndexed(
|
return mapIndexed(
|
||||||
(index, element) {
|
(index, element) {
|
||||||
if (element != last) {
|
if (element != last) {
|
||||||
|
|
@ -14,7 +14,7 @@ extension ListExtensions on List<Widget> {
|
||||||
).expand((element) => element).toList();
|
).expand((element) => element).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
addPadding(EdgeInsets padding) {
|
List<Widget> addPadding(EdgeInsets padding) {
|
||||||
return map((e) {
|
return map((e) {
|
||||||
if (e is Expanded || e is Spacer || e is Flexible) return e;
|
if (e is Expanded || e is Spacer || e is Flexible) return e;
|
||||||
return Padding(
|
return Padding(
|
||||||
|
|
@ -29,7 +29,7 @@ extension ListExtensions on List<Widget> {
|
||||||
}).toList();
|
}).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
addSize({double? width, double? height}) {
|
List<Widget> addSize({double? width, double? height}) {
|
||||||
return map((e) {
|
return map((e) {
|
||||||
if (e is Expanded || e is Spacer || e is Flexible) return e;
|
if (e is Expanded || e is Spacer || e is Flexible) return e;
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ class _GappedContainerPainter extends CustomPainter {
|
||||||
thumbCenterDxFraction.isFinite ? thumbCenterDxFraction * size.width : 0.0; // Default to 0 if invalid fraction
|
thumbCenterDxFraction.isFinite ? thumbCenterDxFraction * size.width : 0.0; // Default to 0 if invalid fraction
|
||||||
|
|
||||||
final Radius trackCornerRadius = Radius.circular(trackRect.shortestSide / 2);
|
final Radius trackCornerRadius = Radius.circular(trackRect.shortestSide / 2);
|
||||||
final Radius trackInsideCornerRadius = Radius.circular(2.0);
|
final Radius trackInsideCornerRadius = const Radius.circular(2.0);
|
||||||
|
|
||||||
final RRect trackRRect = RRect.fromRectAndCorners(
|
final RRect trackRRect = RRect.fromRectAndCorners(
|
||||||
trackRect,
|
trackRect,
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ class FladderAppbar extends StatelessWidget implements PreferredSize {
|
||||||
height: height,
|
height: height,
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
if (automaticallyImplyLeading && context.canPop()) BackButton(),
|
if (automaticallyImplyLeading && context.canPop()) const BackButton(),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: DefaultTitleBar(
|
child: DefaultTitleBar(
|
||||||
label: label,
|
label: label,
|
||||||
|
|
@ -44,7 +44,7 @@ class FladderAppbar extends StatelessWidget implements PreferredSize {
|
||||||
backgroundColor: Theme.of(context).colorScheme.surface.withOpacity(0),
|
backgroundColor: Theme.of(context).colorScheme.surface.withOpacity(0),
|
||||||
scrolledUnderElevation: 0,
|
scrolledUnderElevation: 0,
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
systemOverlayStyle: SystemUiOverlayStyle(),
|
systemOverlayStyle: const SystemUiOverlayStyle(),
|
||||||
title: const Text(""),
|
title: const Text(""),
|
||||||
automaticallyImplyLeading: automaticallyImplyLeading,
|
automaticallyImplyLeading: automaticallyImplyLeading,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ class _CurrentlyPlayingBarState extends ConsumerState<FloatingPlayerBar> {
|
||||||
final playbackModel = ref.watch(playBackModel.select((value) => value?.item));
|
final playbackModel = ref.watch(playBackModel.select((value) => value?.item));
|
||||||
final progress = playbackInfo.position.inMilliseconds / playbackInfo.duration.inMilliseconds;
|
final progress = playbackInfo.position.inMilliseconds / playbackInfo.duration.inMilliseconds;
|
||||||
return Dismissible(
|
return Dismissible(
|
||||||
key: Key("CurrentlyPlayingBar"),
|
key: const Key("CurrentlyPlayingBar"),
|
||||||
confirmDismiss: (direction) async {
|
confirmDismiss: (direction) async {
|
||||||
if (direction == DismissDirection.up) {
|
if (direction == DismissDirection.up) {
|
||||||
await openFullScreenPlayer();
|
await openFullScreenPlayer();
|
||||||
|
|
@ -73,7 +73,7 @@ class _CurrentlyPlayingBarState extends ConsumerState<FloatingPlayerBar> {
|
||||||
child: Card(
|
child: Card(
|
||||||
elevation: 3,
|
elevation: 3,
|
||||||
child: ConstrainedBox(
|
child: ConstrainedBox(
|
||||||
constraints: BoxConstraints(minHeight: 50, maxHeight: 85),
|
constraints: const BoxConstraints(minHeight: 50, maxHeight: 85),
|
||||||
child: LayoutBuilder(builder: (context, constraints) {
|
child: LayoutBuilder(builder: (context, constraints) {
|
||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -108,7 +108,7 @@ class _CurrentlyPlayingBarState extends ConsumerState<FloatingPlayerBar> {
|
||||||
Positioned.fill(
|
Positioned.fill(
|
||||||
child: Tooltip(
|
child: Tooltip(
|
||||||
message: "Expand player",
|
message: "Expand player",
|
||||||
waitDuration: Duration(milliseconds: 500),
|
waitDuration: const Duration(milliseconds: 500),
|
||||||
child: AnimatedOpacity(
|
child: AnimatedOpacity(
|
||||||
opacity: showExpandButton ? 1 : 0,
|
opacity: showExpandButton ? 1 : 0,
|
||||||
duration: const Duration(milliseconds: 125),
|
duration: const Duration(milliseconds: 125),
|
||||||
|
|
@ -116,7 +116,7 @@ class _CurrentlyPlayingBarState extends ConsumerState<FloatingPlayerBar> {
|
||||||
color: Colors.black.withOpacity(0.6),
|
color: Colors.black.withOpacity(0.6),
|
||||||
child: FlatButton(
|
child: FlatButton(
|
||||||
onTap: () async => openFullScreenPlayer(),
|
onTap: () async => openFullScreenPlayer(),
|
||||||
child: Icon(Icons.keyboard_arrow_up_rounded),
|
child: const Icon(Icons.keyboard_arrow_up_rounded),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -157,8 +157,8 @@ class _CurrentlyPlayingBarState extends ConsumerState<FloatingPlayerBar> {
|
||||||
child: IconButton.filledTonal(
|
child: IconButton.filledTonal(
|
||||||
onPressed: () => ref.read(videoPlayerProvider).playOrPause(),
|
onPressed: () => ref.read(videoPlayerProvider).playOrPause(),
|
||||||
icon: playbackInfo.playing
|
icon: playbackInfo.playing
|
||||||
? Icon(Icons.pause_rounded)
|
? const Icon(Icons.pause_rounded)
|
||||||
: Icon(Icons.play_arrow_rounded),
|
: const Icon(Icons.play_arrow_rounded),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (constraints.maxWidth > 500) ...{
|
if (constraints.maxWidth > 500) ...{
|
||||||
|
|
@ -176,14 +176,14 @@ class _CurrentlyPlayingBarState extends ConsumerState<FloatingPlayerBar> {
|
||||||
),
|
),
|
||||||
Tooltip(
|
Tooltip(
|
||||||
message: "Stop playback",
|
message: "Stop playback",
|
||||||
waitDuration: Duration(milliseconds: 500),
|
waitDuration: const Duration(milliseconds: 500),
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
onPressed: () async => stopPlayer(),
|
onPressed: () async => stopPlayer(),
|
||||||
icon: Icon(IconsaxBold.stop),
|
icon: const Icon(IconsaxBold.stop),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
].addInBetween(SizedBox(width: 8)),
|
].addInBetween(const SizedBox(width: 8)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@ class _NavigationBodyState extends ConsumerState<NavigationBody> {
|
||||||
],
|
],
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
IconTheme(
|
IconTheme(
|
||||||
data: IconThemeData(size: 28),
|
data: const IconThemeData(size: 28),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -155,8 +155,8 @@ class _NavigationBodyState extends ConsumerState<NavigationBody> {
|
||||||
child: widget.currentLocation.contains(SettingsRoute().route)
|
child: widget.currentLocation.contains(SettingsRoute().route)
|
||||||
? Card(
|
? Card(
|
||||||
color: Theme.of(context).colorScheme.primaryContainer,
|
color: Theme.of(context).colorScheme.primaryContainer,
|
||||||
child: Padding(
|
child: const Padding(
|
||||||
padding: const EdgeInsets.all(10),
|
padding: EdgeInsets.all(10),
|
||||||
child: Icon(IconsaxBold.setting_3),
|
child: Icon(IconsaxBold.setting_3),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue