Flutter Music Application

 Alif Adrian Anzary - 5025201274

Pada tugas kali ini akan mencoba membuat sebuah aplikasi musik menggunakan framework Flutter. Aplikasi ini nantinya dapat memutar musik, melihat daftar lagu, melihat artist dan lagu-lagunya, dan masih banyak lagi. Aplikasi ini dibuat dengan mengikuti panduan dari Codelabs dengan melewati beberapa step. Berikut adalah implementasi kode yang saya gunakan:

extensions.dart

import 'package:flutter/material.dart';

import 'package:google_fonts/google_fonts.dart';

// Add Google Fonts Package import


extension TypographyUtils on BuildContext {

  ThemeData get theme => Theme.of(this);

  TextTheme get textTheme =>

      GoogleFonts.montserratTextTheme(theme.textTheme); // Modify this line

  ColorScheme get colors => theme.colorScheme;

  TextStyle? get displayLarge => textTheme.displayLarge?.copyWith(

        color: colors.onSurface,

      );

  TextStyle? get displayMedium => textTheme.displayMedium?.copyWith(

        color: colors.onSurface,

      );

  TextStyle? get displaySmall => textTheme.displaySmall?.copyWith(

        color: colors.onSurface,

      );

  TextStyle? get headlineLarge => textTheme.headlineLarge?.copyWith(

        color: colors.onSurface,

      );

  TextStyle? get headlineMedium => textTheme.headlineMedium?.copyWith(

        color: colors.onSurface,

      );

  TextStyle? get headlineSmall => textTheme.headlineSmall?.copyWith(

        color: colors.onSurface,

      );

  TextStyle? get titleLarge => textTheme.titleLarge?.copyWith(

        color: colors.onSurface,

      );

  TextStyle? get titleMedium => textTheme.titleMedium?.copyWith(

        color: colors.onSurface,

      );

  TextStyle? get titleSmall => textTheme.titleSmall?.copyWith(

        color: colors.onSurface,

      );

  TextStyle? get labelLarge => textTheme.labelLarge?.copyWith(

        color: colors.onSurface,

      );

  TextStyle? get labelMedium => textTheme.labelMedium?.copyWith(

        color: colors.onSurface,

      );

  TextStyle? get labelSmall => textTheme.labelSmall?.copyWith(

        color: colors.onSurface,

      );

  TextStyle? get bodyLarge => textTheme.bodyLarge?.copyWith(

        color: colors.onSurface,

      );

  TextStyle? get bodyMedium => textTheme.bodyMedium?.copyWith(

        color: colors.onSurface,

      );

  TextStyle? get bodySmall => textTheme.bodySmall?.copyWith(

        color: colors.onSurface,

      );

}


extension BreakpointUtils on BoxConstraints {

  bool get isTablet => maxWidth > 730;

  bool get isDesktop => maxWidth > 1200;

  bool get isMobile => !isTablet && !isDesktop;

}


extension DurationString on String {

  /// Assumes a string (roughly) of the format '\d{1,2}:\d{2}'

  Duration toDuration() => switch (split(':')) {

        [var minutes, var seconds] => Duration(

            minutes: int.parse(minutes.trim()),

            seconds: int.parse(seconds.trim()),

          ),

        [var hours, var minutes, var seconds] => Duration(

            hours: int.parse(hours.trim()),

            minutes: int.parse(minutes.trim()),

            seconds: int.parse(seconds.trim()),

          ),

        _ => throw Exception('Invalid duration string: $this'),

      };

}


extension HumanizedDuration on Duration {

  String toHumanizedString() {

    final seconds = '${inSeconds % 60}'.padLeft(2, '0');

    String minutes = '${inMinutes % 60}';

    if (inHours > 0 || inMinutes == 0) {

      minutes = minutes.padLeft(2, '0');

    }

    String value = '$minutes:$seconds';

    if (inHours > 0) {

      value = '$inHours:$minutes:$seconds';

    }

    return value;

  }

}

router.dart

import 'package:flutter/material.dart';

import 'package:google_fonts/google_fonts.dart';

// Add Google Fonts Package import


extension TypographyUtils on BuildContext {

  ThemeData get theme => Theme.of(this);

  TextTheme get textTheme =>

      GoogleFonts.montserratTextTheme(theme.textTheme); // Modify this line

  ColorScheme get colors => theme.colorScheme;

  TextStyle? get displayLarge => textTheme.displayLarge?.copyWith(

        color: colors.onSurface,

      );

  TextStyle? get displayMedium => textTheme.displayMedium?.copyWith(

        color: colors.onSurface,

      );

  TextStyle? get displaySmall => textTheme.displaySmall?.copyWith(

        color: colors.onSurface,

      );

  TextStyle? get headlineLarge => textTheme.headlineLarge?.copyWith(

        color: colors.onSurface,

      );

  TextStyle? get headlineMedium => textTheme.headlineMedium?.copyWith(

        color: colors.onSurface,

      );

  TextStyle? get headlineSmall => textTheme.headlineSmall?.copyWith(

        color: colors.onSurface,

      );

  TextStyle? get titleLarge => textTheme.titleLarge?.copyWith(

        color: colors.onSurface,

      );

  TextStyle? get titleMedium => textTheme.titleMedium?.copyWith(

        color: colors.onSurface,

      );

  TextStyle? get titleSmall => textTheme.titleSmall?.copyWith(

        color: colors.onSurface,

      );

  TextStyle? get labelLarge => textTheme.labelLarge?.copyWith(

        color: colors.onSurface,

      );

  TextStyle? get labelMedium => textTheme.labelMedium?.copyWith(

        color: colors.onSurface,

      );

