Issue #1: CloudScreen Zurück-Button — onZurueck Callback statt Navigator.pop() - CloudScreen erhält VoidCallback? onZurueck Parameter - Bei onZurueck != null → Callback (Tab-Wechsel in home_screen) - Fallback: Navigator.pop(context) für Standalone-Nutzung Issue #5: Token wird nur bei HTTP 401 gelöscht - _tokenOnlinePruefen(): nur statusCode == 401 → false - 5xx, andere Fehler, Netzwerkfehler → true (Token behalten) - Verhindert Ausloggen bei temporären Server-Problemen Issue #4: Android 13+ Berechtigungen beim App-Start - main.dart: frageSpeicherZugriff() + POST_NOTIFICATIONS nach Auth-Init - musik_scanner.dart: Permission-Check vor externen Ordnern in _sammleMusikPfade() Build: ⏭️ (no APK)
This commit is contained in:
@@ -1,12 +1,15 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'dart:io' show Platform;
|
||||
import 'package:audio_service/audio_service.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'database/db_helper.dart';
|
||||
import 'services/favoriten_service.dart';
|
||||
import 'services/auth_service.dart';
|
||||
import 'services/cloud_service.dart';
|
||||
import 'services/melo_logger.dart';
|
||||
import 'services/audio_handler.dart';
|
||||
import 'services/musik_scanner.dart';
|
||||
import 'utils/farb_theme.dart';
|
||||
import 'screens/home_screen.dart';
|
||||
import 'screens/login_screen.dart';
|
||||
@@ -37,6 +40,15 @@ void main() async {
|
||||
// Auth initialisieren (Token aus SharedPreferences laden + online validieren)
|
||||
await AuthService().initialisieren();
|
||||
|
||||
// Android-Berechtigungen beim Start abfragen (Issue #4)
|
||||
// Speicherzugriff für Musik-Scan (READ_MEDIA_AUDIO / Storage)
|
||||
await MusikScanner().frageSpeicherZugriff();
|
||||
|
||||
// POST_NOTIFICATIONS für Android 13+ (Notifications für Downloads, Player)
|
||||
if (Platform.isAndroid) {
|
||||
await Permission.notification.request();
|
||||
}
|
||||
|
||||
// Auto-Sync beim Start (wenn eingeloggt und Auto-Sync aktiv)
|
||||
_starteAutoSyncFallsNoetig();
|
||||
|
||||
|
||||
@@ -13,7 +13,8 @@ import '../services/melo_logger.dart';
|
||||
/// Playlisten, Favoriten, Auto-Sync, Persistent Login, Benutzerdefinierte Namen
|
||||
class CloudScreen extends StatefulWidget {
|
||||
final CloudService cloud;
|
||||
const CloudScreen({super.key, required this.cloud});
|
||||
final VoidCallback? onZurueck;
|
||||
const CloudScreen({super.key, required this.cloud, this.onZurueck});
|
||||
|
||||
@override
|
||||
State<CloudScreen> createState() => _CloudScreenState();
|
||||
@@ -590,7 +591,13 @@ class _CloudScreenState extends State<CloudScreen> {
|
||||
backgroundColor: MeloTheme.dunkel1,
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.arrow_back, color: Colors.white, size: 22),
|
||||
onPressed: () => Navigator.pop(context),
|
||||
onPressed: () {
|
||||
if (widget.onZurueck != null) {
|
||||
widget.onZurueck!();
|
||||
} else {
|
||||
Navigator.pop(context);
|
||||
}
|
||||
},
|
||||
),
|
||||
title: const Row(
|
||||
children: [
|
||||
|
||||
@@ -303,7 +303,10 @@ class _MeloHomeState extends State<MeloHome> {
|
||||
onSongsChanged: _vm.ladeSongs,
|
||||
)
|
||||
: _aktiverTab == 4
|
||||
? CloudScreen(cloud: _cloud)
|
||||
? CloudScreen(
|
||||
cloud: _cloud,
|
||||
onZurueck: () => setState(() => _aktiverTab = 0),
|
||||
)
|
||||
: Column(
|
||||
children: [
|
||||
MeloHeader(onDownload: _zeigeDownloadDialog, onSearch: _zeigeSuche, onServer: _zeigeServerBrowser),
|
||||
|
||||
@@ -69,7 +69,11 @@ class AuthService {
|
||||
headers: authHeader,
|
||||
)
|
||||
.timeout(const Duration(seconds: 5));
|
||||
return response.statusCode == 200;
|
||||
if (response.statusCode == 200) return true;
|
||||
// Nur bei explizitem 401 (abgelaufen/ungültig) den Token löschen.
|
||||
// Bei 5xx, anderen Fehlern oder temporären Server-Problemen Token behalten.
|
||||
if (response.statusCode == 401) return false;
|
||||
return true;
|
||||
} catch (_) {
|
||||
// Bei Netzwerkfehler: Token lokal akzeptieren (Offline-Modus)
|
||||
return true;
|
||||
|
||||
@@ -135,8 +135,11 @@ class MusikScanner {
|
||||
MeloLogger().fehler('scanner_intern_pfad', e);
|
||||
}
|
||||
|
||||
// 2. Externe System-Ordner (nur Android)
|
||||
// 2. Externe System-Ordner (nur Android, nur wenn Berechtigung vorhanden)
|
||||
if (Platform.isAndroid) {
|
||||
final hatZugriff = await frageSpeicherZugriff();
|
||||
if (!hatZugriff) return pfade.toList();
|
||||
|
||||
final ordner = <String>[
|
||||
'/storage/emulated/0/Music',
|
||||
'/storage/emulated/0/Download',
|
||||
|
||||
Reference in New Issue
Block a user