Skip to content

Commit

Permalink
feat: track caching and cached track export support (KRTirtho#2117)
Browse files Browse the repository at this point in the history
* feat: add caching support with track metadata

* feat(settings): add cache music toggle

* fix(mobile): cache dir not open-able

* feat(local folder): add cache export/clear actions and size of the folder

* chore: ios deps upgrades

* chore: upgrade lint flutter version

* chore: lint secrets causing error

* cd: invalid value for env var
  • Loading branch information
KRTirtho authored and richard-hajek committed Jan 18, 2025
1 parent a0e0bd8 commit 1231892
Show file tree
Hide file tree
Showing 47 changed files with 5,223 additions and 324 deletions.
12 changes: 6 additions & 6 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# The format:
# SPOTIFY_SECRETS=clintId1:clientSecret1,clientId2:clientSecret2
SPOTIFY_SECRETS=
SPOTIFY_SECRETS=$SPOTIFY_SECRETS

# 0 or 1
# 0 = disable
# 1 = enable
ENABLE_UPDATE_CHECK=
ENABLE_UPDATE_CHECK=$ENABLE_UPDATE_CHECK

LASTFM_API_KEY=
LASTFM_API_SECRET=
LASTFM_API_KEY=$LASTFM_API_KEY
LASTFM_API_SECRET=$LASTFM_API_SECRET

# Release channel. Can be: nightly, stable
RELEASE_CHANNEL=
RELEASE_CHANNEL=$RELEASE_CHANNEL

HIDE_DONATIONS=
HIDE_DONATIONS=$HIDE_DONATIONS
23 changes: 14 additions & 9 deletions .github/workflows/pr-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
pull_request:

env:
FLUTTER_VERSION: 3.22.2
FLUTTER_VERSION: 3.24.5

jobs:
lint:
Expand All @@ -17,18 +17,23 @@ jobs:
with:
flutter-version: ${{ env.FLUTTER_VERSION }}

- name: Dummy Envs
run: |
envsubst < .env.example > .env
env:
SPOTIFY_SECRETS: xxx:xxx
ENABLE_UPDATE_CHECK: true
LASTFM_API_KEY: xxx
LASTFM_API_SECRET: xxx
RELEASE_CHANNEL: nightly
HIDE_DONATIONS: 0


- name: Configure repo
run: |
flutter pub get
echo '${{ secrets.DOTENV_NIGHTLY }}' > .env
dart run build_runner build --delete-conflicting-outputs
- name: Lint Dart files
run: |
dart analyze --no-fatal-warnings
- name: Lint translations & config files
run: |
npm install -g @prantlf/jsonlint
jsonlint -q -D --enforce-double-quotes ./lib/l10n/*.arb
jsonlint -q -D --enforce-double-quotes -T .vscode/*.json
dart analyze --no-fatal-warnings
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,7 @@ apk:
mv build/app/outputs/apk/release/app-release.apk build/Spotube-android-all-arch.apk

gensums:
sh -c scripts/gensums.sh
sh -c scripts/gensums.sh

migrate:
dart run drift_dev make-migrations
1 change: 1 addition & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@ analyzer:
- "**.g.dart"
- "**.gr.dart"
- "**/generated_plugin_registrant.dart"
- test/**/*.dart
1 change: 1 addition & 0 deletions drift_schemas/app_db/drift_schema_v3.json

Large diffs are not rendered by default.

57 changes: 33 additions & 24 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ PODS:
- flutter_inappwebview_ios/Core (0.0.1):
- Flutter
- OrderedSet (~> 6.0.3)
- flutter_native_splash (0.0.1):
- flutter_native_splash (2.4.3):
- Flutter
- flutter_secure_storage (6.0.0):
- Flutter
Expand All @@ -74,6 +74,8 @@ PODS:
- Flutter
- metadata_god (0.0.1):
- Flutter
- open_file_ios (0.0.1):
- Flutter
- OrderedSet (6.0.3)
- package_info_plus (0.4.5):
- Flutter
Expand All @@ -88,21 +90,24 @@ PODS:
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
- sqflite (0.0.3):
- sqflite_darwin (0.0.4):
- Flutter
- FlutterMacOS
- "sqlite3 (3.46.0+1)":
- "sqlite3/common (= 3.46.0+1)"
- "sqlite3/common (3.46.0+1)"
- "sqlite3/fts5 (3.46.0+1)":
- sqlite3 (3.47.1):
- sqlite3/common (= 3.47.1)
- sqlite3/common (3.47.1)
- sqlite3/dbstatvtab (3.47.1):
- sqlite3/common
- sqlite3/fts5 (3.47.1):
- sqlite3/common
- "sqlite3/perf-threadsafe (3.46.0+1)":
- sqlite3/perf-threadsafe (3.47.1):
- sqlite3/common
- "sqlite3/rtree (3.46.0+1)":
- sqlite3/rtree (3.47.1):
- sqlite3/common
- sqlite3_flutter_libs (0.0.1):
- Flutter
- sqlite3 (~> 3.46.0)
- sqlite3 (~> 3.47.0)
- sqlite3/dbstatvtab
- sqlite3/fts5
- sqlite3/perf-threadsafe
- sqlite3/rtree
Expand Down Expand Up @@ -130,11 +135,12 @@ DEPENDENCIES:
- media_kit_libs_ios_audio (from `.symlinks/plugins/media_kit_libs_ios_audio/ios`)
- media_kit_native_event_loop (from `.symlinks/plugins/media_kit_native_event_loop/ios`)
- metadata_god (from `.symlinks/plugins/metadata_god/ios`)
- open_file_ios (from `.symlinks/plugins/open_file_ios/ios`)
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
- sqflite (from `.symlinks/plugins/sqflite/darwin`)
- sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`)
- sqlite3_flutter_libs (from `.symlinks/plugins/sqlite3_flutter_libs/ios`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)

Expand Down Expand Up @@ -186,6 +192,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/media_kit_native_event_loop/ios"
metadata_god:
:path: ".symlinks/plugins/metadata_god/ios"
open_file_ios:
:path: ".symlinks/plugins/open_file_ios/ios"
package_info_plus:
:path: ".symlinks/plugins/package_info_plus/ios"
path_provider_foundation:
Expand All @@ -194,8 +202,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/permission_handler_apple/ios"
shared_preferences_foundation:
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
sqflite:
:path: ".symlinks/plugins/sqflite/darwin"
sqflite_darwin:
:path: ".symlinks/plugins/sqflite_darwin/darwin"
sqlite3_flutter_libs:
:path: ".symlinks/plugins/sqlite3_flutter_libs/ios"
url_launcher_ios:
Expand All @@ -206,35 +214,36 @@ SPEC CHECKSUMS:
audio_service: f509d65da41b9521a61f1c404dd58651f265a567
audio_session: 088d2483ebd1dc43f51d253d4a1c517d9a2e7207
bonsoir_darwin: e3b8526c42ca46a885142df84229131dfabea842
device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d
device_info_plus: bf2e3232933866d73fe290f2942f2156cdd10342
DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac
DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179
file_picker: 09aa5ec1ab24135ccd7a1621c46c84134bfd6655
file_selector_ios: 78baf21d03f1e37a7df97bb2494f9cd86de8fa5d
file_selector_ios: f0670c1064a8c8450e38145d8043160105d0b97c
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_broadcasts: 3ece15b27d8ccbe2132c3df303e7c3401feab882
flutter_discord_rpc: e1c342f29ceb9dd76cdc01db59a70c93bb4d9ec5
flutter_inappwebview_ios: 6f63631e2c62a7c350263b13fa5427aedefe81d4
flutter_native_splash: edf599c81f74d093a4daf8e17bd7a018854bc778
flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be
flutter_native_splash: e8a1e01082d97a8099d973f919f57904c925008a
flutter_secure_storage: d33dac7ae2ea08509be337e775f6b59f1ff45f12
flutter_sharing_intent: e35380d0e1501d7111dbb7e46d5ac6339da6da98
image_picker_ios: b545a5f16c0fa88e3ecbbce3ed4de45567a8ec18
image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1
integration_test: 252f60fa39af5e17c3aa9899d35d908a0721b573
media_kit_libs_ios_audio: 8f39d96a9c630685dfb844c289bd1d114c486fb3
media_kit_native_event_loop: 99111eded5acbdc9c2738021ea6550dd36ca8837
metadata_god: 4bbd8523cdb5d42c5e59d2fabad01ff8f4bc53f9
open_file_ios: 461db5853723763573e140de3193656f91990d9e
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
package_info_plus: 58f0028419748fad15bf008b270aaa8e54380b1c
path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2
SDWebImage: a81bbb3ba4ea5f810f4069c68727cb118467a04a
shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
sqlite3: 292c3e1bfe89f64e51ea7fc7dab9182a017c8630
sqlite3_flutter_libs: 0d611efdf6d1c9297d5ab03dab21b75aeebdae31
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d
sqlite3: 1e522f0938463e44b7faf50393b40bdc1e1e456d
sqlite3_flutter_libs: b55ef23cfafea5318ae5081e0bf3fbbce8417c94
SwiftyGif: 93a1cc87bf3a51916001cf8f3d63835fb64c819f
url_launcher_ios: 6116280ddcfe98ab8820085d8d76ae7449447586
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe

PODFILE CHECKSUM: 0659b64ac6e9e96b61d8550decffa8bff51a957e

COCOAPODS: 1.15.2
COCOAPODS: 1.16.2
2 changes: 1 addition & 1 deletion ios/Runner/AppDelegate.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import UIKit
import Flutter

@UIApplicationMain
@main
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
Expand Down
13 changes: 11 additions & 2 deletions lib/collections/assets.gen.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 6 additions & 3 deletions lib/collections/routes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,12 @@ final routerProvider = Provider((ref) {
pageBuilder: (context, state) {
assert(state.extra is String);
return SpotubePage(
child: LocalLibraryPage(state.extra as String,
isDownloads:
state.uri.queryParameters["downloads"] != null),
child: LocalLibraryPage(
state.extra as String,
isDownloads:
state.uri.queryParameters["downloads"] != null,
isCache: state.uri.queryParameters["cache"] != null,
),
);
},
),
Expand Down
3 changes: 3 additions & 0 deletions lib/collections/spotube_icons.dart
Original file line number Diff line number Diff line change
Expand Up @@ -124,4 +124,7 @@ abstract class SpotubeIcons {
static const chart = FeatherIcons.barChart2;
static const folderAdd = FeatherIcons.folderPlus;
static const folderRemove = FeatherIcons.folderMinus;
static const cache = FeatherIcons.hardDrive;
static const export = Icons.file_open_outlined;
static const delete = FeatherIcons.trash2;
}
28 changes: 28 additions & 0 deletions lib/extensions/track.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'dart:io';
import 'dart:typed_data';

import 'package:metadata_god/metadata_god.dart';
import 'package:path/path.dart';
Expand Down Expand Up @@ -37,6 +38,33 @@ extension TrackExtensions on Track {

return this;
}

Metadata toMetadata({
required int fileLength,
Uint8List? imageBytes,
}) {
return Metadata(
title: name,
artist: artists?.map((a) => a.name).join(", "),
album: album?.name,
albumArtist: artists?.map((a) => a.name).join(", "),
year: album?.releaseDate != null
? int.tryParse(album!.releaseDate!.split("-").first) ?? 1969
: 1969,
trackNumber: trackNumber,
discNumber: discNumber,
durationMs: durationMs?.toDouble() ?? 0.0,
fileSize: BigInt.from(fileLength),
trackTotal: album?.tracks?.length ?? 0,
picture: imageBytes != null
? Picture(
data: imageBytes,
// Spotify images are always JPEGs
mimeType: 'image/jpeg',
)
: null,
);
}
}

extension TrackSimpleExtensions on TrackSimple {
Expand Down
25 changes: 16 additions & 9 deletions lib/hooks/utils/use_custom_status_bar_color.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,27 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart';

void useCustomStatusBarColor(
VoidCallback useCustomStatusBarColor(
Color color,
bool isCurrentRoute, {
bool noSetBGColor = false,
bool? automaticSystemUiAdjustment,
}) {
final context = useContext();
final backgroundColor = Theme.of(context).scaffoldBackgroundColor;
resetStatusbar() => SystemChrome.setSystemUIOverlayStyle(
SystemUiOverlayStyle(
statusBarColor: backgroundColor, // status bar color
statusBarIconBrightness: backgroundColor.computeLuminance() > 0.179
? Brightness.dark
: Brightness.light,
),
);
// ignore: invalid_use_of_visible_for_testing_member
final previousState = SystemChrome.latestStyle;

void resetStatusbar() => previousState != null
? SystemChrome.setSystemUIOverlayStyle(previousState)
: SystemChrome.setSystemUIOverlayStyle(
SystemUiOverlayStyle(
statusBarColor: backgroundColor, // status bar color
statusBarIconBrightness: backgroundColor.computeLuminance() > 0.179
? Brightness.dark
: Brightness.light,
),
);

// ignore: invalid_use_of_visible_for_testing_member
final statusBarColor = SystemChrome.latestStyle?.statusBarColor;
Expand Down Expand Up @@ -54,4 +59,6 @@ void useCustomStatusBarColor(
useEffect(() {
return resetStatusbar;
}, []);

return resetStatusbar;
}
12 changes: 11 additions & 1 deletion lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -391,5 +391,15 @@
"total_money": "Total {money}",
"webview_not_found": "Webview not found",
"webview_not_found_description": "No webview runtime is installed in your device.\nIf it's installed make sure it's in the Environment PATH\n\nAfter installing, restart the app",
"unsupported_platform": "Unsupported platform"
"unsupported_platform": "Unsupported platform",
"cache_music": "Cache music",
"open": "Open",
"cache_folder": "Cache folder",
"export": "Export",
"clear_cache": "Clear cache",
"clear_cache_confirmation": "Do you want to clear the cache?",
"export_cache_files": "Export Cached Files",
"found_n_files": "Found {count} files",
"export_cache_confirmation": "Do you want to export these files to",
"exported_n_out_of_m_files": "Exported {filesExported} out of {files} files"
}
Loading

0 comments on commit 1231892

Please sign in to comment.