mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-09-02 16:20:57 +02:00
refactor(core): reduce generated and duplicate code
This commit is contained in:
@@ -29,6 +29,9 @@ AGENTS.md
|
||||
*.aab
|
||||
*.ipa
|
||||
|
||||
# Generated by Flutter from lib/l10n/arb during pub get/build.
|
||||
/lib/l10n/app_localizations*.dart
|
||||
|
||||
# Local JavaScript tooling (the app itself has no Node dependency)
|
||||
/node_modules/
|
||||
/bun.lock
|
||||
|
||||
@@ -118,16 +118,11 @@ func TestLifecycleTimeoutQuarantinesUnresponsiveCleanupVM(t *testing.T) {
|
||||
|
||||
func TestSignedSessionGrantRetryHonorsCancellationAndReleasesCoordinator(t *testing.T) {
|
||||
previousWait := signedSessionRetryWaitContext
|
||||
previousLegacyWait := signedSessionRetryWait
|
||||
signedSessionRetryWait = nil
|
||||
signedSessionRetryWaitContext = func(ctx context.Context, _ time.Duration) error {
|
||||
<-ctx.Done()
|
||||
return ctx.Err()
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
signedSessionRetryWait = previousLegacyWait
|
||||
signedSessionRetryWaitContext = previousWait
|
||||
})
|
||||
t.Cleanup(func() { signedSessionRetryWaitContext = previousWait })
|
||||
|
||||
var calls atomic.Int32
|
||||
transport := roundTripFunc(func(req *http.Request) (*http.Response, error) {
|
||||
|
||||
@@ -780,10 +780,6 @@ func (r *extensionRuntime) RegisterAPIs(vm *goja.Runtime) {
|
||||
logObj.Set("error", r.logError)
|
||||
vm.Set("log", logObj)
|
||||
|
||||
gobackendObj := vm.NewObject()
|
||||
gobackendObj.Set("sanitizeFilename", r.sanitizeFilenameWrapper)
|
||||
vm.Set("gobackend", gobackendObj)
|
||||
|
||||
vm.Set("fetch", r.fetchPolyfill)
|
||||
|
||||
vm.Set("atob", r.atobPolyfill)
|
||||
|
||||
@@ -1144,9 +1144,6 @@ func TestExtensionRuntimeUtilityAPIs(t *testing.T) {
|
||||
runtime.logInfo(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("info")}})
|
||||
runtime.logWarn(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("warn")}})
|
||||
runtime.logError(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("error")}})
|
||||
if clean := runtime.sanitizeFilenameWrapper(goja.FunctionCall{Arguments: []goja.Value{vm.ToValue("A/B?")}}).String(); strings.ContainsAny(clean, "/?") {
|
||||
t.Fatalf("sanitize wrapper = %q", clean)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClassifySignedSessionExpiredAsVerification(t *testing.T) {
|
||||
|
||||
@@ -372,14 +372,6 @@ func (r *extensionRuntime) formatLogArgs(args []goja.Value) string {
|
||||
return strings.Join(parts, " ")
|
||||
}
|
||||
|
||||
func (r *extensionRuntime) sanitizeFilenameWrapper(call goja.FunctionCall) goja.Value {
|
||||
if len(call.Arguments) < 1 {
|
||||
return r.vm.ToValue("")
|
||||
}
|
||||
input := call.Arguments[0].String()
|
||||
return r.vm.ToValue(sanitizeFilename(input))
|
||||
}
|
||||
|
||||
func (r *extensionRuntime) RegisterGoBackendAPIs(vm *goja.Runtime) {
|
||||
gobackendObj := vm.Get("gobackend")
|
||||
if gobackendObj == nil || goja.IsUndefined(gobackendObj) {
|
||||
|
||||
@@ -36,13 +36,9 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
pendingSignedSessionGrants = make(map[string]string)
|
||||
pendingSignedSessionGrantsMu sync.Mutex
|
||||
signedSessionCoordinators sync.Map
|
||||
// signedSessionRetryWait is retained as a test hook for callers that used
|
||||
// the old duration-only seam. Production waits use the context-aware hook
|
||||
// below; a non-nil legacy hook short-circuits the delay in tests.
|
||||
signedSessionRetryWait func(time.Duration)
|
||||
pendingSignedSessionGrants = make(map[string]string)
|
||||
pendingSignedSessionGrantsMu sync.Mutex
|
||||
signedSessionCoordinators sync.Map
|
||||
signedSessionRetryWaitContext = sleepRetry
|
||||
signedSessionProviderWait = sleepRetry
|
||||
signedSessionRequestNow = time.Now
|
||||
@@ -654,22 +650,6 @@ func waitSignedSessionRetry(ctx context.Context, delay time.Duration) error {
|
||||
if ctx == nil {
|
||||
ctx = context.Background()
|
||||
}
|
||||
// Keep the old duration-only hook useful for existing package tests without
|
||||
// allowing production to fall back to an uninterruptible time.Sleep. The
|
||||
// default hook is nil; tests install an immediate recorder/no-op here.
|
||||
if legacyWait := signedSessionRetryWait; legacyWait != nil {
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
legacyWait(delay)
|
||||
close(done)
|
||||
}()
|
||||
select {
|
||||
case <-done:
|
||||
return nil
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
}
|
||||
return signedSessionRetryWaitContext(ctx, delay)
|
||||
}
|
||||
|
||||
|
||||
@@ -1836,12 +1836,13 @@ func TestExchangeSignedSessionGrant(t *testing.T) {
|
||||
pendingSignedSessionGrantsMu.Lock()
|
||||
pendingSignedSessionGrants = make(map[string]string)
|
||||
pendingSignedSessionGrantsMu.Unlock()
|
||||
previousWait := signedSessionRetryWait
|
||||
previousWait := signedSessionRetryWaitContext
|
||||
var waits []time.Duration
|
||||
signedSessionRetryWait = func(delay time.Duration) {
|
||||
signedSessionRetryWaitContext = func(_ context.Context, delay time.Duration) error {
|
||||
waits = append(waits, delay)
|
||||
return nil
|
||||
}
|
||||
t.Cleanup(func() { signedSessionRetryWait = previousWait })
|
||||
t.Cleanup(func() { signedSessionRetryWaitContext = previousWait })
|
||||
|
||||
calls := 0
|
||||
transport := roundTripFunc(func(req *http.Request) (*http.Response, error) {
|
||||
@@ -1895,9 +1896,11 @@ func TestExchangeSignedSessionGrant(t *testing.T) {
|
||||
pendingSignedSessionGrantsMu.Lock()
|
||||
pendingSignedSessionGrants = make(map[string]string)
|
||||
pendingSignedSessionGrantsMu.Unlock()
|
||||
previousWait := signedSessionRetryWait
|
||||
signedSessionRetryWait = func(time.Duration) {}
|
||||
t.Cleanup(func() { signedSessionRetryWait = previousWait })
|
||||
previousWait := signedSessionRetryWaitContext
|
||||
signedSessionRetryWaitContext = func(context.Context, time.Duration) error {
|
||||
return nil
|
||||
}
|
||||
t.Cleanup(func() { signedSessionRetryWaitContext = previousWait })
|
||||
|
||||
calls := 0
|
||||
transport := roundTripFunc(func(req *http.Request) (*http.Response, error) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -216,16 +216,4 @@ class CacheStats {
|
||||
final int totalSizeBytes;
|
||||
|
||||
const CacheStats({required this.fileCount, required this.totalSizeBytes});
|
||||
|
||||
String get formattedSize {
|
||||
if (totalSizeBytes < 1024) {
|
||||
return '$totalSizeBytes B';
|
||||
} else if (totalSizeBytes < 1024 * 1024) {
|
||||
return '${(totalSizeBytes / 1024).toStringAsFixed(1)} KB';
|
||||
} else if (totalSizeBytes < 1024 * 1024 * 1024) {
|
||||
return '${(totalSizeBytes / (1024 * 1024)).toStringAsFixed(1)} MB';
|
||||
} else {
|
||||
return '${(totalSizeBytes / (1024 * 1024 * 1024)).toStringAsFixed(2)} GB';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:sqflite/sqflite.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:spotiflac_android/services/sqlite_helpers.dart' as sqlite;
|
||||
import 'package:spotiflac_android/utils/isrc_utils.dart' as isrc;
|
||||
import 'package:spotiflac_android/utils/logger.dart';
|
||||
import 'package:spotiflac_android/utils/path_match_keys.dart';
|
||||
|
||||
@@ -286,9 +287,7 @@ class HistoryDatabase {
|
||||
static String normalizeLookupText(String? value) =>
|
||||
sqlite.normalizeLookupText(value);
|
||||
|
||||
static String normalizeIsrc(String? value) {
|
||||
return (value ?? '').trim().toUpperCase().replaceAll(RegExp(r'[-\s]'), '');
|
||||
}
|
||||
static String normalizeIsrc(String? value) => isrc.normalizeIsrc(value);
|
||||
|
||||
static String normalizeSpotifyId(String? value) {
|
||||
return (value ?? '').trim().toLowerCase();
|
||||
|
||||
@@ -240,8 +240,6 @@ class LocalLibrarySource {
|
||||
|
||||
enum LocalLibrarySortMode { album, title, artist, latest, quality }
|
||||
|
||||
enum LocalLibraryFilterMode { all, albums, singles }
|
||||
|
||||
class LocalLibraryLookupIndex {
|
||||
final Set<String> isrcs;
|
||||
final Set<String> matchKeys;
|
||||
|
||||
@@ -254,13 +254,3 @@ void precacheCoverImage(BuildContext context, String? url) {
|
||||
context,
|
||||
);
|
||||
}
|
||||
|
||||
int coverImageCacheExtent(
|
||||
BuildContext context,
|
||||
double logicalSize, {
|
||||
int min = 64,
|
||||
int max = 512,
|
||||
}) {
|
||||
final dpr = MediaQuery.devicePixelRatioOf(context).clamp(1.0, 3.0).toDouble();
|
||||
return (logicalSize * dpr).round().clamp(min, max).toInt();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user