mirror of
https://github.com/gabehf/Fladder.git
synced 2026-03-07 13:38:13 -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
214
.github/workflows/build.yml
vendored
214
.github/workflows/build.yml
vendored
|
|
@ -1,63 +1,90 @@
|
|||
name: Build Fladder
|
||||
name: Build Fladder artifacts
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
branches:
|
||||
- develop
|
||||
pull_request:
|
||||
branches:
|
||||
- develop
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
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:
|
||||
needs: 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
|
||||
- name: Decode Keystore
|
||||
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:
|
||||
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-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-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:"
|
||||
cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:"
|
||||
|
||||
- name: Get dependencies
|
||||
run: flutter pub get
|
||||
|
||||
- name: Build Android APK
|
||||
run: flutter build apk
|
||||
- name: Build Android APK and AAB
|
||||
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
|
||||
with:
|
||||
name: Android
|
||||
path: build/app/outputs/apk/release/app-release.apk
|
||||
name: Android-${{ env.VERSION_NAME }}
|
||||
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:
|
||||
needs: flutter-checks
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
|
|
@ -65,9 +92,10 @@ jobs:
|
|||
uses: actions/checkout@v4.1.1
|
||||
|
||||
- name: Set up Flutter
|
||||
uses: subosito/flutter-action@v2.12.0
|
||||
uses: subosito/flutter-action@v2.16.0
|
||||
with:
|
||||
channel: "stable"
|
||||
channel: ${{ vars.FLUTTER_CHANNEL }}
|
||||
flutter-version: ${{ vars.FLUTTER_VERSION }}
|
||||
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
|
||||
|
|
@ -76,43 +104,64 @@ jobs:
|
|||
run: flutter pub get
|
||||
|
||||
- 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
|
||||
uses: actions/upload-artifact@v4.0.0
|
||||
with:
|
||||
name: Windows
|
||||
name: Windows-${{ env.VERSION_NAME }}
|
||||
path: build\windows\x64\runner\Release\
|
||||
|
||||
# build-ios:
|
||||
# runs-on: macos-latest
|
||||
# build-ios:
|
||||
# runs-on: macos-latest
|
||||
|
||||
# steps:
|
||||
# - name: Checkout repository
|
||||
# uses: actions/checkout@v4.1.1
|
||||
# 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: 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:" # optional
|
||||
# cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:" # optional
|
||||
|
||||
# - name: Get dependencies
|
||||
# run: flutter pub get
|
||||
# - name: Get dependencies
|
||||
# run: flutter pub get
|
||||
|
||||
# - name: Build iOS app
|
||||
# run: flutter build ios
|
||||
# - name: Build iOS app
|
||||
# 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
|
||||
# uses: actions/upload-artifact@v2
|
||||
# with:
|
||||
# name: ios
|
||||
# path: build/ios/iphoneos/Runner.app
|
||||
# flutter build ipa --no-codesign
|
||||
|
||||
# - 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:
|
||||
# name: ios-${{ env.VERSION_NAME }}
|
||||
# path: build/ios/ipa/*.ipa
|
||||
|
||||
build-macos:
|
||||
needs: flutter-checks
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
|
|
@ -120,9 +169,10 @@ jobs:
|
|||
uses: actions/checkout@v4.1.1
|
||||
|
||||
- name: Set up Flutter
|
||||
uses: subosito/flutter-action@v2.12.0
|
||||
uses: subosito/flutter-action@v2.16.0
|
||||
with:
|
||||
channel: "stable"
|
||||
channel: ${{ vars.FLUTTER_CHANNEL }}
|
||||
flutter-version: ${{ vars.FLUTTER_VERSION }}
|
||||
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
|
||||
|
|
@ -131,16 +181,21 @@ jobs:
|
|||
run: flutter pub get
|
||||
|
||||
- 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
|
||||
uses: actions/upload-artifact@v4.0.0
|
||||
with:
|
||||
name: macOS
|
||||
name: macOS-${{ env.VERSION_NAME }}
|
||||
path: build/macos/Build/Products/Release/fladder.app
|
||||
|
||||
# build-linux:
|
||||
# needs: flutter-checks
|
||||
# build-linux:
|
||||
# runs-on: ubuntu-latest
|
||||
|
||||
# steps:
|
||||
|
|
@ -148,9 +203,10 @@ jobs:
|
|||
# uses: actions/checkout@v4.1.1
|
||||
|
||||
# - name: Set up Flutter
|
||||
# uses: subosito/flutter-action@v2.12.0
|
||||
# uses: subosito/flutter-action@v2.16.0
|
||||
# with:
|
||||
# channel: "stable"
|
||||
# channel: ${{ vars.FLUTTER_CHANNEL }}
|
||||
# flutter-version: ${{ vars.FLUTTER_VERSION }}
|
||||
# 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
|
||||
|
|
@ -173,7 +229,6 @@ jobs:
|
|||
# path: build/linux/x64/release/bundle
|
||||
|
||||
build-web:
|
||||
needs: flutter-checks
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
|
|
@ -181,9 +236,10 @@ jobs:
|
|||
uses: actions/checkout@v4.1.1
|
||||
|
||||
- name: Set up Flutter
|
||||
uses: subosito/flutter-action@v2.12.0
|
||||
uses: subosito/flutter-action@v2.16.0
|
||||
with:
|
||||
channel: "stable"
|
||||
channel: ${{ vars.FLUTTER_CHANNEL }}
|
||||
flutter-version: ${{ vars.FLUTTER_VERSION }}
|
||||
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
|
||||
|
|
@ -192,10 +248,16 @@ jobs:
|
|||
run: flutter pub get
|
||||
|
||||
- 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
|
||||
uses: actions/upload-artifact@v4.0.0
|
||||
with:
|
||||
name: Web
|
||||
name: Web-${{ env.VERSION_NAME }}
|
||||
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
|
||||
|
||||
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:
|
||||
# strict-casts: false
|
||||
# strict-raw-types: true
|
||||
|
|
@ -17,3 +27,10 @@ linter:
|
|||
prefer_relative_imports: false
|
||||
avoid_relative_lib_imports: 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 keystorePropertiesFile = rootProject.file('key.properties')
|
||||
def keystorePropertiesFile = file('key.properties')
|
||||
if (keystorePropertiesFile.exists()) {
|
||||
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
||||
}
|
||||
|
|
@ -54,12 +54,12 @@ android {
|
|||
}
|
||||
|
||||
signingConfigs {
|
||||
release {
|
||||
keyAlias keystoreProperties['keyAlias']
|
||||
keyPassword keystoreProperties['keyPassword']
|
||||
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
|
||||
storePassword keystoreProperties['storePassword']
|
||||
}
|
||||
release {
|
||||
storeFile file('keystore.jks')
|
||||
keyAlias keystoreProperties['keyAlias']
|
||||
keyPassword keystoreProperties['keyPassword']
|
||||
storePassword keystoreProperties['storePassword']
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
|
|
|
|||
|
|
@ -1,26 +1,26 @@
|
|||
<?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>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>App</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>io.flutter.flutter.app</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>App</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>MinimumOSVersion</key>
|
||||
<string>11.0</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>App</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>io.flutter.flutter.app</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>App</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>MinimumOSVersion</key>
|
||||
<string>13.0</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
|||
|
|
@ -343,7 +343,7 @@
|
|||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SUPPORTED_PLATFORMS = iphoneos;
|
||||
|
|
@ -420,7 +420,7 @@
|
|||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
|
|
@ -469,7 +469,7 @@
|
|||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = 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,
|
||||
locale: AppLocalizations.supportedLocales.firstWhere(
|
||||
(element) => element.languageCode == language.languageCode,
|
||||
orElse: () => Locale('en', "GB"),
|
||||
orElse: () => const Locale('en', "GB"),
|
||||
),
|
||||
child: ScaffoldMessenger(child: child ?? Container()),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ class ItemBaseModel with ItemBaseModelMappable {
|
|||
SortingOptions.parentalRating => overview.parentalRating != null
|
||||
? Row(
|
||||
children: [
|
||||
Icon(
|
||||
const Icon(
|
||||
IconsaxBold.star_1,
|
||||
size: 14,
|
||||
color: Colors.yellowAccent,
|
||||
|
|
@ -85,7 +85,7 @@ class ItemBaseModel with ItemBaseModelMappable {
|
|||
SortingOptions.communityRating => overview.communityRating != null
|
||||
? Row(
|
||||
children: [
|
||||
Icon(
|
||||
const Icon(
|
||||
IconsaxBold.star_1,
|
||||
size: 14,
|
||||
color: Colors.yellowAccent,
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ class EpisodeModel extends ItemStreamModel with EpisodeModelMappable {
|
|||
images: images,
|
||||
childCount: childCount,
|
||||
primaryRatio: primaryRatio,
|
||||
userData: UserData(),
|
||||
userData: const UserData(),
|
||||
);
|
||||
|
||||
@override
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ class UserData with UserDataMappable {
|
|||
|
||||
factory UserData.fromDto(dto.UserItemDataDto? dto) {
|
||||
if (dto == null) {
|
||||
return UserData();
|
||||
return const UserData();
|
||||
}
|
||||
return UserData(
|
||||
isFavourite: dto.isFavorite ?? false,
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ class SeasonModel extends ItemBaseModel with SeasonModelMappable {
|
|||
images: images,
|
||||
childCount: childCount,
|
||||
primaryRatio: primaryRatio,
|
||||
userData: UserData(),
|
||||
userData: const UserData(),
|
||||
);
|
||||
|
||||
static List<SeasonModel> seasonsFromDto(List<dto.BaseItemDto>? dto, Ref ref) {
|
||||
|
|
|
|||
|
|
@ -113,5 +113,5 @@ class Vector2 {
|
|||
@override
|
||||
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(
|
||||
limit: 16,
|
||||
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: [
|
||||
ItemFields.parentid,
|
||||
ItemFields.mediastreams,
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ final librarySearchProvider =
|
|||
});
|
||||
|
||||
class LibrarySearchNotifier extends StateNotifier<LibrarySearchModel> {
|
||||
LibrarySearchNotifier(this.ref) : super(LibrarySearchModel());
|
||||
LibrarySearchNotifier(this.ref) : super(const LibrarySearchModel());
|
||||
|
||||
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 {
|
||||
final Map<String, UserData> updateInfo = {};
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class SessionInfo extends _$SessionInfo {
|
|||
|
||||
void _startTimer() {
|
||||
_fetchData();
|
||||
_timer = Timer.periodic(Duration(seconds: 2), (timer) async {
|
||||
_timer = Timer.periodic(const Duration(seconds: 2), (timer) async {
|
||||
await _fetchData();
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ class BookViewerSettingsNotifier extends StateNotifier<BookViewerSettingsModel>
|
|||
}
|
||||
}
|
||||
|
||||
setSavedBrightness() {
|
||||
void setSavedBrightness() {
|
||||
if (state.screenBrightness != null) {
|
||||
ScreenBrightness().setScreenBrightness(state.screenBrightness!);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,5 +17,5 @@ class HomeSettingsNotifier extends StateNotifier<HomeSettingsModel> {
|
|||
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);
|
||||
|
||||
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 setFontWeight(FontWeight? value) => state = state.copyWith(fontWeight: value);
|
||||
|
||||
setBackGroundOpacity(double value) =>
|
||||
SubtitleSettingsModel setBackGroundOpacity(double 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) {
|
||||
ScreenBrightness().setScreenBrightness(state.screenBrightness!);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ FileDownloader backgroundDownloader(BackgroundDownloaderRef ref) {
|
|||
return FileDownloader()
|
||||
..trackTasks()
|
||||
..configureNotification(
|
||||
running: TaskNotification('Downloading', 'file: {filename}'),
|
||||
complete: TaskNotification('Download finished', 'file: {filename}'),
|
||||
paused: TaskNotification('Download paused', 'file: {filename}'),
|
||||
running: const TaskNotification('Downloading', 'file: {filename}'),
|
||||
complete: const TaskNotification('Download finished', 'file: {filename}'),
|
||||
paused: const TaskNotification('Download paused', 'file: {filename}'),
|
||||
progressBar: true,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -375,7 +375,7 @@ class SyncNotifier extends StateNotifier<SyncSettingsModel> {
|
|||
Future<DownloadStream?> syncVideoFile(SyncedItem syncItem, bool skipDownload) async {
|
||||
final playbackResponse = await api.itemsItemIdPlaybackInfoPost(
|
||||
itemId: syncItem.id,
|
||||
body: PlaybackInfoDto(
|
||||
body: const PlaybackInfoDto(
|
||||
enableDirectPlay: true,
|
||||
enableDirectStream: true,
|
||||
enableTranscoding: false,
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ class VideoPlayerNotifier extends StateNotifier<MediaControlsWrapper> {
|
|||
final lastPosition = ref.read(mediaPlaybackProvider.select((value) => value.lastPosition));
|
||||
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(
|
||||
position: event,
|
||||
playing: player.state.playing,
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ class BookViewerReader extends ConsumerWidget {
|
|||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
return Container(
|
||||
child: Text("Web not supported."),
|
||||
child: const Text("Web not supported."),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -159,14 +159,14 @@ class _BookViewerScreenState extends ConsumerState<BookViewerScreen> {
|
|||
),
|
||||
} else ...{
|
||||
const SizedBox(height: 32),
|
||||
Card(
|
||||
const Card(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
padding: EdgeInsets.all(16),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.info_rounded),
|
||||
const SizedBox(width: 16),
|
||||
SizedBox(width: 16),
|
||||
Text("No next chapter"),
|
||||
],
|
||||
),
|
||||
|
|
@ -211,14 +211,14 @@ class _BookViewerScreenState extends ConsumerState<BookViewerScreen> {
|
|||
),
|
||||
} else ...{
|
||||
const SizedBox(height: 32),
|
||||
Card(
|
||||
const Card(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
padding: EdgeInsets.all(16),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.info_rounded),
|
||||
const SizedBox(width: 16),
|
||||
SizedBox(width: 16),
|
||||
Text("First chapter"),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -120,9 +120,9 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
|||
),
|
||||
),
|
||||
} else if (AdaptiveLayout.of(context).isDesktop)
|
||||
DefaultSliverTopBadding(),
|
||||
const DefaultSliverTopBadding(),
|
||||
if (AdaptiveLayout.of(context).isDesktop)
|
||||
SliverToBoxAdapter(
|
||||
const SliverToBoxAdapter(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
|
|
@ -191,7 +191,7 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
|||
posters: view.recentlyAdded,
|
||||
),
|
||||
)),
|
||||
].whereNotNull().toList().addInBetween(SliverToBoxAdapter(child: SizedBox(height: 16))),
|
||||
].whereNotNull().toList().addInBetween(const SliverToBoxAdapter(child: SizedBox(height: 16))),
|
||||
const DefautlSliverBottomPadding(),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ class OverviewHeader extends ConsumerWidget {
|
|||
if (onTitleClicked != null)
|
||||
IconButton(
|
||||
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,
|
||||
children: [
|
||||
ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
constraints: const BoxConstraints(
|
||||
maxWidth: 600,
|
||||
),
|
||||
child: Column(
|
||||
|
|
@ -86,7 +86,7 @@ class _SeasonDetailScreenState extends ConsumerState<SeasonDetailScreen> {
|
|||
),
|
||||
),
|
||||
ConstrainedBox(
|
||||
constraints: BoxConstraints(maxWidth: 300),
|
||||
constraints: const BoxConstraints(maxWidth: 300),
|
||||
child: Card(child: FladderImage(image: details.getPosters?.primary))),
|
||||
],
|
||||
).padding(padding),
|
||||
|
|
@ -122,7 +122,7 @@ class _SeasonDetailScreenState extends ConsumerState<SeasonDetailScreen> {
|
|||
Card(
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(200)),
|
||||
child: SegmentedButton(
|
||||
style: ButtonStyle(
|
||||
style: const ButtonStyle(
|
||||
elevation: WidgetStatePropertyAll(5),
|
||||
side: WidgetStatePropertyAll(BorderSide.none),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class FavouritesScreen extends ConsumerWidget {
|
|||
else
|
||||
const DefaultSliverTopBadding(),
|
||||
if (AdaptiveLayout.of(context).isDesktop)
|
||||
SliverToBoxAdapter(
|
||||
const SliverToBoxAdapter(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ class _LibrarySearchScreenState extends ConsumerState<LibrarySearchScreen> {
|
|||
floatingActionButtonLocation:
|
||||
playerState == VideoPlayerState.minimized ? FloatingActionButtonLocation.centerFloat : null,
|
||||
floatingActionButton: switch (playerState) {
|
||||
VideoPlayerState.minimized => Padding(
|
||||
VideoPlayerState.minimized => const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||
child: FloatingPlayerBar(),
|
||||
),
|
||||
|
|
@ -171,7 +171,7 @@ class _LibrarySearchScreenState extends ConsumerState<LibrarySearchScreen> {
|
|||
label: Text(context.localized.viewPhotos),
|
||||
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(
|
||||
label: Text(context.localized.itemCount(librarySearchResults.totalItemCount)),
|
||||
icon: Icon(IconsaxBold.document_1),
|
||||
icon: const Icon(IconsaxBold.document_1),
|
||||
);
|
||||
final refreshAction = ItemActionButton(
|
||||
label: Text(context.localized.forceRefresh),
|
||||
action: () => refreshKey.currentState?.show(),
|
||||
icon: Icon(IconsaxOutline.refresh),
|
||||
icon: const Icon(IconsaxOutline.refresh),
|
||||
);
|
||||
final itemViewAction = ItemActionButton(
|
||||
label: Text(context.localized.selectViewType),
|
||||
|
|
@ -279,7 +279,7 @@ class _LibrarySearchScreenState extends ConsumerState<LibrarySearchScreen> {
|
|||
.map(
|
||||
(e) => FilledButton.tonal(
|
||||
style: FilledButtonTheme.of(context).style?.copyWith(
|
||||
padding: WidgetStatePropertyAll(
|
||||
padding: const WidgetStatePropertyAll(
|
||||
EdgeInsets.symmetric(
|
||||
horizontal: 12, vertical: 24)),
|
||||
backgroundColor: WidgetStateProperty.resolveWith(
|
||||
|
|
@ -373,7 +373,7 @@ class _LibrarySearchScreenState extends ConsumerState<LibrarySearchScreen> {
|
|||
}),
|
||||
if (AdaptiveLayout.of(context).layout == LayoutState.phone) ...[
|
||||
const SizedBox(width: 6),
|
||||
SizedBox.square(dimension: 46, child: SettingsUserIcon()),
|
||||
const SizedBox.square(dimension: 46, child: SettingsUserIcon()),
|
||||
],
|
||||
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)
|
||||
SliverToBoxAdapter(
|
||||
const SliverToBoxAdapter(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
|
|
@ -476,15 +476,15 @@ class _LibrarySearchScreenState extends ConsumerState<LibrarySearchScreen> {
|
|||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(16),
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
CircularProgressIndicator.adaptive(),
|
||||
const CircularProgressIndicator.adaptive(),
|
||||
Text(context.localized.fetchingLibrary, style: Theme.of(context).textTheme.titleMedium),
|
||||
IconButton(
|
||||
onPressed: () => libraryProvider.cancelFetch(),
|
||||
icon: Icon(IconsaxOutline.close_square),
|
||||
icon: const Icon(IconsaxOutline.close_square),
|
||||
)
|
||||
].addInBetween(const SizedBox(width: 16)),
|
||||
),
|
||||
|
|
@ -598,7 +598,7 @@ class _LibrarySearchBottomBar extends ConsumerWidget {
|
|||
if (context.mounted) context.refreshData();
|
||||
},
|
||||
label: Text(context.localized.addToCollection),
|
||||
icon: Icon(
|
||||
icon: const Icon(
|
||||
IconsaxOutline.save_add,
|
||||
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))) ...{
|
||||
ItemActionButton(
|
||||
label: Text(context.localized.removeFromCollection),
|
||||
icon: Icon(IconsaxOutline.archive_slash),
|
||||
icon: const Icon(IconsaxOutline.archive_slash),
|
||||
action: () async {
|
||||
await libraryProvider.removeFromCollection(items: [item]);
|
||||
if (context.mounted) {
|
||||
|
|
@ -93,7 +93,7 @@ class LibraryViews extends ConsumerWidget {
|
|||
if (ref.watch(librarySearchProvider(key!).select((value) => value.nestedCurrentItem is PlaylistModel))) ...{
|
||||
ItemActionButton(
|
||||
label: Text(context.localized.removeFromPlaylist),
|
||||
icon: Icon(IconsaxOutline.archive_minus),
|
||||
icon: const Icon(IconsaxOutline.archive_minus),
|
||||
action: () async {
|
||||
await libraryProvider.removeFromPlaylist(items: [item]);
|
||||
if (context.mounted) {
|
||||
|
|
|
|||
|
|
@ -98,8 +98,8 @@ class _SearchBarState extends ConsumerState<SuggestionSearchBar> {
|
|||
},
|
||||
decoration: InputDecoration(
|
||||
hintText: widget.title ?? "${context.localized.search}...",
|
||||
prefixIcon: Icon(IconsaxOutline.search_normal),
|
||||
contentPadding: EdgeInsets.only(top: 13),
|
||||
prefixIcon: const Icon(IconsaxOutline.search_normal),
|
||||
contentPadding: const EdgeInsets.only(top: 13),
|
||||
suffixIcon: controller.text.isNotEmpty
|
||||
? IconButton(
|
||||
onPressed: () {
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ class _LockScreenState extends ConsumerState<LockScreen> with WidgetsBindingObse
|
|||
size: 38,
|
||||
),
|
||||
ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
constraints: const BoxConstraints(
|
||||
maxHeight: 400,
|
||||
maxWidth: 400,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ class LoginEditUser extends ConsumerWidget {
|
|||
),
|
||||
Row(
|
||||
children: [
|
||||
Icon(IconsaxBold.clock),
|
||||
const Icon(IconsaxBold.clock),
|
||||
const SizedBox(width: 8),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
|
|
|
|||
|
|
@ -79,13 +79,13 @@ class _LoginPageState extends ConsumerState<LoginScreen> {
|
|||
children: [
|
||||
if (!AdaptiveLayout.of(context).isDesktop)
|
||||
FloatingActionButton(
|
||||
key: Key("edit_button"),
|
||||
child: Icon(IconsaxOutline.edit_2),
|
||||
key: const Key("edit_button"),
|
||||
child: const Icon(IconsaxOutline.edit_2),
|
||||
onPressed: () => setState(() => editingUsers = !editingUsers),
|
||||
),
|
||||
FloatingActionButton(
|
||||
key: Key("new_button"),
|
||||
child: Icon(IconsaxOutline.add_square),
|
||||
key: const Key("new_button"),
|
||||
child: const Icon(IconsaxOutline.add_square),
|
||||
onPressed: startAddingNewUser,
|
||||
),
|
||||
].addInBetween(const SizedBox(width: 16)),
|
||||
|
|
@ -98,7 +98,7 @@ class _LoginPageState extends ConsumerState<LoginScreen> {
|
|||
shrinkWrap: true,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 32),
|
||||
children: [
|
||||
Center(
|
||||
const Center(
|
||||
child: FladderLogo(),
|
||||
),
|
||||
AnimatedFadeSize(
|
||||
|
|
@ -369,7 +369,7 @@ class _LoginPageState extends ConsumerState<LoginScreen> {
|
|||
children: [
|
||||
Text(context.localized.login),
|
||||
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)
|
||||
Align(
|
||||
alignment: Alignment.topRight,
|
||||
child: Card(
|
||||
color: Theme.of(context).colorScheme.errorContainer,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: const Icon(
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: Icon(
|
||||
IconsaxBold.edit_2,
|
||||
size: 14,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class DiscoverServersWidget extends ConsumerWidget {
|
|||
style: context.textTheme.bodyLarge,
|
||||
),
|
||||
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),
|
||||
|
|
@ -63,7 +63,7 @@ class DiscoverServersWidget extends ConsumerWidget {
|
|||
style: context.textTheme.bodyLarge,
|
||||
),
|
||||
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),
|
||||
|
|
@ -92,7 +92,7 @@ class DiscoverServersWidget extends ConsumerWidget {
|
|||
));
|
||||
},
|
||||
error: (error, stackTrace) => Text(context.localized.error),
|
||||
loading: () => Center(
|
||||
loading: () => const Center(
|
||||
child: SizedBox.square(
|
||||
dimension: 24.0,
|
||||
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)),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ class LoginIcon extends ConsumerWidget {
|
|||
],
|
||||
),
|
||||
)
|
||||
].addInBetween(SizedBox(width: 8, height: 8)),
|
||||
].addInBetween(const SizedBox(width: 8, height: 8)),
|
||||
),
|
||||
),
|
||||
FlatButton(
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ Future<ItemBaseModel?> showEditItemPopup(
|
|||
);
|
||||
return AdaptiveLayout.of(context).inputDevice == InputDevice.pointer
|
||||
? Dialog(
|
||||
insetPadding: EdgeInsets.all(64),
|
||||
insetPadding: const EdgeInsets.all(64),
|
||||
child: editWidget(),
|
||||
)
|
||||
: Dialog.fullscreen(
|
||||
|
|
@ -75,11 +75,11 @@ class _EditDialogSwitcherState extends ConsumerState<EditDialogSwitcher> with Ti
|
|||
final advancedFields = ref.watch(editItemProvider.notifier).advancedFields ?? {};
|
||||
|
||||
Map<Tab, Widget> widgets = {
|
||||
Tab(text: "General"): EditFields(fields: generalFields, json: state),
|
||||
Tab(text: "Primary"): EditImageContent(type: ImageType.primary),
|
||||
Tab(text: "Logo"): EditImageContent(type: ImageType.logo),
|
||||
Tab(text: "Backdrops"): EditImageContent(type: ImageType.backdrop),
|
||||
Tab(text: "Advanced"): EditFields(fields: advancedFields, json: state),
|
||||
const Tab(text: "General"): EditFields(fields: generalFields, json: state),
|
||||
const Tab(text: "Primary"): const EditImageContent(type: ImageType.primary),
|
||||
const Tab(text: "Logo"): const EditImageContent(type: ImageType.logo),
|
||||
const Tab(text: "Backdrops"): const EditImageContent(type: ImageType.backdrop),
|
||||
const Tab(text: "Advanced"): EditFields(fields: advancedFields, json: state),
|
||||
};
|
||||
|
||||
return Card(
|
||||
|
|
@ -103,7 +103,7 @@ class _EditDialogSwitcherState extends ConsumerState<EditDialogSwitcher> with Ti
|
|||
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: [
|
||||
Flexible(
|
||||
child: ListView(
|
||||
padding: EdgeInsets.symmetric(horizontal: 16),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
shrinkWrap: true,
|
||||
children: [
|
||||
if (widget.json != null)
|
||||
|
|
@ -64,7 +64,7 @@ class _EditGeneralState extends ConsumerState<EditFields> {
|
|||
current: map.entries.firstWhereOrNull((element) => element.value == true)?.key ?? "",
|
||||
itemBuilder: (context) => [
|
||||
PopupMenuItem(
|
||||
child: Text(""),
|
||||
child: const Text(""),
|
||||
onTap: () => ref.read(editItemProvider.notifier).updateField(MapEntry(e.key, "")),
|
||||
),
|
||||
...map.entries.map(
|
||||
|
|
@ -119,7 +119,7 @@ class _EditGeneralState extends ConsumerState<EditFields> {
|
|||
onPressed: () => ref.read(editItemProvider.notifier).updateField(
|
||||
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(
|
||||
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 = "";
|
||||
});
|
||||
},
|
||||
icon: Icon(Icons.add_rounded),
|
||||
icon: const Icon(Icons.add_rounded),
|
||||
)
|
||||
],
|
||||
),
|
||||
|
|
@ -326,7 +326,7 @@ class _EditGeneralState extends ConsumerState<EditFields> {
|
|||
message: "Open in browser",
|
||||
child: IconButton(
|
||||
onPressed: () => launchUrl(context, externalUrl.url),
|
||||
icon: Icon(Icons.open_in_browser_rounded)),
|
||||
icon: const Icon(Icons.open_in_browser_rounded)),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
|
|
@ -338,7 +338,7 @@ class _EditGeneralState extends ConsumerState<EditFields> {
|
|||
.toList()),
|
||||
);
|
||||
},
|
||||
icon: Icon(Icons.remove_rounded))
|
||||
icon: const Icon(Icons.remove_rounded))
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
@ -371,7 +371,7 @@ class _EditGeneralState extends ConsumerState<EditFields> {
|
|||
.toList()),
|
||||
);
|
||||
},
|
||||
icon: Icon(Icons.add_rounded),
|
||||
icon: const Icon(Icons.add_rounded),
|
||||
)
|
||||
],
|
||||
),
|
||||
|
|
@ -429,7 +429,7 @@ class _EditGeneralState extends ConsumerState<EditFields> {
|
|||
const Spacer(),
|
||||
IconButton(
|
||||
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)
|
||||
.updateField(MapEntry(e.key, newDate.toIso8601String()));
|
||||
},
|
||||
icon: Icon(IconsaxOutline.calendar_2))
|
||||
icon: const Icon(IconsaxOutline.calendar_2))
|
||||
],
|
||||
),
|
||||
DisplayOrder _ => Builder(builder: (context) {
|
||||
|
|
@ -580,8 +580,8 @@ class _EditGeneralState extends ConsumerState<EditFields> {
|
|||
.toList(),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||
child: Text("Order episodes by air date, DVD order, or absolute numbering."),
|
||||
)
|
||||
],
|
||||
|
|
@ -656,7 +656,7 @@ class _EditGeneralState extends ConsumerState<EditFields> {
|
|||
children: [
|
||||
Text(keyLabel, style: Theme.of(context).textTheme.titleLarge),
|
||||
const SizedBox(height: 6),
|
||||
Text(
|
||||
const Text(
|
||||
"Uncheck a field to lock it and prevent its data from being changed.",
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
|
|
@ -722,8 +722,8 @@ class _EditGeneralState extends ConsumerState<EditFields> {
|
|||
},
|
||||
)
|
||||
else
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
const Padding(
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: Center(
|
||||
child: CircularProgressIndicator.adaptive(strokeCap: StrokeCap.round),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ class _EditImageContentState extends ConsumerState<EditImageContent> {
|
|||
Align(
|
||||
alignment: Alignment.bottomRight,
|
||||
child: Transform.translate(
|
||||
offset: Offset(2, 2),
|
||||
offset: const Offset(2, 2),
|
||||
child: IconButton.filledTonal(
|
||||
style: FilledButton.styleFrom(
|
||||
backgroundColor: Theme.of(context).colorScheme.error,
|
||||
|
|
@ -115,10 +115,10 @@ class _EditImageContentState extends ConsumerState<EditImageContent> {
|
|||
await showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog.adaptive(
|
||||
title: Text("Delete image"),
|
||||
content: Text("Deleting is permanent are you sure?"),
|
||||
title: const Text("Delete image"),
|
||||
content: const Text("Deleting is permanent are you sure?"),
|
||||
actions: [
|
||||
ElevatedButton(onPressed: () => Navigator.of(context).pop(), child: Text("Cancel")),
|
||||
ElevatedButton(onPressed: () => Navigator.of(context).pop(), child: const Text("Cancel")),
|
||||
FilledButton(
|
||||
style: FilledButton.styleFrom(
|
||||
backgroundColor: Theme.of(context).colorScheme.error,
|
||||
|
|
@ -128,7 +128,7 @@ class _EditImageContentState extends ConsumerState<EditImageContent> {
|
|||
await ref.read(editItemProvider.notifier).deleteImage(widget.type, image);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(
|
||||
child: const Text(
|
||||
"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(
|
||||
label: Text("Include all languages"),
|
||||
label: const Text("Include all languages"),
|
||||
trailing: Switch.adaptive(
|
||||
value: includeAllImages,
|
||||
onChanged: (value) {
|
||||
|
|
@ -231,7 +231,7 @@ class _EditImageContentState extends ConsumerState<EditImageContent> {
|
|||
),
|
||||
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)
|
||||
Center(child: Text("No ${widget.type.value}s found"))
|
||||
],
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ class _IdentifyScreenState extends ConsumerState<IdentifyScreen> with TickerProv
|
|||
const Spacer(),
|
||||
IconButton(
|
||||
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)
|
||||
Center(
|
||||
child: processing
|
||||
? CircularProgressIndicator.adaptive(strokeCap: StrokeCap.round)
|
||||
? const CircularProgressIndicator.adaptive(strokeCap: StrokeCap.round)
|
||||
: Text(context.localized.noResults),
|
||||
)
|
||||
else
|
||||
|
|
@ -181,7 +181,7 @@ class _IdentifyScreenState extends ConsumerState<IdentifyScreen> with TickerProv
|
|||
|
||||
launchUrl(context, url ?? "");
|
||||
},
|
||||
icon: Icon(Icons.launch_rounded)),
|
||||
icon: const Icon(Icons.launch_rounded)),
|
||||
),
|
||||
Tooltip(
|
||||
message: "Select result",
|
||||
|
|
@ -202,7 +202,7 @@ class _IdentifyScreenState extends ConsumerState<IdentifyScreen> with TickerProv
|
|||
Navigator.of(context).pop();
|
||||
}
|
||||
: 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,
|
||||
),
|
||||
),
|
||||
Opacity(opacity: 0.3, child: const Divider()),
|
||||
const Opacity(opacity: 0.3, child: Divider()),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
|
|
|
|||
|
|
@ -214,13 +214,13 @@ class _PhotoViewerControllsState extends ConsumerState<PhotoViewerControls> with
|
|||
?.copyWith(fontWeight: FontWeight.bold),
|
||||
),
|
||||
if (widget.loadingMoreItems)
|
||||
SizedBox.square(
|
||||
const SizedBox.square(
|
||||
dimension: 16,
|
||||
child: CircularProgressIndicator.adaptive(
|
||||
strokeCap: StrokeCap.round,
|
||||
),
|
||||
),
|
||||
].addInBetween(SizedBox(width: 6)),
|
||||
].addInBetween(const SizedBox(width: 6)),
|
||||
),
|
||||
),
|
||||
Positioned.fill(
|
||||
|
|
@ -301,7 +301,7 @@ class _PhotoViewerControllsState extends ConsumerState<PhotoViewerControls> with
|
|||
onPressed: widget.openOptions,
|
||||
icon: IconsaxOutline.more_2,
|
||||
),
|
||||
Spacer(),
|
||||
const Spacer(),
|
||||
ElevatedIconButton(
|
||||
onPressed: markAsFavourite,
|
||||
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)),
|
||||
child: Scaffold(
|
||||
appBar: photos.isEmpty
|
||||
? FladderAppbar(
|
||||
? const FladderAppbar(
|
||||
automaticallyImplyLeading: true,
|
||||
)
|
||||
: null,
|
||||
|
|
@ -242,7 +242,7 @@ class _PhotoViewerScreenState extends ConsumerState<PhotoViewerScreen> with Widg
|
|||
),
|
||||
),
|
||||
switch (state.extendedImageLoadState) {
|
||||
LoadState.loading => Center(
|
||||
LoadState.loading => const Center(
|
||||
child: CircularProgressIndicator.adaptive(strokeCap: StrokeCap.round),
|
||||
),
|
||||
LoadState.completed => switch (photo.internalType) {
|
||||
|
|
@ -256,7 +256,7 @@ class _PhotoViewerScreenState extends ConsumerState<PhotoViewerScreen> with Widg
|
|||
LoadState.failed || _ => Align(
|
||||
alignment: Alignment.topRight,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(24).copyWith(top: topPadding + 85),
|
||||
padding: const EdgeInsets.all(24).copyWith(top: topPadding + 85),
|
||||
child: Card(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(24),
|
||||
|
|
@ -426,7 +426,7 @@ class _PhotoViewerScreenState extends ConsumerState<PhotoViewerScreen> with Widg
|
|||
controller: scrollController,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Consumer(builder: (context, ref, child) {
|
||||
|
|
@ -474,7 +474,7 @@ class _PhotoViewerScreenState extends ConsumerState<PhotoViewerScreen> with Widg
|
|||
}),
|
||||
),
|
||||
),
|
||||
Divider(),
|
||||
const Divider(),
|
||||
...currentPhoto
|
||||
.generateActions(
|
||||
context,
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ class _ClientSettingsPageState extends ConsumerState<ClientSettingsPage> {
|
|||
],
|
||||
),
|
||||
),
|
||||
icon: Icon(IconsaxOutline.folder_minus),
|
||||
icon: const Icon(IconsaxOutline.folder_minus),
|
||||
)
|
||||
: null,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|||
Future<void> openQuickConnectDialog(
|
||||
BuildContext context,
|
||||
) async {
|
||||
return showDialog(context: context, builder: (context) => QuickConnectDialog());
|
||||
return showDialog(context: context, builder: (context) => const QuickConnectDialog());
|
||||
}
|
||||
|
||||
class QuickConnectDialog extends ConsumerStatefulWidget {
|
||||
|
|
@ -90,7 +90,7 @@ class _QuickConnectDialogState extends ConsumerState<QuickConnectDialog> {
|
|||
success = context.localized.loggedIn;
|
||||
},
|
||||
);
|
||||
await Future.delayed(Duration(seconds: 2));
|
||||
await Future.delayed(const Duration(seconds: 2));
|
||||
Navigator.of(context).pop();
|
||||
} else {
|
||||
if (controller.text.isEmpty) {
|
||||
|
|
@ -106,7 +106,7 @@ class _QuickConnectDialogState extends ConsumerState<QuickConnectDialog> {
|
|||
controller.text = "";
|
||||
},
|
||||
child: loading
|
||||
? SizedBox.square(
|
||||
? const SizedBox.square(
|
||||
child: CircularProgressIndicator(),
|
||||
dimension: 16.0,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
|
|||
},
|
||||
icon: Padding(
|
||||
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(
|
||||
label: Text(context.localized.about),
|
||||
subLabel: Text("Fladder"),
|
||||
subLabel: const Text("Fladder"),
|
||||
suffix: Opacity(
|
||||
opacity: 1,
|
||||
child: FladderIconOutlined(
|
||||
|
|
@ -135,7 +135,7 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
|
|||
)),
|
||||
onTap: () => showAboutDialog(
|
||||
context: context,
|
||||
applicationIcon: FladderIcon(size: 85),
|
||||
applicationIcon: const FladderIcon(size: 85),
|
||||
applicationVersion: ref.watch(applicationInfoProvider).versionAndPlatform,
|
||||
applicationLegalese: "Donut Factory",
|
||||
),
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import 'package:fladder/util/list_padding.dart';
|
|||
import 'package:fladder/util/localization_helper.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
showAuthOptionsDialogue(
|
||||
void showAuthOptionsDialogue(
|
||||
BuildContext context,
|
||||
AccountModel currentUser,
|
||||
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)),
|
||||
);
|
||||
}),
|
||||
Divider(),
|
||||
const Divider(),
|
||||
},
|
||||
...otherItems.mapIndexed((index, element) {
|
||||
return CheckboxListTile.adaptive(
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ class _DefaultTitleBarState extends ConsumerState<DefaultTitleBar> with WindowLi
|
|||
}
|
||||
},
|
||||
icon: Transform.translate(
|
||||
offset: Offset(0, -2),
|
||||
offset: const Offset(0, -2),
|
||||
child: Icon(
|
||||
Icons.minimize_rounded,
|
||||
color: iconColor,
|
||||
|
|
@ -126,7 +126,7 @@ class _DefaultTitleBarState extends ConsumerState<DefaultTitleBar> with WindowLi
|
|||
}
|
||||
},
|
||||
icon: Transform.translate(
|
||||
offset: Offset(0, 0),
|
||||
offset: const Offset(0, 0),
|
||||
child: Icon(
|
||||
maximized ? Icons.maximize_rounded : Icons.crop_square_rounded,
|
||||
color: iconColor,
|
||||
|
|
@ -148,7 +148,7 @@ class _DefaultTitleBarState extends ConsumerState<DefaultTitleBar> with WindowLi
|
|||
windowManager.close();
|
||||
},
|
||||
icon: Transform.translate(
|
||||
offset: Offset(0, -2),
|
||||
offset: const Offset(0, -2),
|
||||
child: Icon(
|
||||
Icons.close_rounded,
|
||||
color: iconColor,
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ class _DetailScreenState extends ConsumerState<DetailScreen> {
|
|||
),
|
||||
//Small offset to match detailscaffold
|
||||
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(
|
||||
|
|
@ -140,8 +140,8 @@ class _DetailScaffoldState extends ConsumerState<DetailScaffold> {
|
|||
child: Scaffold(
|
||||
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
|
||||
floatingActionButton: switch (playerState) {
|
||||
VideoPlayerState.minimized => Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
VideoPlayerState.minimized => const Padding(
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: FloatingPlayerBar(),
|
||||
),
|
||||
_ => null,
|
||||
|
|
@ -204,11 +204,11 @@ class _DetailScaffoldState extends ConsumerState<DetailScaffold> {
|
|||
IconTheme(
|
||||
data: IconThemeData(color: Theme.of(context).colorScheme.onSurface),
|
||||
child: Transform.translate(
|
||||
offset: Offset(0, kToolbarHeight),
|
||||
offset: const Offset(0, kToolbarHeight),
|
||||
child: Row(
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 16),
|
||||
padding: const EdgeInsets.only(left: 16),
|
||||
child: IconButton.filledTonal(
|
||||
style: IconButton.styleFrom(
|
||||
backgroundColor: backGroundColor,
|
||||
|
|
@ -223,7 +223,7 @@ class _DetailScaffoldState extends ConsumerState<DetailScaffold> {
|
|||
icon: Padding(
|
||||
padding:
|
||||
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,
|
||||
child: IconButton(
|
||||
onPressed: () => context.refreshData(),
|
||||
icon: Icon(IconsaxOutline.refresh),
|
||||
icon: const Icon(IconsaxOutline.refresh),
|
||||
),
|
||||
),
|
||||
)
|
||||
else
|
||||
SizedBox(height: 30, width: 30, child: SettingsUserIcon()),
|
||||
const SizedBox(height: 30, width: 30, child: SettingsUserIcon()),
|
||||
Tooltip(
|
||||
message: context.localized.home,
|
||||
child: IconButton(
|
||||
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),
|
||||
child: Container(
|
||||
constraints: BoxConstraints(minHeight: 50, minWidth: 50),
|
||||
constraints: const BoxConstraints(minHeight: 50, minWidth: 50),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey,
|
||||
gradient: LinearGradient(
|
||||
|
|
@ -106,7 +106,7 @@ class _FilePickerBarState extends ConsumerState<FilePickerBar> {
|
|||
),
|
||||
),
|
||||
child: AnimatedSwitcher(
|
||||
duration: Duration(milliseconds: 250),
|
||||
duration: const Duration(milliseconds: 250),
|
||||
child: inputField
|
||||
? OutlinedTextField(
|
||||
controller: controller,
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ void fladderSnackbar(
|
|||
clipBehavior: Clip.none,
|
||||
showCloseIcon: showCloseButton,
|
||||
duration: duration,
|
||||
padding: EdgeInsets.all(18),
|
||||
padding: const EdgeInsets.all(18),
|
||||
action: action,
|
||||
));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class IntInputField extends ConsumerWidget {
|
|||
onSubmitted: (value) => onSubmitted?.call(int.tryParse(value)),
|
||||
textAlign: TextAlign.center,
|
||||
decoration: InputDecoration(
|
||||
contentPadding: EdgeInsets.all(0),
|
||||
contentPadding: const EdgeInsets.all(0),
|
||||
hintText: placeHolder,
|
||||
suffixText: suffix,
|
||||
border: InputBorder.none,
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class _CarouselBannerState extends ConsumerState<CarouselBanner> {
|
|||
double dragIntensity = 1;
|
||||
double slidePosition = 1;
|
||||
|
||||
late final RestartableTimer timer = RestartableTimer(Duration(seconds: 8), () => nextSlide());
|
||||
late final RestartableTimer timer = RestartableTimer(const Duration(seconds: 8), () => nextSlide());
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
|
@ -121,7 +121,7 @@ class _CarouselBannerState extends ConsumerState<CarouselBanner> {
|
|||
fit: StackFit.expand,
|
||||
children: [
|
||||
Dismissible(
|
||||
key: Key("Dismissable"),
|
||||
key: const Key("Dismissable"),
|
||||
direction: DismissDirection.horizontal,
|
||||
onUpdate: (details) {
|
||||
setState(() {
|
||||
|
|
@ -137,10 +137,10 @@ class _CarouselBannerState extends ConsumerState<CarouselBanner> {
|
|||
return false;
|
||||
},
|
||||
child: AnimatedOpacity(
|
||||
duration: Duration(milliseconds: 125),
|
||||
duration: const Duration(milliseconds: 125),
|
||||
opacity: dragOpacity.abs(),
|
||||
child: AnimatedSwitcher(
|
||||
duration: Duration(milliseconds: 125),
|
||||
duration: const Duration(milliseconds: 125),
|
||||
child: Container(
|
||||
key: Key(currentItem.id),
|
||||
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),
|
||||
child: AnimatedOpacity(
|
||||
opacity: showControls ? 1 : 0,
|
||||
duration: Duration(milliseconds: 250),
|
||||
duration: const Duration(milliseconds: 250),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
IconButton.filledTonal(
|
||||
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,
|
||||
height: 28,
|
||||
child: AnimatedContainer(
|
||||
duration: Duration(milliseconds: 125),
|
||||
duration: const Duration(milliseconds: 125),
|
||||
width: currentItem == e ? 22 : 6,
|
||||
height: currentItem == e ? 10 : 6,
|
||||
decoration: BoxDecoration(
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ class _PosterImageState extends ConsumerState<PosterImage> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final poster = widget.poster;
|
||||
final padding = EdgeInsets.all(5);
|
||||
final padding = const EdgeInsets.all(5);
|
||||
return Hero(
|
||||
tag: currentTag,
|
||||
child: MouseRegion(
|
||||
|
|
@ -169,7 +169,7 @@ class _PosterImageState extends ConsumerState<PosterImage> {
|
|||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (widget.poster.userData.isFavourite)
|
||||
Row(
|
||||
const Row(
|
||||
children: [
|
||||
StatusCard(
|
||||
color: Colors.red,
|
||||
|
|
@ -327,7 +327,7 @@ class _PosterImageState extends ConsumerState<PosterImage> {
|
|||
child: Padding(
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
decoration: const BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Colors.amber,
|
||||
),
|
||||
|
|
@ -347,8 +347,8 @@ class _PosterImageState extends ConsumerState<PosterImage> {
|
|||
.textTheme
|
||||
.labelLarge
|
||||
?.copyWith(fontSize: 20, fontWeight: FontWeight.bold, shadows: [
|
||||
BoxShadow(blurRadius: 8, spreadRadius: 16),
|
||||
BoxShadow(blurRadius: 2, spreadRadius: 16),
|
||||
const BoxShadow(blurRadius: 8, spreadRadius: 16),
|
||||
const BoxShadow(blurRadius: 2, spreadRadius: 16),
|
||||
]),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ class EpisodeDetailsList extends ConsumerWidget {
|
|||
ref.watch(clientSettingsProvider.select((value) => value.posterSize)));
|
||||
final decimals = size - size.toInt();
|
||||
return AnimatedSwitcher(
|
||||
duration: Duration(milliseconds: 250),
|
||||
duration: const Duration(milliseconds: 250),
|
||||
child: switch (viewType) {
|
||||
EpisodeDetailsViewType.list => ListView.builder(
|
||||
shrinkWrap: true,
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ class _EpisodePosterState extends ConsumerState<EpisodePosters> {
|
|||
label: widget.label,
|
||||
titleActions: [
|
||||
if (episodesBySeason.isNotEmpty && episodesBySeason.length > 1) ...{
|
||||
SizedBox(width: 12),
|
||||
const SizedBox(width: 12),
|
||||
EnumBox(
|
||||
current: selectedSeason != null ? "${context.localized.season(1)} $selectedSeason" : context.localized.all,
|
||||
itemBuilder: (context) => [
|
||||
|
|
@ -210,7 +210,7 @@ class EpisodePoster extends ConsumerWidget {
|
|||
);
|
||||
}),
|
||||
if (episode.userData.isFavourite)
|
||||
StatusCard(
|
||||
const StatusCard(
|
||||
color: Colors.red,
|
||||
child: Icon(
|
||||
Icons.favorite_rounded,
|
||||
|
|
@ -219,7 +219,7 @@ class EpisodePoster extends ConsumerWidget {
|
|||
if (episode.userData.played)
|
||||
StatusCard(
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
child: Icon(
|
||||
child: const Icon(
|
||||
Icons.check_rounded,
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ class PosterListItem extends ConsumerWidget {
|
|||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 2),
|
||||
padding: const EdgeInsets.symmetric(vertical: 2),
|
||||
child: Card(
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
child: SizedBox(
|
||||
|
|
@ -151,7 +151,7 @@ class PosterListItem extends ConsumerWidget {
|
|||
children: [
|
||||
if (subTitle != null) ...[
|
||||
subTitle!,
|
||||
Spacer(),
|
||||
const Spacer(),
|
||||
],
|
||||
if (poster.subText != null && poster.subText != poster.name)
|
||||
ClickableText(
|
||||
|
|
@ -180,7 +180,7 @@ class PosterListItem extends ConsumerWidget {
|
|||
),
|
||||
),
|
||||
if (poster.userData.isFavourite)
|
||||
Icon(
|
||||
const Icon(
|
||||
IconsaxBold.heart,
|
||||
color: Colors.red,
|
||||
),
|
||||
|
|
@ -206,7 +206,7 @@ class PosterListItem extends ConsumerWidget {
|
|||
.popupMenuItems(useIcons: true),
|
||||
),
|
||||
)
|
||||
].addInBetween(SizedBox(width: 8)),
|
||||
].addInBetween(const SizedBox(width: 8)),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ class PosterWidget extends ConsumerWidget {
|
|||
opacity: opacity,
|
||||
child: subTitle!,
|
||||
),
|
||||
Spacer()
|
||||
const Spacer()
|
||||
],
|
||||
if (poster.subText?.isNotEmpty ?? false)
|
||||
Flexible(
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ class SeasonPoster extends ConsumerWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
placeHolder(String title) {
|
||||
Padding placeHolder(String title) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(4),
|
||||
child: Container(
|
||||
|
|
@ -104,7 +104,7 @@ class SeasonPoster extends ConsumerWidget {
|
|||
child: Center(
|
||||
child: Text(
|
||||
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,
|
||||
child: StatusCard(
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
child: Icon(
|
||||
child: const Icon(
|
||||
Icons.check_rounded,
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ class NestedScaffold extends ConsumerWidget {
|
|||
floatingActionButton: switch (AdaptiveLayout.layoutOf(context)) {
|
||||
LayoutState.phone => null,
|
||||
_ => switch (playerState) {
|
||||
VideoPlayerState.minimized => Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
VideoPlayerState.minimized => const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||
child: FloatingPlayerBar(),
|
||||
),
|
||||
_ => null,
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ class NestedSliverAppBar extends ConsumerWidget {
|
|||
backgroundColor: WidgetStatePropertyAll(Theme.of(context).colorScheme.surface),
|
||||
),
|
||||
onPressed: () => Scaffold.of(parent).openDrawer(),
|
||||
icon: Icon(
|
||||
icon: const Icon(
|
||||
IconsaxBold.menu,
|
||||
size: 28,
|
||||
),
|
||||
|
|
@ -59,10 +59,10 @@ class NestedSliverAppBar extends ConsumerWidget {
|
|||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Icon(IconsaxOutline.search_normal),
|
||||
const Icon(IconsaxOutline.search_normal),
|
||||
const SizedBox(width: 16),
|
||||
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)),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ class _OutlinedTextFieldState extends ConsumerState<OutlinedTextField> {
|
|||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 6),
|
||||
child: AnimatedContainer(
|
||||
duration: Duration(milliseconds: 250),
|
||||
duration: const Duration(milliseconds: 250),
|
||||
decoration: BoxDecoration(
|
||||
color: widget.fillColor ?? getColor(),
|
||||
borderRadius: FladderTheme.defaultShape.borderRadius,
|
||||
|
|
|
|||
|
|
@ -44,11 +44,11 @@ class _SplashScreenState extends ConsumerState<SplashScreen> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
return const Scaffold(
|
||||
body: Center(
|
||||
child: FractionallySizedBox(
|
||||
heightFactor: 0.4,
|
||||
child: const FladderLogo(),
|
||||
child: FladderLogo(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ class _SyncButtonState extends ConsumerState<SyncButton> {
|
|||
if ((progress?.progress ?? 0) > 0)
|
||||
IgnorePointer(
|
||||
child: SizedBox.fromSize(
|
||||
size: Size.fromRadius(10),
|
||||
size: const Size.fromRadius(10),
|
||||
child: CircularProgressIndicator(
|
||||
strokeCap: StrokeCap.round,
|
||||
strokeWidth: 2,
|
||||
|
|
|
|||
|
|
@ -76,12 +76,12 @@ class _SyncItemDetailsState extends ConsumerState<SyncItemDetails> {
|
|||
),
|
||||
IconButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
icon: Icon(IconsaxBold.close_circle),
|
||||
icon: const Icon(IconsaxBold.close_circle),
|
||||
)
|
||||
],
|
||||
),
|
||||
if (baseItem != null) ...{
|
||||
Divider(),
|
||||
const Divider(),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: Row(
|
||||
|
|
@ -128,24 +128,24 @@ class _SyncItemDetailsState extends ConsumerState<SyncItemDetails> {
|
|||
IconButton(
|
||||
onPressed: () =>
|
||||
ref.read(backgroundDownloaderProvider).pause(combinedStream!.task!),
|
||||
icon: Icon(IconsaxBold.pause),
|
||||
icon: const Icon(IconsaxBold.pause),
|
||||
),
|
||||
if (combinedStream?.status == TaskStatus.paused) ...[
|
||||
IconButton(
|
||||
onPressed: () =>
|
||||
ref.read(backgroundDownloaderProvider).resume(combinedStream!.task!),
|
||||
icon: Icon(IconsaxBold.play),
|
||||
icon: const Icon(IconsaxBold.play),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () => ref.read(syncProvider.notifier).deleteFullSyncFiles(syncedItem),
|
||||
icon: Icon(IconsaxBold.stop),
|
||||
icon: const Icon(IconsaxBold.stop),
|
||||
),
|
||||
],
|
||||
const SizedBox(width: 16)
|
||||
},
|
||||
if (combinedStream != null && combinedStream.hasDownload)
|
||||
SizedBox.fromSize(
|
||||
size: Size.fromRadius(35),
|
||||
size: const Size.fromRadius(35),
|
||||
child: Stack(
|
||||
fit: StackFit.expand,
|
||||
alignment: Alignment.center,
|
||||
|
|
@ -168,7 +168,7 @@ class _SyncItemDetailsState extends ConsumerState<SyncItemDetails> {
|
|||
if (!hasFile && !downloadTask.hasDownload && syncedItem.hasVideoFile)
|
||||
IconButtonAwait(
|
||||
onPressed: () async => await ref.read(syncProvider.notifier).syncVideoFile(syncedItem, false),
|
||||
icon: Icon(IconsaxOutline.cloud_change),
|
||||
icon: const Icon(IconsaxOutline.cloud_change),
|
||||
)
|
||||
else if (hasFile)
|
||||
IconButtonAwait(
|
||||
|
|
@ -187,13 +187,13 @@ class _SyncItemDetailsState extends ConsumerState<SyncItemDetails> {
|
|||
context.localized.cancel,
|
||||
);
|
||||
},
|
||||
icon: Icon(IconsaxOutline.trash),
|
||||
icon: const Icon(IconsaxOutline.trash),
|
||||
),
|
||||
].addInBetween(const SizedBox(width: 16)),
|
||||
),
|
||||
),
|
||||
},
|
||||
Divider(),
|
||||
const Divider(),
|
||||
if (syncChildren.isNotEmpty == true)
|
||||
Flexible(
|
||||
child: ListView(
|
||||
|
|
|
|||
|
|
@ -38,8 +38,8 @@ class SyncListItemState extends ConsumerState<SyncListItem> {
|
|||
child: Dismissible(
|
||||
background: Container(
|
||||
color: Theme.of(context).colorScheme.errorContainer,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
children: [Icon(IconsaxBold.trash)],
|
||||
),
|
||||
|
|
@ -130,11 +130,11 @@ class SyncListItemState extends ConsumerState<SyncListItem> {
|
|||
)),
|
||||
IconButton(
|
||||
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 downloadTask = task.task;
|
||||
if (!task.hasDownload) {
|
||||
return SizedBox.shrink();
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
|
|
@ -73,20 +73,20 @@ class SyncProgressBar extends ConsumerWidget {
|
|||
if (downloadStatus != TaskStatus.paused)
|
||||
IconButton(
|
||||
onPressed: () => ref.read(backgroundDownloaderProvider).pause(downloadTask),
|
||||
icon: Icon(IconsaxBold.pause),
|
||||
icon: const Icon(IconsaxBold.pause),
|
||||
)
|
||||
},
|
||||
if (downloadStatus == TaskStatus.paused && downloadTask != null) ...[
|
||||
IconButton(
|
||||
onPressed: () => ref.read(backgroundDownloaderProvider).resume(downloadTask),
|
||||
icon: Icon(IconsaxBold.play),
|
||||
icon: const Icon(IconsaxBold.play),
|
||||
),
|
||||
IconButton(
|
||||
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),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ class _SyncedScreenState extends ConsumerState<SyncedScreen> {
|
|||
const DefaultSliverTopBadding(),
|
||||
SliverToBoxAdapter(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 16),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Text(
|
||||
context.localized.syncedItems,
|
||||
style: Theme.of(context).textTheme.titleLarge,
|
||||
|
|
@ -56,7 +56,7 @@ class _SyncedScreenState extends ConsumerState<SyncedScreen> {
|
|||
),
|
||||
),
|
||||
SliverPadding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 16),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
sliver: SliverList.builder(
|
||||
itemBuilder: (context, index) {
|
||||
final item = items[index];
|
||||
|
|
@ -78,7 +78,7 @@ class _SyncedScreenState extends ConsumerState<SyncedScreen> {
|
|||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Icon(
|
||||
const Icon(
|
||||
IconsaxOutline.cloud_cross,
|
||||
)
|
||||
],
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ class SyncMarkedForDelete extends ConsumerWidget {
|
|||
strokeCap: StrokeCap.round,
|
||||
valueColor: AlwaysStoppedAnimation(Theme.of(context).colorScheme.error),
|
||||
),
|
||||
Text("Deleting"),
|
||||
Icon(IconsaxOutline.trash)
|
||||
].addPadding(EdgeInsets.symmetric(horizontal: 16)),
|
||||
const Text("Deleting"),
|
||||
const Icon(IconsaxOutline.trash)
|
||||
].addPadding(const EdgeInsets.symmetric(horizontal: 16)),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ class _SyncedEpisodeItemState extends ConsumerState<SyncedEpisodeItem> {
|
|||
if (!hasFile && !downloadTask.hasDownload)
|
||||
IconButtonAwait(
|
||||
onPressed: () async => await ref.read(syncProvider.notifier).syncVideoFile(syncedItem, false),
|
||||
icon: Icon(IconsaxOutline.cloud_change),
|
||||
icon: const Icon(IconsaxOutline.cloud_change),
|
||||
)
|
||||
else if (hasFile)
|
||||
IconButtonAwait(
|
||||
|
|
@ -114,7 +114,7 @@ class _SyncedEpisodeItemState extends ConsumerState<SyncedEpisodeItem> {
|
|||
context.localized.cancel,
|
||||
);
|
||||
},
|
||||
icon: Icon(IconsaxOutline.trash),
|
||||
icon: const Icon(IconsaxOutline.trash),
|
||||
)
|
||||
].addInBetween(const SizedBox(width: 16)),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ class _SyncedSeasonPosterState extends ConsumerState<SyncedSeasonPoster> {
|
|||
)
|
||||
],
|
||||
),
|
||||
Spacer(),
|
||||
const Spacer(),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
|
|
@ -63,16 +63,16 @@ class _SyncedSeasonPosterState extends ConsumerState<SyncedSeasonPoster> {
|
|||
},
|
||||
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(
|
||||
duration: const Duration(milliseconds: 250),
|
||||
child: expanded && children.isNotEmpty
|
||||
? ListView(
|
||||
shrinkWrap: true,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
children: <Widget>[
|
||||
Divider(),
|
||||
const Divider(),
|
||||
...children.map(
|
||||
(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(),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|||
Future<void> showVideoPlaybackInformation(BuildContext context) {
|
||||
return showDialog(
|
||||
context: context,
|
||||
builder: (context) => _VideoPlaybackInformation(),
|
||||
builder: (context) => const _VideoPlaybackInformation(),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -28,11 +28,11 @@ class _VideoPlaybackInformation extends ConsumerWidget {
|
|||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("Playback information", style: Theme.of(context).textTheme.titleMedium),
|
||||
Divider(),
|
||||
const Divider(),
|
||||
...[
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [Text('type: '), Text(playbackModel.label ?? "")],
|
||||
children: [const Text('type: '), Text(playbackModel.label ?? "")],
|
||||
),
|
||||
if (sessionInfo.transCodeInfo != null) ...[
|
||||
const SizedBox(height: 6),
|
||||
|
|
@ -40,34 +40,34 @@ class _VideoPlaybackInformation extends ConsumerWidget {
|
|||
if (sessionInfo.transCodeInfo?.transcodeReasons?.isNotEmpty == true)
|
||||
Row(
|
||||
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)
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text('transcode progress: '),
|
||||
const Text('transcode progress: '),
|
||||
Text("${sessionInfo.transCodeInfo?.completionPercentage?.toStringAsFixed(2)} %")
|
||||
],
|
||||
),
|
||||
if (sessionInfo.transCodeInfo?.container != null)
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [Text('container: '), Text(sessionInfo.transCodeInfo!.container.toString())],
|
||||
children: [const Text('container: '), Text(sessionInfo.transCodeInfo!.container.toString())],
|
||||
),
|
||||
],
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [Text('resolution: '), Text(playbackModel?.item.streamModel?.resolutionText ?? "")],
|
||||
children: [const Text('resolution: '), Text(playbackModel?.item.streamModel?.resolutionText ?? "")],
|
||||
),
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text('container: '),
|
||||
const Text('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_riverpod/flutter_riverpod.dart';
|
||||
|
||||
showPlayerChapterDialogue(
|
||||
void showPlayerChapterDialogue(
|
||||
BuildContext context, {
|
||||
required List<Chapter> chapters,
|
||||
required Function(Chapter chapter) onChapterTapped,
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ class _VideoOptionsMobileState extends ConsumerState<VideoOptions> {
|
|||
],
|
||||
),
|
||||
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(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Flexible(flex: 1, child: const Text("Screen Brightness")),
|
||||
const Flexible(flex: 1, child: Text("Screen Brightness")),
|
||||
Flexible(
|
||||
child: Row(
|
||||
children: [
|
||||
|
|
@ -250,7 +250,7 @@ class _VideoOptionsMobileState extends ConsumerState<VideoOptions> {
|
|||
Navigator.of(context).pop();
|
||||
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 player = ref.watch(videoPlayerProvider);
|
||||
return SimpleDialog(
|
||||
contentPadding: EdgeInsets.only(top: 8, bottom: 24),
|
||||
contentPadding: const EdgeInsets.only(top: 8, bottom: 24),
|
||||
title: Row(
|
||||
children: [
|
||||
const Text("Subtitle"),
|
||||
|
|
@ -388,7 +388,7 @@ Future<void> showAudioSelection(BuildContext context) {
|
|||
final playbackModel = ref.watch(playBackModel);
|
||||
final player = ref.watch(videoPlayerProvider);
|
||||
return SimpleDialog(
|
||||
contentPadding: EdgeInsets.only(top: 8, bottom: 24),
|
||||
contentPadding: const EdgeInsets.only(top: 8, bottom: 24),
|
||||
title: Row(
|
||||
children: [
|
||||
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_riverpod/flutter_riverpod.dart';
|
||||
|
||||
showFullScreenItemQueue(
|
||||
void showFullScreenItemQueue(
|
||||
BuildContext context, {
|
||||
required List<ItemBaseModel> items,
|
||||
ValueChanged<List<ItemBaseModel>>? onListChanged,
|
||||
|
|
|
|||
|
|
@ -304,7 +304,7 @@ class _ChapterProgressSliderState extends ConsumerState<ChapterProgressSlider> {
|
|||
AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 250),
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(maxHeight: 250),
|
||||
constraints: const BoxConstraints(maxHeight: 250),
|
||||
child: ClipRRect(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||
child: trickPlay == null || trickPlay.images.isEmpty
|
||||
|
|
@ -313,7 +313,7 @@ class _ChapterProgressSliderState extends ConsumerState<ChapterProgressSlider> {
|
|||
image: chapter.imageProvider,
|
||||
fit: BoxFit.contain,
|
||||
)
|
||||
: SizedBox.shrink()
|
||||
: const SizedBox.shrink()
|
||||
: AspectRatio(
|
||||
aspectRatio: trickPlay.width.toDouble() / trickPlay.height.toDouble(),
|
||||
child: TrickplayImage(
|
||||
|
|
|
|||
|
|
@ -108,15 +108,15 @@ class _VideoSubtitleControlsState extends ConsumerState<VideoSubtitleControls> {
|
|||
multiSelectionEnabled: false,
|
||||
segments: [
|
||||
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,
|
||||
),
|
||||
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,
|
||||
),
|
||||
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,
|
||||
),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ class _VideoVolumeSliderState extends ConsumerState<VideoVolumeSlider> {
|
|||
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(),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ class _DesktopControlsState extends ConsumerState<DesktopControls> {
|
|||
.update((state) => state.copyWith(state: VideoPlayerState.minimized));
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
icon: Icon(
|
||||
icon: const Icon(
|
||||
IconsaxOutline.arrow_down_1,
|
||||
size: 24,
|
||||
),
|
||||
|
|
@ -256,7 +256,7 @@ class _DesktopControlsState extends ConsumerState<DesktopControls> {
|
|||
),
|
||||
)
|
||||
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(
|
||||
padding: EdgeInsets.only(bottom: bottomPadding)
|
||||
.copyWith(bottom: 21)
|
||||
.add(EdgeInsets.symmetric(vertical: 16))
|
||||
.add(const EdgeInsets.symmetric(vertical: 16))
|
||||
.add(EdgeInsets.symmetric(horizontal: AdaptiveLayout.of(context).isDesktop ? 32 : 0)),
|
||||
child: Column(
|
||||
children: [
|
||||
|
|
@ -362,7 +362,7 @@ class _DesktopControlsState extends ConsumerState<DesktopControls> {
|
|||
children: [
|
||||
Tooltip(
|
||||
message: "Stop",
|
||||
child: IconButton(onPressed: () => closePlayer(), icon: Icon(IconsaxOutline.stop))),
|
||||
child: IconButton(onPressed: () => closePlayer(), icon: const Icon(IconsaxOutline.stop))),
|
||||
const Spacer(),
|
||||
if (AdaptiveLayout.of(context).isDesktop && ref.read(videoPlayerProvider).player != null) ...{
|
||||
// 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),
|
||||
SizedBox(
|
||||
|
|
@ -558,9 +558,9 @@ class _DesktopControlsState extends ConsumerState<DesktopControls> {
|
|||
onPressed: () => seekForward(mediaPlaybackModel),
|
||||
tooltip: "15",
|
||||
iconSize: 40,
|
||||
icon: Stack(
|
||||
icon: const Stack(
|
||||
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 largeShape => RoundedRectangleBorder(borderRadius: BorderRadius.circular(16));
|
||||
|
||||
static Color get darkBackgroundColor => Color.fromARGB(255, 10, 10, 10);
|
||||
static Color get lightBackgroundColor => Color.fromARGB(237, 255, 255, 255);
|
||||
static Color get darkBackgroundColor => const Color.fromARGB(255, 10, 10, 10);
|
||||
static Color get lightBackgroundColor => const Color.fromARGB(237, 255, 255, 255);
|
||||
|
||||
static ThemeData theme(ColorScheme? colorScheme) {
|
||||
final ColorScheme? scheme = generateDynamicColourSchemes(colorScheme);
|
||||
|
|
@ -50,7 +50,7 @@ class FladderTheme {
|
|||
margin: EdgeInsets.zero,
|
||||
shape: defaultShape,
|
||||
),
|
||||
progressIndicatorTheme: ProgressIndicatorThemeData(),
|
||||
progressIndicatorTheme: const ProgressIndicatorThemeData(),
|
||||
floatingActionButtonTheme: FloatingActionButtonThemeData(
|
||||
backgroundColor: scheme?.secondaryContainer,
|
||||
foregroundColor: scheme?.onSecondaryContainer,
|
||||
|
|
@ -65,7 +65,7 @@ class FladderTheme {
|
|||
),
|
||||
tooltipTheme: TooltipThemeData(
|
||||
textAlign: TextAlign.center,
|
||||
waitDuration: Duration(milliseconds: 500),
|
||||
waitDuration: const Duration(milliseconds: 500),
|
||||
textStyle: TextStyle(
|
||||
color: scheme?.onSurface,
|
||||
),
|
||||
|
|
@ -77,21 +77,21 @@ class FladderTheme {
|
|||
switchTheme: SwitchThemeData(
|
||||
thumbIcon: WidgetStateProperty.resolveWith((states) {
|
||||
if (states.contains(WidgetState.selected)) {
|
||||
return Icon(Icons.check_rounded);
|
||||
return const Icon(Icons.check_rounded);
|
||||
}
|
||||
return null;
|
||||
}),
|
||||
trackOutlineWidth: WidgetStatePropertyAll(1),
|
||||
trackOutlineWidth: const WidgetStatePropertyAll(1),
|
||||
),
|
||||
iconButtonTheme: IconButtonThemeData(
|
||||
style: ButtonStyle(
|
||||
shape: WidgetStatePropertyAll(defaultShape),
|
||||
),
|
||||
),
|
||||
navigationBarTheme: NavigationBarThemeData(),
|
||||
navigationBarTheme: const NavigationBarThemeData(),
|
||||
dialogTheme: DialogTheme(shape: defaultShape),
|
||||
scrollbarTheme: ScrollbarThemeData(
|
||||
radius: Radius.circular(16),
|
||||
radius: const Radius.circular(16),
|
||||
thumbColor: WidgetStateProperty.resolveWith((states) {
|
||||
if (states.contains(WidgetState.hovered)) {
|
||||
return colorScheme?.primary;
|
||||
|
|
|
|||
|
|
@ -183,9 +183,9 @@ class _AdaptiveLayoutBuilderState extends ConsumerState<AdaptiveLayoutBuilder> {
|
|||
isDesktop: isDesktop,
|
||||
router: router,
|
||||
posterDefaults: switch (layout) {
|
||||
LayoutState.phone => PosterDefaults(size: 300, ratio: 0.55),
|
||||
LayoutState.tablet => PosterDefaults(size: 350, ratio: 0.55),
|
||||
LayoutState.desktop => PosterDefaults(size: 400, ratio: 0.55),
|
||||
LayoutState.phone => const PosterDefaults(size: 300, ratio: 0.55),
|
||||
LayoutState.tablet => const PosterDefaults(size: 350, ratio: 0.55),
|
||||
LayoutState.desktop => const PosterDefaults(size: 400, ratio: 0.55),
|
||||
},
|
||||
child: widget.child,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ class FloatingActionButtonAnimated extends ConsumerWidget {
|
|||
onPressed: onPressed,
|
||||
foregroundColor: alternate ? Theme.of(context).colorScheme.onSecondary : null,
|
||||
backgroundColor: alternate ? Theme.of(context).colorScheme.secondary : null,
|
||||
extendedPadding: EdgeInsets.all(14),
|
||||
extendedPadding: const EdgeInsets.all(14),
|
||||
label: AnimatedSize(
|
||||
duration: const Duration(milliseconds: 250),
|
||||
child: isExtended
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ extension ItemBaseModelExtensions on ItemBaseModel {
|
|||
if (playAble)
|
||||
ItemActionButton(
|
||||
action: () => play(context, ref),
|
||||
icon: Icon(IconsaxOutline.play),
|
||||
icon: const Icon(IconsaxOutline.play),
|
||||
label: Text(playButtonLabel(context)),
|
||||
),
|
||||
if (parentId?.isNotEmpty == true) ...[
|
||||
|
|
@ -99,7 +99,7 @@ extension ItemBaseModelExtensions on ItemBaseModel {
|
|||
if (!galleryItem && !exclude.contains(ItemActions.details))
|
||||
ItemActionButton(
|
||||
action: () async => await navigateTo(context),
|
||||
icon: Icon(IconsaxOutline.main_component),
|
||||
icon: const Icon(IconsaxOutline.main_component),
|
||||
label: Text(context.localized.showDetails),
|
||||
)
|
||||
else if (!exclude.contains(ItemActions.showAlbum) && galleryItem)
|
||||
|
|
@ -111,7 +111,7 @@ extension ItemBaseModelExtensions on ItemBaseModel {
|
|||
if (!exclude.contains(ItemActions.playFromStart))
|
||||
if ((userData.progress) > 0)
|
||||
ItemActionButton(
|
||||
icon: Icon(IconsaxOutline.refresh),
|
||||
icon: const Icon(IconsaxOutline.refresh),
|
||||
action: (this is BookModel)
|
||||
? () => ((this as BookModel).play(context, ref, currentPage: 0))
|
||||
: () => play(context, ref, startPosition: Duration.zero),
|
||||
|
|
@ -123,7 +123,7 @@ extension ItemBaseModelExtensions on ItemBaseModel {
|
|||
if (!exclude.contains(ItemActions.addCollection))
|
||||
if (type != FladderItemType.boxset)
|
||||
ItemActionButton(
|
||||
icon: Icon(IconsaxOutline.archive_add),
|
||||
icon: const Icon(IconsaxOutline.archive_add),
|
||||
action: () async {
|
||||
await addItemToCollection(context, [this]);
|
||||
if (context.mounted) {
|
||||
|
|
@ -135,7 +135,7 @@ extension ItemBaseModelExtensions on ItemBaseModel {
|
|||
if (!exclude.contains(ItemActions.addPlaylist))
|
||||
if (type != FladderItemType.playlist)
|
||||
ItemActionButton(
|
||||
icon: Icon(IconsaxOutline.archive_add),
|
||||
icon: const Icon(IconsaxOutline.archive_add),
|
||||
action: () async {
|
||||
await addItemToPlaylist(context, [this]);
|
||||
if (context.mounted) {
|
||||
|
|
@ -146,7 +146,7 @@ extension ItemBaseModelExtensions on ItemBaseModel {
|
|||
),
|
||||
if (!exclude.contains(ItemActions.markPlayed))
|
||||
ItemActionButton(
|
||||
icon: Icon(IconsaxOutline.eye),
|
||||
icon: const Icon(IconsaxOutline.eye),
|
||||
action: () async {
|
||||
final userData = await ref.read(userProvider.notifier).markAsPlayed(true, id);
|
||||
onUserDataChanged?.call(userData?.bodyOrThrow);
|
||||
|
|
@ -156,7 +156,7 @@ extension ItemBaseModelExtensions on ItemBaseModel {
|
|||
),
|
||||
if (!exclude.contains(ItemActions.markUnplayed))
|
||||
ItemActionButton(
|
||||
icon: Icon(IconsaxOutline.eye_slash),
|
||||
icon: const Icon(IconsaxOutline.eye_slash),
|
||||
label: Text(context.localized.markAsUnwatched),
|
||||
action: () async {
|
||||
final userData = await ref.read(userProvider.notifier).markAsPlayed(false, id);
|
||||
|
|
@ -178,7 +178,7 @@ extension ItemBaseModelExtensions on ItemBaseModel {
|
|||
ItemActionDivider(),
|
||||
if (!exclude.contains(ItemActions.editMetaData) && isAdmin)
|
||||
ItemActionButton(
|
||||
icon: Icon(IconsaxOutline.edit),
|
||||
icon: const Icon(IconsaxOutline.edit),
|
||||
action: () async {
|
||||
final newItem = await showEditItemPopup(context, id);
|
||||
if (newItem != null) {
|
||||
|
|
@ -189,7 +189,7 @@ extension ItemBaseModelExtensions on ItemBaseModel {
|
|||
),
|
||||
if (!exclude.contains(ItemActions.refreshMetaData) && isAdmin)
|
||||
ItemActionButton(
|
||||
icon: Icon(IconsaxOutline.global_refresh),
|
||||
icon: const Icon(IconsaxOutline.global_refresh),
|
||||
action: () async {
|
||||
showRefreshPopup(context, id, detailedName(context) ?? name);
|
||||
},
|
||||
|
|
@ -198,7 +198,7 @@ extension ItemBaseModelExtensions on ItemBaseModel {
|
|||
if (!exclude.contains(ItemActions.download) && downloadEnabled) ...{
|
||||
if (syncedItem == null)
|
||||
ItemActionButton(
|
||||
icon: Icon(IconsaxOutline.arrow_down_2),
|
||||
icon: const Icon(IconsaxOutline.arrow_down_2),
|
||||
label: Text(context.localized.sync),
|
||||
action: () => ref.read(syncProvider.notifier).addSyncItem(context, this),
|
||||
)
|
||||
|
|
@ -212,7 +212,7 @@ extension ItemBaseModelExtensions on ItemBaseModel {
|
|||
if (canDelete == true)
|
||||
ItemActionButton(
|
||||
icon: Container(
|
||||
child: Icon(
|
||||
child: const Icon(
|
||||
IconsaxOutline.trash,
|
||||
),
|
||||
),
|
||||
|
|
@ -231,7 +231,7 @@ extension ItemBaseModelExtensions on ItemBaseModel {
|
|||
),
|
||||
if (!exclude.contains(ItemActions.identify) && identifiable && isAdmin)
|
||||
ItemActionButton(
|
||||
icon: Icon(IconsaxOutline.search_normal),
|
||||
icon: const Icon(IconsaxOutline.search_normal),
|
||||
action: () async {
|
||||
showIdentifyScreen(context, this);
|
||||
},
|
||||
|
|
@ -239,7 +239,7 @@ extension ItemBaseModelExtensions on ItemBaseModel {
|
|||
),
|
||||
if (!exclude.contains(ItemActions.mediaInfo))
|
||||
ItemActionButton(
|
||||
icon: Icon(IconsaxOutline.info_circle),
|
||||
icon: const Icon(IconsaxOutline.info_circle),
|
||||
action: () async {
|
||||
showInfoScreen(context, this);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -320,7 +320,7 @@ class PlaybackDialogue extends StatelessWidget {
|
|||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
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(
|
||||
"Playback type",
|
||||
style: Theme.of(context).textTheme.titleLarge,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import 'package:uuid/uuid.dart';
|
||||
|
||||
String get jellyId {
|
||||
var uuid = Uuid();
|
||||
var uuid = const Uuid();
|
||||
var guid = uuid.v4().replaceAll('-', ''); // Remove hyphens
|
||||
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';
|
||||
|
||||
extension ListExtensions on List<Widget> {
|
||||
addInBetween(Widget widget) {
|
||||
List<Widget> addInBetween(Widget widget) {
|
||||
return mapIndexed(
|
||||
(index, element) {
|
||||
if (element != last) {
|
||||
|
|
@ -14,7 +14,7 @@ extension ListExtensions on List<Widget> {
|
|||
).expand((element) => element).toList();
|
||||
}
|
||||
|
||||
addPadding(EdgeInsets padding) {
|
||||
List<Widget> addPadding(EdgeInsets padding) {
|
||||
return map((e) {
|
||||
if (e is Expanded || e is Spacer || e is Flexible) return e;
|
||||
return Padding(
|
||||
|
|
@ -29,7 +29,7 @@ extension ListExtensions on List<Widget> {
|
|||
}).toList();
|
||||
}
|
||||
|
||||
addSize({double? width, double? height}) {
|
||||
List<Widget> addSize({double? width, double? height}) {
|
||||
return map((e) {
|
||||
if (e is Expanded || e is Spacer || e is Flexible) return e;
|
||||
return SizedBox(
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ class _GappedContainerPainter extends CustomPainter {
|
|||
thumbCenterDxFraction.isFinite ? thumbCenterDxFraction * size.width : 0.0; // Default to 0 if invalid fraction
|
||||
|
||||
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(
|
||||
trackRect,
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class FladderAppbar extends StatelessWidget implements PreferredSize {
|
|||
height: height,
|
||||
child: Row(
|
||||
children: [
|
||||
if (automaticallyImplyLeading && context.canPop()) BackButton(),
|
||||
if (automaticallyImplyLeading && context.canPop()) const BackButton(),
|
||||
Expanded(
|
||||
child: DefaultTitleBar(
|
||||
label: label,
|
||||
|
|
@ -44,7 +44,7 @@ class FladderAppbar extends StatelessWidget implements PreferredSize {
|
|||
backgroundColor: Theme.of(context).colorScheme.surface.withOpacity(0),
|
||||
scrolledUnderElevation: 0,
|
||||
elevation: 0,
|
||||
systemOverlayStyle: SystemUiOverlayStyle(),
|
||||
systemOverlayStyle: const SystemUiOverlayStyle(),
|
||||
title: const Text(""),
|
||||
automaticallyImplyLeading: automaticallyImplyLeading,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ class _CurrentlyPlayingBarState extends ConsumerState<FloatingPlayerBar> {
|
|||
final playbackModel = ref.watch(playBackModel.select((value) => value?.item));
|
||||
final progress = playbackInfo.position.inMilliseconds / playbackInfo.duration.inMilliseconds;
|
||||
return Dismissible(
|
||||
key: Key("CurrentlyPlayingBar"),
|
||||
key: const Key("CurrentlyPlayingBar"),
|
||||
confirmDismiss: (direction) async {
|
||||
if (direction == DismissDirection.up) {
|
||||
await openFullScreenPlayer();
|
||||
|
|
@ -73,7 +73,7 @@ class _CurrentlyPlayingBarState extends ConsumerState<FloatingPlayerBar> {
|
|||
child: Card(
|
||||
elevation: 3,
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(minHeight: 50, maxHeight: 85),
|
||||
constraints: const BoxConstraints(minHeight: 50, maxHeight: 85),
|
||||
child: LayoutBuilder(builder: (context, constraints) {
|
||||
return Row(
|
||||
children: [
|
||||
|
|
@ -108,7 +108,7 @@ class _CurrentlyPlayingBarState extends ConsumerState<FloatingPlayerBar> {
|
|||
Positioned.fill(
|
||||
child: Tooltip(
|
||||
message: "Expand player",
|
||||
waitDuration: Duration(milliseconds: 500),
|
||||
waitDuration: const Duration(milliseconds: 500),
|
||||
child: AnimatedOpacity(
|
||||
opacity: showExpandButton ? 1 : 0,
|
||||
duration: const Duration(milliseconds: 125),
|
||||
|
|
@ -116,7 +116,7 @@ class _CurrentlyPlayingBarState extends ConsumerState<FloatingPlayerBar> {
|
|||
color: Colors.black.withOpacity(0.6),
|
||||
child: FlatButton(
|
||||
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(
|
||||
onPressed: () => ref.read(videoPlayerProvider).playOrPause(),
|
||||
icon: playbackInfo.playing
|
||||
? Icon(Icons.pause_rounded)
|
||||
: Icon(Icons.play_arrow_rounded),
|
||||
? const Icon(Icons.pause_rounded)
|
||||
: const Icon(Icons.play_arrow_rounded),
|
||||
),
|
||||
),
|
||||
if (constraints.maxWidth > 500) ...{
|
||||
|
|
@ -176,14 +176,14 @@ class _CurrentlyPlayingBarState extends ConsumerState<FloatingPlayerBar> {
|
|||
),
|
||||
Tooltip(
|
||||
message: "Stop playback",
|
||||
waitDuration: Duration(milliseconds: 500),
|
||||
waitDuration: const Duration(milliseconds: 500),
|
||||
child: IconButton(
|
||||
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(),
|
||||
IconTheme(
|
||||
data: IconThemeData(size: 28),
|
||||
data: const IconThemeData(size: 28),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
|
|
@ -155,8 +155,8 @@ class _NavigationBodyState extends ConsumerState<NavigationBody> {
|
|||
child: widget.currentLocation.contains(SettingsRoute().route)
|
||||
? Card(
|
||||
color: Theme.of(context).colorScheme.primaryContainer,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(10),
|
||||
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