// Import file atau widget yang diperlukan
import '../helper/audio_query.dart';
import '../services/player_service.dart';
import '../widgets/empty_screen.dart';
import '../widgets/mini_player.dart';
import '../widgets/playlist_head.dart';
import '../widgets/snackbar.dart';
// Deklarasi class MyHomePage yang merupakan stateful widget
class MyHomePage extends StatefulWidget {
final List? cachedSongs;
final String? title;
final int? playlistId;
final bool showPlaylists;
const MyHomePage({
super.key,
this.cachedSongs,
this.title,
this.playlistId,
this.showPlaylists = false,
});
@override
State createState() => MyHomePageState();
}
// Deklarasi class MyHomePageState yang merupakan state dari MyHomePage
class MyHomePageState extends State with TickerProviderStateMixin {
// Inisialisasi variabel dan objek yang diperlukan
List _songs = [];
String? tempPath = Hive.box('settings').get('tempDirPath')?.toString();
final Map<String, List> _albums = {};
final Map<String, List> _artists = {};
final Map<String, List> _genres = {};
final Map<String, List> _folders = {};
final miniplayer = MiniPlayer();
final List _sortedAlbumKeysList = [];
final List _sortedArtistKeysList = [];
final List _sortedGenreKeysList = [];
final List _sortedFolderKeysList = [];
bool added = false;
int sortValue = Hive.box('settings').get('sortValue', defaultValue: 1) as int;
int orderValue = Hive.box('settings').get('orderValue', defaultValue: 1) as int;
int albumSortValue = Hive.box('settings').get('albumSortValue', defaultValue: 2) as int;
List dirPaths = Hive.box('settings').get('searchPaths', defaultValue: []) as List;
int minDuration = Hive.box('settings').get('minDuration', defaultValue: 30) as int;
bool includeOrExclude = Hive.box('settings').get('includeOrExclude', defaultValue: false) as bool;
List includedExcludedPaths = Hive.box('settings').get('includedExcludedPaths', defaultValue: []) as List;
TabController? _tcontroller;
int _currentTabIndex = 0;
OfflineAudioQuery offlineAudioQuery = OfflineAudioQuery();
List playlistDetails = {};
// Override method dispose untuk membersihkan sumber daya yang digunakan
@override
void dispose() {
super.dispose();
_tcontroller!.dispose();
}
// Method untuk memeriksa apakah lagu termasuk atau tidak termasuk
bool checkIncludedOrExcluded(SongModel song) {
for (final path in includedExcludedPaths) {
if (song.data.contains(path.toString())) return true;
}
return false;
}
// Method untuk mendapatkan data lagu
Future getData() async {
try {
// Meminta izin dan mendapatkan path sementara
await offlineAudioQuery.requestPermission();
tempPath ??= (await getTemporaryDirectory()).path;
// Mendapatkan detail playlist jika perangkat adalah Android
if (Platform.isAndroid) {
playlistDetails = await offlineAudioQuery.getPlaylists();
}
// Mendapatkan lagu-lagu offline
if (widget.cachedSongs == null) {
final receivedSongs = await offlineAudioQuery.getSongs(
sortType: songSortTypes[sortValue],
orderType: songOrderTypes[orderValue],
);
_songs = receivedSongs
.where(
(i) =>
(i.duration ?? 60000) > 1000 * minDuration &&
(i.isMusic! || i.isPodcast! || i.isAudioBook!) &&
(includeOrExclude
? checkIncludedOrExcluded(i)
: !checkIncludedOrExcluded(i)),
)
.toList();
} else {
_songs = widget.cachedSongs!;
}
added = true;
setState(() {});
// Membuat struktur data untuk album, artist, genre, dan folder
for (int i = 0; i < _songs.length; i++) {
try {
if (_albums.containsKey(_songs[i].album ?? 'Unknown')) {
_albums[_songs[i].album ?? 'Unknown']!.add(_songs[i]);
} else {
_albums[_songs[i].album ?? 'Unknown'] = [_songs[i]];
_sortedAlbumKeysList.add(_songs[i].album ?? 'Unknown');
}
if (_artists.containsKey(_songs[i].artist ?? 'Unknown')) {
_artists[_songs[i].artist ?? 'Unknown']!.add(_songs[i]);
} else {
_artists[_songs[i].artist ?? 'Unknown'] = [_songs[i]];
_sortedArtistKeysList.add(_songs[i].artist ?? 'Unknown');
}
if (_genres.containsKey(_songs[i].genre ?? 'Unknown')) {
_genres[_songs[i].genre ?? 'Unknown']!.add(_songs[i]);
} else {
_genres[_songs[i].genre ?? 'Unknown'] = [_songs[i]];
_sortedGenreKeysList.add(_songs[i].genre ?? 'Unknown');
}
final tempPath = _songs[i].data.split('/');
tempPath.removeLast();
final dirPath = tempPath.join('/');
if (_folders.containsKey(dirPath)) {
_folders[dirPath]!.add(_songs[i]);
} else {
_folders[dirPath] = [_songs[i]];
_sortedFolderKeysList.add(dirPath);
}
} catch (e) {
print(e);
}
}
// Override method build untuk membangun tampilan widget
@override
Widget build(BuildContext context) {
// Jika data belum siap, tampilkan loading
if (!added) {
return Scaffold(body: Center(child: CircularProgressIndicator()));
}
// Tampilan jika tidak ada lagu yang ditemukan
if (_songs.isEmpty) {
return const Scaffold(
body: Center(
child: EmptyScreen(
title: 'No songs found',
message: 'Please make sure you have some songs in your device.',
),
),
);
}
// Tampilan utama
return Scaffold(
// Tampilan app bar
appBar: AppBar(
// Judul app bar sesuai dengan tab yang dipilih
title: Text(
widget.showPlaylists
? (_currentTabIndex == 0
? 'All Songs'
: _currentTabIndex == 1
? 'Albums'
: _currentTabIndex == 2
? 'Artists'
: _currentTabIndex == 3
? 'Genres'
: _currentTabIndex == 4
? 'Folders'
: 'Playlists')
: (_currentTabIndex == 0
? 'All Songs'
: _currentTabIndex == 1
? 'Albums'
: _currentTabIndex == 2
? 'Artists'
: _currentTabIndex == 3
? 'Genres'
: 'Folders'),
),
// Tambahkan icon settings pada app bar
actions: [
IconButton(
onPressed: () async {
// Navigasi ke halaman Settings dan ambil hasil
final result = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => const SettingsPage()),
);
// Jika terdapat perubahan pada pengaturan, perbarui tampilan
if (result != null && result) {
getData();
}
},
icon: const Icon(Icons.settings),
)
],
// Tambahkan TabBar jika widget menunjukkan daftar putar
bottom: widget.showPlaylists
? TabBar(
// Kontrol TabBar
controller: _tcontroller,
// Atur indikator tab menjadi warna putih
indicatorColor: Colors.white,
// Atur warna latar belakang TabBar
tabs: const [
Tab(icon: Icon(Icons.music_note)),
Tab(icon: Icon(Icons.album)),
Tab(icon: Icon(Icons.person)),
Tab(icon: Icon(Icons.category)),
Tab(icon: Icon(Icons.folder)),
Tab(icon: Icon(Icons.playlist_play)),
],
)
: null,
),
// Tampilan utama body
body: TabBarView(
// Kontrol TabBarView
controller: _tcontroller,
// Daftar tampilan sesuai dengan tab yang dipilih
children: widget.showPlaylists
? [
AllSongs(
songs: _songs,
miniplayer: miniplayer,
),
PlaylistHead(
albums: _albums,
sortedAlbumKeysList: _sortedAlbumKeysList,
sortValue: albumSortValue,
),
PlaylistHead(
albums: _artists,
sortedAlbumKeysList: _sortedArtistKeysList,
sortValue: albumSortValue,
),
PlaylistHead(
albums: _genres,
sortedAlbumKeysList: _sortedGenreKeysList,
sortValue: albumSortValue,
),
PlaylistHead(
albums: _folders,
sortedAlbumKeysList: _sortedFolderKeysList,
sortValue: albumSortValue,
),
PlaylistHead(
playlists: playlistDetails,
type: 'playlist',
),
]
: [
AllSongs(
songs: _songs,
miniplayer: miniplayer,
),
PlaylistHead(
albums: _albums,
sortedAlbumKeysList: _sortedAlbumKeysList,
sortValue: albumSortValue,
),
PlaylistHead(
albums: _artists,
sortedAlbumKeysList: _sortedArtistKeysList,
sortValue: albumSortValue,
),
PlaylistHead(
albums: _genres,
sortedAlbumKeysList: _sortedGenreKeysList,
sortValue: albumSortValue,
),
PlaylistHead(
albums: _folders,
sortedAlbumKeysList: _sortedFolderKeysList,
sortValue: albumSortValue,
),
],
),
// Tambahkan MiniPlayer di bagian bawah layar
bottomSheet: miniplayer,
);
}
}
Dibawah ini adalah source code yang digunakan untuk membuat bagian halaman utama/halaman awal :
// Import library yang diperlukan import 'dart:io';
import 'package:flutter/material.dart'; import 'package:hive/hive.dart'; import 'package:music_player_app1/pages/settings.dart'; import 'package:on_audio_query/on_audio_query.dart'; import 'package:path_provider/path_provider.dart';
// Import file atau widget yang diperlukan import '../helper/audio_query.dart'; import '../services/player_service.dart'; import '../widgets/empty_screen.dart'; import '../widgets/mini_player.dart'; import '../widgets/playlist_head.dart'; import '../widgets/snackbar.dart';
// Deklarasi class MyHomePage yang merupakan stateful widget class MyHomePage extends StatefulWidget { final List? cachedSongs;
final String? title;
final int? playlistId;
final bool showPlaylists;
const MyHomePage({
super.key,
this.cachedSongs,
this.title,
this.playlistId,
this.showPlaylists = false,
});
@override State createState() => MyHomePageState();
}
// Deklarasi class MyHomePageState yang merupakan state dari MyHomePage class MyHomePageState extends State with TickerProviderStateMixin {
// Inisialisasi variabel dan objek yang diperlukan
List _songs = [];
String? tempPath = Hive.box('settings').get('tempDirPath')?.toString();
final Map<String, List> _albums = {};
final Map<String, List> _artists = {};
final Map<String, List> _genres = {};
final Map<String, List> _folders = {};
final miniplayer = MiniPlayer();
final List _sortedAlbumKeysList = [];
final List _sortedArtistKeysList = [];
final List _sortedGenreKeysList = [];
final List _sortedFolderKeysList = [];
bool added = false; int sortValue = Hive.box('settings').get('sortValue', defaultValue: 1) as int; int orderValue = Hive.box('settings').get('orderValue', defaultValue: 1) as int; int albumSortValue = Hive.box('settings').get('albumSortValue', defaultValue: 2) as int; List dirPaths = Hive.box('settings').get('searchPaths', defaultValue: []) as List; int minDuration = Hive.box('settings').get('minDuration', defaultValue: 30) as int; bool includeOrExclude = Hive.box('settings').get('includeOrExclude', defaultValue: false) as bool; List includedExcludedPaths = Hive.box('settings').get('includedExcludedPaths', defaultValue: []) as List; TabController? _tcontroller; int _currentTabIndex = 0; OfflineAudioQuery offlineAudioQuery = OfflineAudioQuery(); List playlistDetails = {};
final Map<int, SongSortType> songSortTypes = { 0: SongSortType.DISPLAY_NAME, 1: SongSortType.DATE_ADDED, 2: SongSortType.ALBUM, 3: SongSortType.ARTIST, 4: SongSortType.DURATION, 5: SongSortType.SIZE, };
final Map<int, OrderType> songOrderTypes = { 0: OrderType.ASC_OR_SMALLER, 1: OrderType.DESC_OR_GREATER, };
// Override method initState untuk inisialisasi state @override void initState() { // Inisialisasi TabController dan listener _tcontroller = TabController(length: widget.showPlaylists ? 6 : 5, vsync: this); _tcontroller!.addListener(() { if ((_tcontroller!.previousIndex != 0 && _tcontroller!.index == 0) || (_tcontroller!.previousIndex == 0)) { setState(() => _currentTabIndex = _tcontroller!.index); } }); // Panggil method getData getData(); super.initState(); }
// Override method dispose untuk membersihkan sumber daya yang digunakan @override void dispose() { super.dispose(); _tcontroller!.dispose(); }
// Method untuk memeriksa apakah lagu termasuk atau tidak termasuk bool checkIncludedOrExcluded(SongModel song) { for (final path in includedExcludedPaths) { if (song.data.contains(path.toString())) return true; } return false; }
// Method untuk mendapatkan data lagu Future getData() async {
try {
// Meminta izin dan mendapatkan path sementara
await offlineAudioQuery.requestPermission();
tempPath ??= (await getTemporaryDirectory()).path;
} catch (e) { print('Caught exception: $e'); setState(() {}); } }
// Override method build untuk membangun tampilan widget @override Widget build(BuildContext context) { // Jika data belum siap, tampilkan loading if (!added) { return Scaffold(body: Center(child: CircularProgressIndicator())); }
// Tampilan jika tidak ada lagu yang ditemukan if (_songs.isEmpty) { return const Scaffold( body: Center( child: EmptyScreen( title: 'No songs found', message: 'Please make sure you have some songs in your device.', ), ), ); }
// Tampilan utama return Scaffold( // Tampilan app bar appBar: AppBar( // Judul app bar sesuai dengan tab yang dipilih title: Text( widget.showPlaylists ? (_currentTabIndex == 0 ? 'All Songs' : _currentTabIndex == 1 ? 'Albums' : _currentTabIndex == 2 ? 'Artists' : _currentTabIndex == 3 ? 'Genres' : _currentTabIndex == 4 ? 'Folders' : 'Playlists') : (_currentTabIndex == 0 ? 'All Songs' : _currentTabIndex == 1 ? 'Albums' : _currentTabIndex == 2 ? 'Artists' : _currentTabIndex == 3 ? 'Genres' : 'Folders'), ), // Tambahkan icon settings pada app bar actions: [ IconButton( onPressed: () async { // Navigasi ke halaman Settings dan ambil hasil final result = await Navigator.push( context, MaterialPageRoute(builder: (context) => const SettingsPage()), ); // Jika terdapat perubahan pada pengaturan, perbarui tampilan if (result != null && result) { getData(); } }, icon: const Icon(Icons.settings), ) ], // Tambahkan TabBar jika widget menunjukkan daftar putar bottom: widget.showPlaylists ? TabBar( // Kontrol TabBar controller: _tcontroller, // Atur indikator tab menjadi warna putih indicatorColor: Colors.white, // Atur warna latar belakang TabBar tabs: const [ Tab(icon: Icon(Icons.music_note)), Tab(icon: Icon(Icons.album)), Tab(icon: Icon(Icons.person)), Tab(icon: Icon(Icons.category)), Tab(icon: Icon(Icons.folder)), Tab(icon: Icon(Icons.playlist_play)), ], ) : null, ), // Tampilan utama body body: TabBarView( // Kontrol TabBarView controller: _tcontroller, // Daftar tampilan sesuai dengan tab yang dipilih children: widget.showPlaylists ? [ AllSongs( songs: _songs, miniplayer: miniplayer, ), PlaylistHead( albums: _albums, sortedAlbumKeysList: _sortedAlbumKeysList, sortValue: albumSortValue, ), PlaylistHead( albums: _artists, sortedAlbumKeysList: _sortedArtistKeysList, sortValue: albumSortValue, ), PlaylistHead( albums: _genres, sortedAlbumKeysList: _sortedGenreKeysList, sortValue: albumSortValue, ), PlaylistHead( albums: _folders, sortedAlbumKeysList: _sortedFolderKeysList, sortValue: albumSortValue, ), PlaylistHead( playlists: playlistDetails, type: 'playlist', ), ] : [ AllSongs( songs: _songs, miniplayer: miniplayer, ), PlaylistHead( albums: _albums, sortedAlbumKeysList: _sortedAlbumKeysList, sortValue: albumSortValue, ), PlaylistHead( albums: _artists, sortedAlbumKeysList: _sortedArtistKeysList, sortValue: albumSortValue, ), PlaylistHead( albums: _genres, sortedAlbumKeysList: _sortedGenreKeysList, sortValue: albumSortValue, ), PlaylistHead( albums: _folders, sortedAlbumKeysList: _sortedFolderKeysList, sortValue: albumSortValue, ), ], ), // Tambahkan MiniPlayer di bagian bawah layar bottomSheet: miniplayer, ); } }