  TextStyle? get labelSmall => textTheme.labelSmall?.copyWith(

        color: colors.onSurface,

      );

  TextStyle? get bodyLarge => textTheme.bodyLarge?.copyWith(

        color: colors.onSurface,

      );

  TextStyle? get bodyMedium => textTheme.bodyMedium?.copyWith(

        color: colors.onSurface,

      );

  TextStyle? get bodySmall => textTheme.bodySmall?.copyWith(

        color: colors.onSurface,

      );

}


extension BreakpointUtils on BoxConstraints {

  bool get isTablet => maxWidth > 730;

  bool get isDesktop => maxWidth > 1200;

  bool get isMobile => !isTablet && !isDesktop;

}


extension DurationString on String {

  /// Assumes a string (roughly) of the format '\d{1,2}:\d{2}'

  Duration toDuration() => switch (split(':')) {

        [var minutes, var seconds] => Duration(

            minutes: int.parse(minutes.trim()),

            seconds: int.parse(seconds.trim()),

          ),

        [var hours, var minutes, var seconds] => Duration(

            hours: int.parse(hours.trim()),

            minutes: int.parse(minutes.trim()),

            seconds: int.parse(seconds.trim()),

          ),

        _ => throw Exception('Invalid duration string: $this'),

      };

}


extension HumanizedDuration on Duration {

  String toHumanizedString() {

    final seconds = '${inSeconds % 60}'.padLeft(2, '0');

    String minutes = '${inMinutes % 60}';

    if (inHours > 0 || inMinutes == 0) {

      minutes = minutes.padLeft(2, '0');

    }

    String value = '$minutes:$seconds';

    if (inHours > 0) {

      value = '$inHours:$minutes:$seconds';

    }

    return value;

  }

}

view rawextensions.dart hosted with ❤ by GitHub

// Copyright 2022 The Flutter Authors. All rights reserved.

// Use of this source code is governed by a BSD-style license that can be

// found in the LICENSE file.


import 'package:flutter/material.dart';

import 'package:go_router/go_router.dart';


import '../features/artists/artists.dart';

import '../features/home/home.dart';

import '../features/playlists/playlists.dart';

import '../features/playlists/view/view.dart';

import 'providers/artists.dart';

import 'providers/playlists.dart';

import 'views/views.dart';


const _pageKey = ValueKey('_pageKey');

const _scaffoldKey = ValueKey('_scaffoldKey');


final artistsProvider = ArtistsProvider();

final playlistsProvider = PlaylistsProvider();


const List<NavigationDestination> destinations = [

  NavigationDestination(

    label: 'Home',

    icon: Icon(Icons.home), // Modify this line

    route: '/',

  ),

  NavigationDestination(

    label: 'Playlists',

    icon: Icon(Icons.playlist_add_check), // Modify this line

    route: '/playlists',

  ),

  NavigationDestination(

    label: 'Artists',

    icon: Icon(Icons.people), // Modify this line

    route: '/artists',

  ),

];


class NavigationDestination {

  const NavigationDestination({

    required this.route,

    required this.label,

    required this.icon,

    this.child,

  });


  final String route;

  final String label;

  final Icon icon;

  final Widget? child;

}


final appRouter = GoRouter(

  routes: [

    // HomeScreen

    GoRoute(

      path: '/',

      pageBuilder: (context, state) => const MaterialPage<void>(

        key: _pageKey,

        child: RootLayout(

          key: _scaffoldKey,

          currentIndex: 0,

          child: HomeScreen(),

        ),

      ),

    ),


    // PlaylistHomeScreen

    GoRoute(

      path: '/playlists',

      pageBuilder: (context, state) => const MaterialPage<void>(

        key: _pageKey,

        child: RootLayout(

          key: _scaffoldKey,

          currentIndex: 1,

          child: PlaylistHomeScreen(),

        ),

      ),

      routes: [

        GoRoute(

          path: ':pid',

          pageBuilder: (context, state) => MaterialPage<void>(

            key: state.pageKey,

            child: RootLayout(

              key: _scaffoldKey,

              currentIndex: 1,

              child: PlaylistScreen(

                playlist: playlistsProvider

                    .getPlaylist(state.pathParameters['pid']!)!,

              ),

            ),

          ),

        ),

      ],

    ),


    // ArtistHomeScreen

    GoRoute(

      path: '/artists',

      pageBuilder: (context, state) => const MaterialPage<void>(

        key: _pageKey,

        child: RootLayout(

          key: _scaffoldKey,

          currentIndex: 2,

          child: ArtistsScreen(),

        ),

      ),

      routes: [

        GoRoute(

          path: ':aid',

          pageBuilder: (context, state) => MaterialPage<void>(

            key: state.pageKey,

            child: RootLayout(

              key: _scaffoldKey,

              currentIndex: 2,

              child: ArtistScreen(

                artist:

                    artistsProvider.getArtist(state.pathParameters['aid']!)!,

              ),

            ),

          ),

          // builder: (context, state) => ArtistScreen(

          //   id: state.params['aid']!,

          // ),

        ),

      ],

    ),

    for (final route in destinations.skip(3))

      GoRoute(

        path: route.route,

        pageBuilder: (context, state) => MaterialPage<void>(

          key: _pageKey,

          child: RootLayout(

            key: _scaffoldKey,

            currentIndex: destinations.indexOf(route),

            child: const SizedBox(),

          ),

        ),

      ),

  ],

);

Comments

Popular posts from this blog

program conversion untuk composite database

Kuis Akhir Evolusi Perangkat Lunak