Merge branch 'master' into auth-EKA-DDA

pull/28/head
root 2 years ago
commit 1c177c2279

@ -1,3 +1,4 @@
<<<<<<< HEAD
<component name="libraryTable"> <component name="libraryTable">
<library name="Dart Packages" type="DartPackagesLibraryType"> <library name="Dart Packages" type="DartPackagesLibraryType">
<properties> <properties>
@ -529,4 +530,545 @@
<JAVADOC /> <JAVADOC />
<SOURCES /> <SOURCES />
</library> </library>
=======
<component name="libraryTable">
<library name="Dart Packages" type="DartPackagesLibraryType">
<properties>
<option name="packageNameToDirsMap">
<entry key="async">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/async-2.11.0/lib" />
</list>
</value>
</entry>
<entry key="audioplayers">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/audioplayers-4.1.0/lib" />
</list>
</value>
</entry>
<entry key="audioplayers_android">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/audioplayers_android-3.0.2/lib" />
</list>
</value>
</entry>
<entry key="audioplayers_darwin">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/audioplayers_darwin-4.1.0/lib" />
</list>
</value>
</entry>
<entry key="audioplayers_linux">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/audioplayers_linux-2.1.0/lib" />
</list>
</value>
</entry>
<entry key="audioplayers_platform_interface">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/audioplayers_platform_interface-5.0.1/lib" />
</list>
</value>
</entry>
<entry key="audioplayers_web">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/audioplayers_web-3.1.0/lib" />
</list>
</value>
</entry>
<entry key="audioplayers_windows">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/audioplayers_windows-2.0.2/lib" />
</list>
</value>
</entry>
<entry key="auto_size_text">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/auto_size_text-3.0.0/lib" />
</list>
</value>
</entry>
<entry key="boolean_selector">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/boolean_selector-2.1.1/lib" />
</list>
</value>
</entry>
<entry key="characters">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/characters-1.3.0/lib" />
</list>
</value>
</entry>
<entry key="circular_reveal_animation">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/circular_reveal_animation-2.0.1/lib" />
</list>
</value>
</entry>
<entry key="clock">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/clock-1.1.1/lib" />
</list>
</value>
</entry>
<entry key="collection">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/collection-1.17.1/lib" />
</list>
</value>
</entry>
<entry key="crypto">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/crypto-3.0.2/lib" />
</list>
</value>
</entry>
<entry key="cupertino_icons">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/cupertino_icons-1.0.5/lib" />
</list>
</value>
</entry>
<entry key="custom_draggable_widget">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/custom_draggable_widget-0.0.2/lib" />
</list>
</value>
</entry>
<entry key="fake_async">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/fake_async-1.3.1/lib" />
</list>
</value>
</entry>
<entry key="ffi">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/ffi-2.0.2/lib" />
</list>
</value>
</entry>
<entry key="file">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/file-6.1.4/lib" />
</list>
</value>
</entry>
<entry key="flutter">
<value>
<list>
<option value="$PROJECT_DIR$/../../../../src/flutter/packages/flutter/lib" />
</list>
</value>
</entry>
<entry key="flutter_animated_play_button">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/flutter_animated_play_button-0.3.0/lib" />
</list>
</value>
</entry>
<entry key="flutter_lints">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/flutter_lints-2.0.2/lib" />
</list>
</value>
</entry>
<entry key="flutter_screenutil">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/flutter_screenutil-5.7.0/lib" />
</list>
</value>
</entry>
<entry key="flutter_signin_button">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/flutter_signin_button-2.0.0/lib" />
</list>
</value>
</entry>
<entry key="flutter_test">
<value>
<list>
<option value="$PROJECT_DIR$/../../../../src/flutter/packages/flutter_test/lib" />
</list>
</value>
</entry>
<entry key="flutter_web_plugins">
<value>
<list>
<option value="$PROJECT_DIR$/../../../../src/flutter/packages/flutter_web_plugins/lib" />
</list>
</value>
</entry>
<entry key="font_awesome_flutter">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/font_awesome_flutter-9.2.0/lib" />
</list>
</value>
</entry>
<entry key="google_fonts">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/google_fonts-4.0.4/lib" />
</list>
</value>
</entry>
<entry key="gradiantbutton">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/gradiantbutton-0.0.1/lib" />
</list>
</value>
</entry>
<entry key="gradient_borders">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/gradient_borders-1.0.0/lib" />
</list>
</value>
</entry>
<entry key="http">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/http-0.13.5/lib" />
</list>
</value>
</entry>
<entry key="http_parser">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/http_parser-4.0.2/lib" />
</list>
</value>
</entry>
<entry key="ionicons">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/ionicons-0.2.2/lib" />
</list>
</value>
</entry>
<entry key="js">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/js-0.6.7/lib" />
</list>
</value>
</entry>
<entry key="lints">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/lints-2.0.1/lib" />
</list>
</value>
</entry>
<entry key="matcher">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/matcher-0.12.15/lib" />
</list>
</value>
</entry>
<entry key="material_color_utilities">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/material_color_utilities-0.2.0/lib" />
</list>
</value>
</entry>
<entry key="meta">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/meta-1.9.1/lib" />
</list>
</value>
</entry>
<entry key="modal_bottom_sheet">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/modal_bottom_sheet-2.1.2/lib" />
</list>
</value>
</entry>
<entry key="path">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/path-1.8.3/lib" />
</list>
</value>
</entry>
<entry key="path_provider">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/path_provider-2.0.15/lib" />
</list>
</value>
</entry>
<entry key="path_provider_android">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/path_provider_android-2.0.27/lib" />
</list>
</value>
</entry>
<entry key="path_provider_foundation">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/path_provider_foundation-2.2.4/lib" />
</list>
</value>
</entry>
<entry key="path_provider_linux">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/path_provider_linux-2.1.11/lib" />
</list>
</value>
</entry>
<entry key="path_provider_platform_interface">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/path_provider_platform_interface-2.0.6/lib" />
</list>
</value>
</entry>
<entry key="path_provider_windows">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/path_provider_windows-2.1.7/lib" />
</list>
</value>
</entry>
<entry key="platform">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/platform-3.1.0/lib" />
</list>
</value>
</entry>
<entry key="plugin_platform_interface">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/plugin_platform_interface-2.1.5/lib" />
</list>
</value>
</entry>
<entry key="sky_engine">
<value>
<list>
<option value="$PROJECT_DIR$/../../../../src/flutter/bin/cache/pkg/sky_engine/lib" />
</list>
</value>
</entry>
<entry key="smooth_corner">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/smooth_corner-1.1.0/lib" />
</list>
</value>
</entry>
<entry key="source_span">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/source_span-1.9.1/lib" />
</list>
</value>
</entry>
<entry key="stack_trace">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/stack_trace-1.11.0/lib" />
</list>
</value>
</entry>
<entry key="stream_channel">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/stream_channel-2.1.1/lib" />
</list>
</value>
</entry>
<entry key="string_scanner">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/string_scanner-1.2.0/lib" />
</list>
</value>
</entry>
<entry key="synchronized">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/synchronized-3.1.0/lib" />
</list>
</value>
</entry>
<entry key="term_glyph">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/term_glyph-1.2.1/lib" />
</list>
</value>
</entry>
<entry key="test_api">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/test_api-0.5.1/lib" />
</list>
</value>
</entry>
<entry key="text_scroll">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/text_scroll-0.2.0/lib" />
</list>
</value>
</entry>
<entry key="top_snackbar_flutter">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/top_snackbar_flutter-3.1.0/lib" />
</list>
</value>
</entry>
<entry key="typed_data">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/typed_data-1.3.2/lib" />
</list>
</value>
</entry>
<entry key="uuid">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/uuid-3.0.7/lib" />
</list>
</value>
</entry>
<entry key="vector_math">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/vector_math-2.1.4/lib" />
</list>
</value>
</entry>
<entry key="win32">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/win32-4.1.4/lib" />
</list>
</value>
</entry>
<entry key="xdg_directories">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/xdg_directories-1.0.1/lib" />
</list>
</value>
</entry>
<entry key="zoom_tap_animation">
<value>
<list>
<option value="$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/zoom_tap_animation-1.1.0/lib" />
</list>
</value>
</entry>
</option>
</properties>
<CLASSES>
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/async-2.11.0/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/audioplayers-4.1.0/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/audioplayers_android-3.0.2/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/audioplayers_darwin-4.1.0/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/audioplayers_linux-2.1.0/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/audioplayers_platform_interface-5.0.1/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/audioplayers_web-3.1.0/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/audioplayers_windows-2.0.2/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/auto_size_text-3.0.0/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/boolean_selector-2.1.1/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/characters-1.3.0/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/circular_reveal_animation-2.0.1/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/clock-1.1.1/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/collection-1.17.1/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/crypto-3.0.2/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/cupertino_icons-1.0.5/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/custom_draggable_widget-0.0.2/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/fake_async-1.3.1/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/ffi-2.0.2/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/file-6.1.4/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/flutter_animated_play_button-0.3.0/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/flutter_lints-2.0.2/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/flutter_screenutil-5.7.0/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/flutter_signin_button-2.0.0/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/font_awesome_flutter-9.2.0/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/google_fonts-4.0.4/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/gradiantbutton-0.0.1/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/gradient_borders-1.0.0/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/http-0.13.5/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/http_parser-4.0.2/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/ionicons-0.2.2/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/js-0.6.7/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/lints-2.0.1/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/matcher-0.12.15/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/material_color_utilities-0.2.0/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/meta-1.9.1/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/modal_bottom_sheet-2.1.2/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/path-1.8.3/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/path_provider-2.0.15/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/path_provider_android-2.0.27/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/path_provider_foundation-2.2.4/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/path_provider_linux-2.1.11/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/path_provider_platform_interface-2.0.6/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/path_provider_windows-2.1.7/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/platform-3.1.0/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/plugin_platform_interface-2.1.5/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/smooth_corner-1.1.0/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/source_span-1.9.1/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/stack_trace-1.11.0/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/stream_channel-2.1.1/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/string_scanner-1.2.0/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/synchronized-3.1.0/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/term_glyph-1.2.1/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/test_api-0.5.1/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/text_scroll-0.2.0/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/top_snackbar_flutter-3.1.0/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/typed_data-1.3.2/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/uuid-3.0.7/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/vector_math-2.1.4/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/win32-4.1.4/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/xdg_directories-1.0.1/lib" />
<root url="file://$USER_HOME$/AppData/Local/Pub/Cache/hosted/pub.dev/zoom_tap_animation-1.1.0/lib" />
<root url="file://$PROJECT_DIR$/../../../../src/flutter/bin/cache/pkg/sky_engine/lib" />
<root url="file://$PROJECT_DIR$/../../../../src/flutter/packages/flutter/lib" />
<root url="file://$PROJECT_DIR$/../../../../src/flutter/packages/flutter_test/lib" />
<root url="file://$PROJECT_DIR$/../../../../src/flutter/packages/flutter_web_plugins/lib" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
>>>>>>> master
</component> </component>

@ -30,6 +30,7 @@ migrate_working_dir/
.packages .packages
.pub-cache/ .pub-cache/
.pub/ .pub/
.lib/values/keys.dart
/build/ /build/
# Symbolication related # Symbolication related

@ -1,7 +1,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.justmusic">
<!-- The INTERNET permission is required for development. Specifically, <!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc. to allow setting breakpoints, to provide hot reload, etc.
--> -->
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest> </manifest>

@ -1,19 +1,15 @@
buildscript { buildscript {
ext.kotlin_version = '1.7.10' ext.kotlin_version = '1.9.0'
repositories { repositories {
google() google()
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:7.3.0' classpath 'com.android.tools.build:gradle:7.1.2'
classpath 'com.google.gms:google-services:4.3.15' classpath 'com.google.gms:google-services:4.3.15'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
} }
} }
allprojects { allprojects {
@ -34,4 +30,3 @@ subprojects {
tasks.register("clean", Delete) { tasks.register("clean", Delete) {
delete rootProject.buildDir delete rootProject.buildDir
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

@ -0,0 +1,146 @@
import 'package:flutter/Material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:ionicons/ionicons.dart';
import 'package:tuple/tuple.dart';
import '../values/constants.dart';
class PhotoPostComponent extends StatelessWidget {
final bool empty;
const PhotoPostComponent({Key? key, required this.empty}) : super(key: key);
@override
Widget build(BuildContext context) {
return empty
? Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
color: postbutton, borderRadius: BorderRadius.circular(8)),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Icon(
Ionicons.camera,
size: 15,
color: Colors.white,
),
SizedBox(
width: 10,
),
Expanded(
child: Text(
'Prendre un selfie',
style: GoogleFonts.plusJakartaSans(
color: Colors.white, fontSize: 12),
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
)
]),
))
: Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
color: fillButton, borderRadius: BorderRadius.circular(8)),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
child: Text(
"Selfie enregistré",
style: GoogleFonts.plusJakartaSans(
color: Colors.white, fontSize: 12),
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
SizedBox(
width: 10,
),
Icon(
Icons.close,
size: 12,
color: Colors.white,
),
]),
));
}
}
class LocationPostComponent extends StatelessWidget {
final bool empty;
final Tuple2<String, String>? location;
const LocationPostComponent(
{Key? key, required this.empty, required this.location})
: super(key: key);
@override
Widget build(BuildContext context) {
return empty
? Container(
width: double.infinity,
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
color: postbutton, borderRadius: BorderRadius.circular(8)),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Icon(
Icons.location_on,
size: 15,
color: Colors.white,
),
SizedBox(
width: 10,
),
Expanded(
child: Text(
'Ajouter un lieu',
style: GoogleFonts.plusJakartaSans(
color: Colors.white, fontSize: 12),
overflow: TextOverflow.ellipsis,
),
)
])),
)
: Container(
width: double.infinity,
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
color: fillButton, borderRadius: BorderRadius.circular(8)),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
child: Text(
'${location?.item1}, ${location?.item2}',
style: GoogleFonts.plusJakartaSans(
color: Colors.white, fontSize: 12),
overflow: TextOverflow.ellipsis,
),
),
SizedBox(
width: 10,
),
Icon(
Icons.close,
size: 12,
color: Colors.white,
),
]),
),
);
}
}

@ -0,0 +1,45 @@
import 'package:flutter/Material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:justmusic/values/constants.dart';
import 'package:tuple/tuple.dart';
class CityListComponent extends StatelessWidget {
final Tuple2<String, String> location;
const CityListComponent({Key? key, required this.location}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 20),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Flexible(
child: RichText(
overflow: TextOverflow.ellipsis,
maxLines: 1,
text: TextSpan(children: [
TextSpan(
text: location.item2 + ", ",
style: GoogleFonts.plusJakartaSans(
color: grayText,
fontWeight: FontWeight.w400,
fontSize: 17),
),
TextSpan(
text: location.item1,
style: GoogleFonts.plusJakartaSans(
color: Colors.white,
fontWeight: FontWeight.w400,
fontSize: 17),
),
])),
),
],
),
),
);
}
}

@ -1,67 +1,272 @@
import 'dart:io';
import 'package:animated_appear/animated_appear.dart';
import 'package:auto_size_text/auto_size_text.dart'; import 'package:auto_size_text/auto_size_text.dart';
import 'package:circular_reveal_animation/circular_reveal_animation.dart';
import 'package:flutter/Material.dart'; import 'package:flutter/Material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:image_picker/image_picker.dart';
import 'package:insta_image_viewer/insta_image_viewer.dart';
import 'package:justmusic/values/constants.dart'; import 'package:justmusic/values/constants.dart';
import 'package:text_scroll/text_scroll.dart';
import 'package:tuple/tuple.dart';
import '../model/Music.dart';
import '../screens/search_location_screen.dart';
import 'buttonPostComponent.dart';
class EditablePostComponent extends StatefulWidget { class EditablePostComponent extends StatefulWidget {
const EditablePostComponent({Key? key}) : super(key: key); final Music? music;
const EditablePostComponent({Key? key, this.music}) : super(key: key);
@override @override
State<EditablePostComponent> createState() => _EditablePostComponentState(); State<EditablePostComponent> createState() => _EditablePostComponentState();
} }
class _EditablePostComponentState extends State<EditablePostComponent> { class _EditablePostComponentState extends State<EditablePostComponent>
with TickerProviderStateMixin {
final ImagePicker picker = ImagePicker();
late Animation<double> animation;
late AnimationController animationController;
late AnimationController _controller;
File? image;
Tuple2<String, String>? selectedCity;
@override
void initState() {
_controller = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 400),
);
animationController = AnimationController(
vsync: this,
duration: Duration(milliseconds: 400),
);
animation = CurvedAnimation(
parent: animationController,
curve: Curves.easeInOutSine,
);
animationController.forward();
super.initState();
}
Future pickImage(ImageSource source) async {
try {
final image = await ImagePicker().pickImage(source: source);
if (image == null) return;
final imageTemp = File(image.path);
setState(() {
this.image = imageTemp;
});
} on PlatformException catch (e) {
print('Failed to pick image: $e');
}
}
void _selectLocation(Tuple2<String, String> location) {
Navigator.pop(context);
setState(() {
selectedCity = location;
});
}
void searchLocation() {
showModalBottomSheet(
transitionAnimationController: _controller,
barrierColor: Colors.black.withOpacity(0.7),
backgroundColor: Colors.transparent,
elevation: 1,
constraints: const BoxConstraints(
maxWidth: 600,
),
isScrollControlled: true,
context: context,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20), topRight: Radius.circular(20))),
builder: ((context) {
return ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20), topRight: Radius.circular(20)),
child: SearchCityScreen(callback: _selectLocation));
}),
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ClipRRect( return ClipRRect(
borderRadius: BorderRadius.circular(25), borderRadius: BorderRadius.circular(25),
child: Container( child: Container(
constraints: BoxConstraints(maxWidth: 400), constraints: BoxConstraints(maxWidth: 400, minHeight: 500),
width: double.infinity, width: double.infinity,
color: warningBttnColor, color: warningBttnColor,
child: Column( child: Column(
children: [ children: [
AspectRatio( CircularRevealAnimation(
aspectRatio: 1 / 1, animation: animation,
child: Container( centerOffset: Offset(30.w, -100),
decoration: BoxDecoration( child: Stack(
// add border children: [
border: Border.all(width: 3.0, color: grayColor), AspectRatio(
// set border radius aspectRatio: 1 / 1,
borderRadius: BorderRadius.circular(20), child: Container(
), decoration: BoxDecoration(
child: ClipRRect( // add border
borderRadius: BorderRadius.circular(18), border: Border.all(width: 3.0, color: grayColor),
// implement image // set border radius
child: const Image( borderRadius: BorderRadius.circular(20),
image: AssetImage("assets/images/exemple_cover.png"), ),
fit: BoxFit.cover, child: ClipRRect(
width: double.infinity, borderRadius: BorderRadius.circular(18),
), // implement image
), child: widget.music == null
), ? Container(
), color: grayColor,
Padding( width: double.infinity,
padding: EdgeInsets.fromLTRB(15, 25, 15, 25), )
: Image(
image:
NetworkImage(widget.music?.cover ?? ""),
fit: BoxFit.cover,
width: double.infinity,
),
),
),
),
image != null
? Positioned(
top: 10,
right: 10,
child: AnimatedAppear(
delay: Duration(milliseconds: 500),
duration: Duration(milliseconds: 400),
child: Container(
width: 110,
height: 110,
decoration: BoxDecoration(
image: DecorationImage(
image: FileImage(image!),
fit: BoxFit.cover,
),
color: grayColor,
borderRadius: BorderRadius.circular(20),
border: Border.all(
style: BorderStyle.solid,
color: Colors.white,
width: 4)),
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: InstaImageViewer(
backgroundIsTransparent: true,
child: Image(
image: FileImage(image!),
fit: BoxFit.cover,
),
),
),
),
))
: Container()
],
)),
widget.music != null
? Padding(
padding: const EdgeInsets.all(10),
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
flex: 8,
child: TextScroll(
(widget.music?.title)!,
style: GoogleFonts.plusJakartaSans(
height: 1,
color: Colors.white,
fontWeight: FontWeight.w600,
fontSize: 26.h),
mode: TextScrollMode.endless,
pauseBetween: Duration(milliseconds: 500),
velocity:
Velocity(pixelsPerSecond: Offset(20, 0)),
)),
Padding(
padding: EdgeInsets.only(
bottom: 10.h, right: 5.w, left: 5.w),
child: ClipOval(
child: Container(
width: 5.h,
height: 5.h,
color: Colors.white,
),
),
),
Flexible(
flex: 6,
child: Padding(
padding: EdgeInsets.only(bottom: 2),
child: TextScroll(
(widget.music?.artists[0].name)!,
style: GoogleFonts.plusJakartaSans(
height: 1,
color: Colors.white,
fontWeight: FontWeight.w300,
fontSize: 16.h),
mode: TextScrollMode.endless,
velocity:
Velocity(pixelsPerSecond: Offset(50, 20)),
pauseBetween: Duration(milliseconds: 500),
),
)),
Container(width: 10),
AutoSizeText(
"2013",
style: GoogleFonts.plusJakartaSans(
color: Colors.white.withOpacity(0.5),
fontWeight: FontWeight.w300,
fontSize: 16.h),
textAlign: TextAlign.end,
maxFontSize: 20,
),
],
),
)
: Container(),
Container(
padding: EdgeInsets.fromLTRB(15, 15, 15, 25),
width: double.infinity,
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
AutoSizeText( Expanded(
"France, Lyon", flex: 5,
style: GoogleFonts.plusJakartaSans( child: GestureDetector(
color: Colors.white, fontSize: 13.sp), onTap: () {
maxFontSize: 20, manageImage();
},
child: PhotoPostComponent(
empty: image == null,
),
),
), ),
Image( SizedBox(
image: AssetImage("assets/images/camera_icon.png"), width: 15,
width: 30,
), ),
AutoSizeText( Expanded(
"10 Juil. 2023", flex: 5,
style: GoogleFonts.plusJakartaSans( child: GestureDetector(
color: Colors.white, fontSize: 13.sp), onTap: () {
maxFontSize: 20, manageLocation();
},
child: LocationPostComponent(
empty: selectedCity == null,
location: selectedCity,
),
),
), ),
], ],
), ),
@ -110,4 +315,63 @@ class _EditablePostComponentState extends State<EditablePostComponent> {
), ),
)); ));
} }
void manageImage() {
if (image != null) {
setState(() {
image = null;
});
} else {
_showActionSheet(context);
}
}
void manageLocation() {
if (selectedCity != null) {
setState(() {
selectedCity = null;
});
} else {
searchLocation();
}
}
void _showActionSheet(BuildContext context) {
showCupertinoModalPopup<void>(
context: context,
barrierColor: Colors.black.withOpacity(0.5),
builder: (BuildContext context) => Container(
color: Colors.black,
child: CupertinoActionSheet(
title: Text(
'Ajouter une photo',
style: GoogleFonts.plusJakartaSans(fontWeight: FontWeight.bold),
),
actions: <CupertinoActionSheetAction>[
CupertinoActionSheetAction(
onPressed: () {
pickImage(ImageSource.gallery);
Navigator.pop(context);
},
child: const Text('Galerie'),
),
CupertinoActionSheetAction(
onPressed: () {
pickImage(ImageSource.camera);
Navigator.pop(context);
},
child: const Text('Prendre un selfie'),
),
],
cancelButton: CupertinoActionSheetAction(
isDestructiveAction: true,
onPressed: () {
Navigator.pop(context);
},
child: const Text('Annuler'),
),
),
),
);
}
} }

@ -6,9 +6,15 @@ import '../model/Music.dart';
class MusicListComponent extends StatelessWidget { class MusicListComponent extends StatelessWidget {
final Music music; final Music music;
const MusicListComponent({ final bool playing;
final int index;
final Function(int) callback;
MusicListComponent({
Key? key, Key? key,
required this.music, required this.music,
required this.playing,
required this.callback,
required this.index,
}) : super(key: key); }) : super(key: key);
@override @override
@ -71,11 +77,13 @@ class MusicListComponent extends StatelessWidget {
intervalSpaces: 10, intervalSpaces: 10,
), ),
)), )),
Icon( music.explicit
Icons.explicit, ? Icon(
color: Colors.grey.withOpacity(0.7), Icons.explicit,
size: 17, color: Colors.grey.withOpacity(0.7),
), size: 17,
)
: Container(),
], ],
), ),
ScrollConfiguration( ScrollConfiguration(
@ -90,9 +98,14 @@ class MusicListComponent extends StatelessWidget {
), ),
), ),
Spacer(), Spacer(),
PlayButtonComponent( music.previewUrl != null
urlPreview: music.previewUrl, ? PlayButtonComponent(
) music: music,
callback: callback,
playing: playing,
index: index,
)
: Container()
], ],
), ),
); );

@ -3,9 +3,20 @@ import 'package:flutter/Material.dart';
import 'package:flutter_animated_play_button/flutter_animated_play_button.dart'; import 'package:flutter_animated_play_button/flutter_animated_play_button.dart';
import 'package:ionicons/ionicons.dart'; import 'package:ionicons/ionicons.dart';
import '../main.dart';
import '../model/Music.dart';
class PlayButtonComponent extends StatefulWidget { class PlayButtonComponent extends StatefulWidget {
final String? urlPreview; final Music music;
const PlayButtonComponent({Key? key, required this.urlPreview}) final Function callback;
final int index;
final bool playing;
const PlayButtonComponent(
{Key? key,
required this.music,
required this.callback,
required this.playing,
required this.index})
: super(key: key); : super(key: key);
@override @override
@ -13,31 +24,24 @@ class PlayButtonComponent extends StatefulWidget {
} }
class _PlayButtonComponentState extends State<PlayButtonComponent> { class _PlayButtonComponentState extends State<PlayButtonComponent> {
bool isPlaying = true;
final player = AudioPlayer(); final player = AudioPlayer();
void switchStatePlaying() {
setState(() {
isPlaying = !isPlaying;
});
stopSong();
}
@override @override
void initState() { void initState() {
player.onPlayerComplete.listen((event) { MyApp.audioPlayer.onPlayerComplete.listen((event) {
switchStatePlaying(); widget.callback(widget.index);
}); });
super.initState(); super.initState();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (!isPlaying) { return !widget.playing
playSong();
} else {}
return isPlaying
? GestureDetector( ? GestureDetector(
onTap: switchStatePlaying, onTap: () {
widget.music.playSong();
widget.callback(widget.index);
},
child: Container( child: Container(
width: 30, width: 30,
height: 30, height: 30,
@ -48,25 +52,21 @@ class _PlayButtonComponentState extends State<PlayButtonComponent> {
)), )),
) )
: GestureDetector( : GestureDetector(
onTap: switchStatePlaying, onTap: () {
widget.music.stopSong();
widget.callback(widget.index);
},
child: Container( child: Container(
width: 30, width: 30,
height: 30, height: 30,
child: AnimatedPlayButton( child: AnimatedPlayButton(
stopped: false, stopped: false,
color: Colors.grey.withOpacity(0.3), color: Colors.grey.withOpacity(0.3),
onPressed: () {}, onPressed: () {
print("cc");
},
), ),
)); ));
} }
Future<void> playSong() async {
if (widget.urlPreview != null) {
await player.play(UrlSource(widget.urlPreview ?? ""));
}
}
Future<void> stopSong() async {
await player.stop();
}
} }

@ -1,32 +1,149 @@
import 'dart:ui';
import 'package:flutter/Material.dart'; import 'package:flutter/Material.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class PostButtonComponent extends StatelessWidget { class PostButtonComponent extends StatefulWidget {
const PostButtonComponent({Key? key}) : super(key: key); final bool empty;
const PostButtonComponent({Key? key, required this.empty}) : super(key: key);
@override
State<PostButtonComponent> createState() => _PostButtonComponentState();
}
class _PostButtonComponentState extends State<PostButtonComponent>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
animationBehavior: AnimationBehavior.normal,
vsync: this,
duration: Duration(milliseconds: 1500),
);
_controller.addStatusListener((status) {
if (status == AnimationStatus.completed) {
_controller.reverse();
} else if (status == AnimationStatus.dismissed) {
_controller.forward();
}
});
_controller.forward();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (widget.empty) {
return Container(
constraints: BoxConstraints(maxWidth: 400),
decoration: BoxDecoration(
gradient: LinearGradient(colors: [
Color(0xFF141414),
Color(0xFF272727),
Color(0xFF141414)
]),
borderRadius: BorderRadius.circular(10000)),
padding: EdgeInsets.symmetric(vertical: 25),
width: double.infinity,
child: Align(
child: Text(
"Publier la capsule",
style: GoogleFonts.plusJakartaSans(
color: Color(0xFF474747),
fontWeight: FontWeight.w800,
fontStyle: FontStyle.italic,
fontSize: 24),
),
),
);
}
return Container( return Container(
constraints: BoxConstraints(maxWidth: 400),
decoration: BoxDecoration(
gradient: LinearGradient(colors: [
Color(0xFF141414),
Color(0xFF272727),
Color(0xFF141414)
]),
borderRadius: BorderRadius.circular(10000)),
padding: EdgeInsets.symmetric(vertical: 25),
width: double.infinity, width: double.infinity,
child: Align( height: 90,
child: Text( clipBehavior: Clip.hardEdge,
"Publier la capsule", decoration: BoxDecoration(
style: GoogleFonts.plusJakartaSans( color: Colors.transparent, borderRadius: BorderRadius.circular(1000)),
color: Color(0xFF474747), child: Stack(
fontWeight: FontWeight.w800, children: [
fontStyle: FontStyle.italic, AnimatedBuilder(
fontSize: 24), animation: _controller,
), builder: (context, child) {
return Transform.translate(
offset: Offset(
_controller.value * (MediaQuery.of(context).size.width - 200),
0,
),
child: child,
);
},
child: Container(
width: 120,
height: 80,
alignment: Alignment.center,
decoration: BoxDecoration(
gradient: LinearGradient(colors: [
Color(0xFF9E78FF).withOpacity(0.0),
Color(0xFFFDFDFF),
Color(0xFFFFFFFF),
Color(0xFF9E78FF).withOpacity(0.0)
], stops: const [
0,
0.4,
0.5,
1
]),
),
),
),
BackdropFilter(
filter: ImageFilter.blur(
sigmaX: 10.0,
sigmaY: 10.0,
),
child: Opacity(
opacity: 0.9,
child: Container(
constraints: BoxConstraints(maxWidth: 400),
decoration: BoxDecoration(
gradient: LinearGradient(colors: [
Color(0xFF633AF4),
Color(0xFF9367FF),
Color(0xFF633AF4)
]),
border: Border.all(width: 5, color: Color(0xFF1C1C1C)),
borderRadius: BorderRadius.circular(10000)),
padding: EdgeInsets.symmetric(vertical: 25),
width: double.infinity,
child: Padding(
padding: EdgeInsets.only(left: 100),
child: Text(
"Publier la capsule",
style: GoogleFonts.plusJakartaSans(
color: Colors.white,
fontWeight: FontWeight.w700,
fontStyle: FontStyle.italic,
fontSize: 22),
),
),
),
)),
ClipOval(
child: Positioned(
left: -15,
child: Padding(
padding: const EdgeInsets.only(left: 5, top: 5),
child: Image(
image: AssetImage("assets/images/rocket_button.png"),
height: 65,
),
),
),
)
],
), ),
); );
} }

@ -1,4 +1,6 @@
import 'package:audioplayers/audioplayers.dart';
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
@ -11,7 +13,7 @@ import 'package:justmusic/screens/registration_screen.dart';
import 'package:justmusic/screens/welcome_screen.dart'; import 'package:justmusic/screens/welcome_screen.dart';
import 'package:justmusic/view_model/MusicViewModel.dart'; import 'package:justmusic/view_model/MusicViewModel.dart';
import 'package:justmusic/view_model/UserViewModel.dart'; import 'package:justmusic/view_model/UserViewModel.dart';
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart'; import 'firebase_options.dart';
Future<void> main() async { Future<void> main() async {
@ -23,10 +25,10 @@ Future<void> main() async {
} }
class MyApp extends StatelessWidget { class MyApp extends StatelessWidget {
// ugly as fuck
static FirebaseFirestore db = FirebaseFirestore.instance; static FirebaseFirestore db = FirebaseFirestore.instance;
static UserViewModel userViewModel = UserViewModel(); static UserViewModel userViewModel = UserViewModel();
static MusicViewModel musicViewModel = MusicViewModel(); static MusicViewModel musicViewModel = MusicViewModel();
static AudioPlayer audioPlayer = AudioPlayer();
const MyApp({super.key}); const MyApp({super.key});
@ -36,6 +38,7 @@ class MyApp extends StatelessWidget {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky); SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
Paint.enableDithering = true; Paint.enableDithering = true;
return ScreenUtilInit( return ScreenUtilInit(
useInheritedMediaQuery: true,
builder: (context, child) { builder: (context, child) {
return MaterialApp( return MaterialApp(
routes: { routes: {

@ -1,11 +1,14 @@
import 'package:audioplayers/audioplayers.dart';
import 'Artist.dart'; import 'Artist.dart';
import '../main.dart';
class Music { class Music {
final String _id; final String _id;
String? _title; String? _title;
String? _cover; String? _cover;
String? _previewUrl; String? _previewUrl;
DateTime? _date; int? _date;
double? _duration; double? _duration;
bool _explicit = false; bool _explicit = false;
List<Artist> _artists; List<Artist> _artists;
@ -35,9 +38,9 @@ class Music {
_previewUrl = value; _previewUrl = value;
} }
DateTime? get date => _date; int? get date => _date;
set date(DateTime? value) { set date(int? value) {
_date = value; _date = value;
} }
@ -58,4 +61,14 @@ class Music {
set artists(List<Artist> value) { set artists(List<Artist> value) {
_artists = value; _artists = value;
} }
Future<void> playSong() async {
if (previewUrl != null) {
await MyApp.audioPlayer.play(UrlSource(previewUrl!));
}
}
Future<void> stopSong() async {
await MyApp.audioPlayer.stop();
}
} }

@ -88,7 +88,7 @@ class _FeedScreenState extends State<FeedScreen>
shape: const RoundedRectangleBorder( shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only( borderRadius: BorderRadius.only(
topLeft: Radius.circular(20), topRight: Radius.circular(20))), topLeft: Radius.circular(20), topRight: Radius.circular(20))),
builder: ((context) { builder: ((BuildContext context) {
return GestureDetector( return GestureDetector(
onTap: () { onTap: () {
FocusScopeNode currentFocus = FocusScope.of(context); FocusScopeNode currentFocus = FocusScope.of(context);
@ -122,6 +122,8 @@ class _FeedScreenState extends State<FeedScreen>
padding: EdgeInsets.only( padding: EdgeInsets.only(
left: defaultPadding, right: defaultPadding), left: defaultPadding, right: defaultPadding),
child: SingleChildScrollView( child: SingleChildScrollView(
physics: BouncingScrollPhysics(
decelerationRate: ScrollDecelerationRate.fast),
child: Wrap( child: Wrap(
// to apply margin in the main axis of the wrap // to apply margin in the main axis of the wrap
runSpacing: 10, runSpacing: 10,
@ -246,6 +248,8 @@ class _FeedScreenState extends State<FeedScreen>
animation: animation, animation: animation,
centerOffset: Offset(30.w, -100), centerOffset: Offset(30.w, -100),
child: SingleChildScrollView( child: SingleChildScrollView(
physics: const BouncingScrollPhysics(
decelerationRate: ScrollDecelerationRate.fast),
child: SizedBox( child: SizedBox(
width: double.infinity, width: double.infinity,
child: Align( child: Align(

@ -3,8 +3,10 @@ import 'package:flutter/Material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:justmusic/components/back_button.dart'; import 'package:justmusic/components/back_button.dart';
import 'package:justmusic/screens/search_song_screen.dart'; import 'package:justmusic/screens/search_song_screen.dart';
import 'package:tuple/tuple.dart';
import '../components/editable_post_component.dart'; import '../components/editable_post_component.dart';
import '../components/post_button_component.dart'; import '../components/post_button_component.dart';
import '../model/Music.dart';
import '../values/constants.dart'; import '../values/constants.dart';
class PostScreen extends StatefulWidget { class PostScreen extends StatefulWidget {
@ -18,7 +20,9 @@ class _PostScreenState extends State<PostScreen>
with SingleTickerProviderStateMixin { with SingleTickerProviderStateMixin {
final scrollController = ScrollController(); final scrollController = ScrollController();
late AnimationController _controller; late AnimationController _controller;
late Animation<double> _animation;
Music? selectedMusic;
Tuple2<String, String>? selectedCity;
@override @override
void initState() { void initState() {
@ -27,16 +31,17 @@ class _PostScreenState extends State<PostScreen>
duration: const Duration(milliseconds: 400), duration: const Duration(milliseconds: 400),
); );
_animation = Tween<double>(begin: 0.0, end: 400.0).animate(
CurvedAnimation(
parent: _controller,
curve: Curves.easeOut,
),
);
super.initState(); super.initState();
} }
void openDetailPost() { void _selectMusic(Music music) {
Navigator.pop(context);
setState(() {
selectedMusic = music;
});
}
void openSearchSong() {
showModalBottomSheet( showModalBottomSheet(
transitionAnimationController: _controller, transitionAnimationController: _controller,
barrierColor: Colors.black.withOpacity(0.7), barrierColor: Colors.black.withOpacity(0.7),
@ -51,10 +56,10 @@ class _PostScreenState extends State<PostScreen>
borderRadius: BorderRadius.only( borderRadius: BorderRadius.only(
topLeft: Radius.circular(20), topRight: Radius.circular(20))), topLeft: Radius.circular(20), topRight: Radius.circular(20))),
builder: ((context) { builder: ((context) {
return const ClipRRect( return ClipRRect(
borderRadius: BorderRadius.only( borderRadius: BorderRadius.only(
topLeft: Radius.circular(20), topRight: Radius.circular(20)), topLeft: Radius.circular(20), topRight: Radius.circular(20)),
child: SearchSongScreen()); child: SearchSongScreen(callback: _selectMusic));
}), }),
); );
} }
@ -65,11 +70,11 @@ class _PostScreenState extends State<PostScreen>
resizeToAvoidBottomInset: true, resizeToAvoidBottomInset: true,
backgroundColor: bgColor, backgroundColor: bgColor,
extendBodyBehindAppBar: true, extendBodyBehindAppBar: true,
appBar: PreferredSize( appBar: const PreferredSize(
preferredSize: Size(double.infinity, 80), preferredSize: Size(double.infinity, 80),
child: SafeArea( child: SafeArea(
child: Padding( child: Padding(
padding: const EdgeInsets.only( padding: EdgeInsets.only(
left: defaultPadding, left: defaultPadding,
right: defaultPadding, right: defaultPadding,
top: defaultPadding), top: defaultPadding),
@ -90,35 +95,29 @@ class _PostScreenState extends State<PostScreen>
fit: BoxFit.cover, fit: BoxFit.cover,
), ),
), ),
child: Stack( child: ScrollConfiguration(
alignment: Alignment.topCenter, behavior: ScrollBehavior().copyWith(scrollbars: false),
children: [ child: SingleChildScrollView(
ScrollConfiguration( controller: scrollController,
behavior: ScrollBehavior().copyWith(scrollbars: false), child: Column(
child: SingleChildScrollView( mainAxisAlignment: MainAxisAlignment.end,
controller: scrollController, children: [
child: Column( SizedBox(
mainAxisAlignment: MainAxisAlignment.end, height: 100.h,
children: [ ),
SizedBox( GestureDetector(
height: 100.h, onTap: openSearchSong,
), child: EditablePostComponent(music: selectedMusic)),
GestureDetector( SizedBox(
onTap: openDetailPost, height: 40.h,
child: EditablePostComponent(),
),
SizedBox(
height: 40.h,
),
PostButtonComponent(),
SizedBox(
height: 40.h,
),
],
), ),
), PostButtonComponent(empty: selectedMusic == null),
SizedBox(
height: 40.h,
),
],
), ),
], ),
), ),
), ),
); );

@ -60,6 +60,8 @@ class _ProfileScreenState extends State<ProfileScreen> {
height: double.infinity, height: double.infinity,
color: bgColor, color: bgColor,
child: SingleChildScrollView( child: SingleChildScrollView(
physics: const BouncingScrollPhysics(
decelerationRate: ScrollDecelerationRate.fast),
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal: settingPadding), padding: const EdgeInsets.symmetric(horizontal: settingPadding),
child: Column( child: Column(

@ -0,0 +1,89 @@
import 'dart:ui';
import 'package:flutter/Material.dart';
import 'package:flutter/cupertino.dart';
import '../components/city_list_component.dart';
import '../services/GeoApi.dart';
import '../values/constants.dart';
class SearchCityScreen extends StatefulWidget {
final Function callback;
const SearchCityScreen({Key? key, required this.callback}) : super(key: key);
@override
State<SearchCityScreen> createState() => _SearchCityScreenState();
}
class _SearchCityScreenState extends State<SearchCityScreen> {
final ScrollController _scrollController = ScrollController();
final GeoApi api = GeoApi();
@override
Widget build(BuildContext context) {
double screenHeight = MediaQuery.of(context).size.height;
return BackdropFilter(
filter: ImageFilter.blur(
sigmaX: 60.0,
sigmaY: 60.0,
),
child: Container(
color: bgAppBar.withOpacity(0.5),
height: screenHeight - 50,
padding: const EdgeInsets.only(top: 10),
child: Column(
children: [
Align(
child: Container(
width: 60,
height: 5,
decoration: BoxDecoration(
color: Color(0xFF3A3A3A).withOpacity(0.6),
borderRadius: BorderRadius.circular(20))),
),
const SizedBox(
height: 10,
),
Flexible(
child: ScrollConfiguration(
behavior: ScrollBehavior().copyWith(scrollbars: true),
child: FutureBuilder(
future: api.getNearbyCities(),
builder:
(BuildContext context, AsyncSnapshot<dynamic> snapshot) {
if (snapshot.hasData) {
return ListView.builder(
physics: const BouncingScrollPhysics(
decelerationRate: ScrollDecelerationRate.fast),
controller: _scrollController,
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return InkWell(
onTap: () {
widget.callback(snapshot.data[index]);
},
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 20),
child: CityListComponent(
location: snapshot.data[index],
),
));
});
} else {
return Center(
child: CupertinoActivityIndicator(
radius: 15,
color: grayColor,
),
);
}
},
),
))
],
),
),
);
}
}

@ -11,7 +11,8 @@ import '../values/constants.dart';
import '../main.dart'; import '../main.dart';
class SearchSongScreen extends StatefulWidget { class SearchSongScreen extends StatefulWidget {
const SearchSongScreen({Key? key}) : super(key: key); final Function callback;
const SearchSongScreen({Key? key, required this.callback}) : super(key: key);
@override @override
State<SearchSongScreen> createState() => _SearchSongScreenState(); State<SearchSongScreen> createState() => _SearchSongScreenState();
@ -20,6 +21,7 @@ class SearchSongScreen extends StatefulWidget {
class _SearchSongScreenState extends State<SearchSongScreen> { class _SearchSongScreenState extends State<SearchSongScreen> {
final ScrollController _scrollController = ScrollController(); final ScrollController _scrollController = ScrollController();
final TextEditingController _textEditingController = TextEditingController(); final TextEditingController _textEditingController = TextEditingController();
int? playingIndex;
Future<void> resetFullScreen() async { Future<void> resetFullScreen() async {
await SystemChannels.platform.invokeMethod<void>( await SystemChannels.platform.invokeMethod<void>(
@ -62,6 +64,18 @@ class _SearchSongScreenState extends State<SearchSongScreen> {
List<Music> filteredData = []; List<Music> filteredData = [];
void playMusic(int index) {
if (playingIndex == index) {
setState(() {
playingIndex = null;
});
} else {
setState(() {
playingIndex = index;
});
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
double screenHeight = MediaQuery.of(context).size.height; double screenHeight = MediaQuery.of(context).size.height;
@ -101,10 +115,11 @@ class _SearchSongScreenState extends State<SearchSongScreen> {
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: TextField( child: TextField(
autofocus: true,
controller: _textEditingController, controller: _textEditingController,
keyboardAppearance: Brightness.dark, keyboardAppearance: Brightness.dark,
onEditingComplete: resetFullScreen, onEditingComplete: resetFullScreen,
onChanged: (value) async { onSubmitted: (value) async {
if (_textEditingController.text.isEmpty) { if (_textEditingController.text.isEmpty) {
} else if (value == " ") { } else if (value == " ") {
print("popular"); print("popular");
@ -152,13 +167,41 @@ class _SearchSongScreenState extends State<SearchSongScreen> {
child: ScrollConfiguration( child: ScrollConfiguration(
behavior: ScrollBehavior().copyWith(scrollbars: true), behavior: ScrollBehavior().copyWith(scrollbars: true),
child: ListView.builder( child: ListView.builder(
physics: const BouncingScrollPhysics(
decelerationRate: ScrollDecelerationRate.fast),
controller: _scrollController, controller: _scrollController,
itemCount: filteredData.length, itemCount: filteredData.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
return Padding( if (playingIndex == index) {
padding: const EdgeInsets.symmetric(horizontal: 20), return InkWell(
child: MusicListComponent(music: filteredData[index]), onTap: () {
); widget.callback(filteredData[index]);
},
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 20),
child: MusicListComponent(
music: filteredData[index],
playing: true,
callback: playMusic,
index: index,
),
));
}
return InkWell(
onTap: () {
widget.callback(filteredData[index]);
},
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 20),
child: MusicListComponent(
music: filteredData[index],
playing: false,
callback: playMusic,
index: index,
),
));
}), }),
)) ))
], ],

@ -0,0 +1,62 @@
import 'package:geolocator/geolocator.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:tuple/tuple.dart';
import '../values/keys.dart';
class GeoApi {
final String apiKey = geoKey;
Future<List<Tuple2<String, String>>?> getNearbyCities() async {
try {
LocationPermission permission = await Geolocator.checkPermission();
bool serviceEnabled;
// Test if location services are enabled.
serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
// Location services are not enabled don't continue
// accessing the position and request users of the
// App to enable the location services.
return Future.error('Location services are disabled.');
}
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
return Future.error('Location permissions are denied');
}
}
if (permission == LocationPermission.deniedForever) {
return Future.error(
'Location permissions are permanently denied, we cannot request permissions.');
}
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high);
String apiUrl =
'http://api.openweathermap.org/data/2.5/find?lat=${position.latitude}&lon=${position.longitude}&cnt=10&appid=$apiKey';
var response = await http.get(Uri.parse(apiUrl));
if (response.statusCode == 200) {
var data = json.decode(response.body);
List<dynamic> cities = data['list'];
List<Tuple2<String, String>> cityInfo = cities.map((city) {
String cityName = city['name'] as String;
String countryName = city['sys']['country'] as String;
return Tuple2(cityName, countryName);
}).toList();
return cityInfo;
} else {
print('Failed to fetch data');
}
} catch (e) {
print('Error: $e');
}
return null;
}
}
class Tuple {}

@ -20,6 +20,8 @@ const bgAppBar = Color(0xFF181818);
const grayText = Color(0xFF898989); const grayText = Color(0xFF898989);
const settingColor = Color(0xFF232323); const settingColor = Color(0xFF232323);
const searchBarColor = Color(0xFF161616); const searchBarColor = Color(0xFF161616);
const postbutton = Color(0xFF1B1B1B);
const fillButton = Color(0xFF633AF4);
// All constants important too us // All constants important too us
const defaultPadding = 30.0; const defaultPadding = 30.0;

@ -0,0 +1 @@
const geoKey = "85a2724ad38b3994c2b7ebe1d239bbff";

@ -27,42 +27,27 @@ class MusicViewModel {
return Artist(artist['id'], artist['name'], ''); return Artist(artist['id'], artist['name'], '');
})); }));
return Music( return _getMusicFromResponse(responseData);
responseData['id'],
responseData['name'],
responseData['album']['images'][0]['url'],
responseData['preview_url'],
DateTime.parse(responseData['album']['release_date']),
responseData['duration_ms'] / 1000,
responseData['explicit'],
artists);
} else { } else {
throw Exception( throw Exception(
'Error retrieving music information : ${response.statusCode} ${response.reasonPhrase}'); 'Error retrieving music information : ${response.statusCode} ${response.reasonPhrase}');
} }
} }
List<Music> _getMusicsFromResponse(Map<String, dynamic> responseData) { Music _getMusicFromResponse(dynamic track) {
List<Music> musics = []; List<Artist> artists = List<Artist>.from(track['artists'].map((artist) {
return Artist(artist['id'], artist['name'], '');
List<dynamic> tracks = responseData['tracks']['items']; }));
for (var track in tracks) {
List<Artist> artists = List<Artist>.from(track['artists'].map((artist) { return Music(
return Artist(artist['id'], artist['name'], ''); track['id'],
})); track['name'],
track['album']['images'][0]['url'],
musics.add(Music( track['preview_url'],
track['id'], int.parse(track['album']['release_date'].split('-')[0]),
track['name'], track['duration_ms'] / 1000,
track['album']['images'][0]['url'], track['explicit'],
track['preview_url'], artists);
DateTime.now(),
track['duration_ms'] / 1000,
track['explicit'],
artists));
}
return musics;
} }
Future<List<Music>> getMusicsWithName(String name, Future<List<Music>> getMusicsWithName(String name,
@ -77,7 +62,9 @@ class MusicViewModel {
if (response.statusCode == 200) { if (response.statusCode == 200) {
Map<String, dynamic> responseData = jsonDecode(response.body); Map<String, dynamic> responseData = jsonDecode(response.body);
return _getMusicsFromResponse(responseData); return List<Music>.from(responseData['tracks']['items'].map((track) {
return _getMusicFromResponse(track);
}));
} else { } else {
throw Exception( throw Exception(
'Error while retrieving music : ${response.statusCode} ${response.reasonPhrase}'); 'Error while retrieving music : ${response.statusCode} ${response.reasonPhrase}');
@ -96,7 +83,9 @@ class MusicViewModel {
if (response.statusCode == 200) { if (response.statusCode == 200) {
Map<String, dynamic> responseData = jsonDecode(response.body); Map<String, dynamic> responseData = jsonDecode(response.body);
return _getMusicsFromResponse(responseData); return List<Music>.from(responseData['tracks']['items'].map((track) {
return _getMusicFromResponse(track);
}));
} else { } else {
throw Exception( throw Exception(
'Error while retrieving music : ${response.statusCode} ${response.reasonPhrase}'); 'Error while retrieving music : ${response.statusCode} ${response.reasonPhrase}');
@ -175,23 +164,31 @@ class MusicViewModel {
if (response.statusCode == 200) { if (response.statusCode == 200) {
Map<String, dynamic> responseData = jsonDecode(response.body); Map<String, dynamic> responseData = jsonDecode(response.body);
return List<Music>.from(responseData['tracks'].map((track) {
return _getMusicFromResponse(track);
}));
} else {
throw Exception(
'Error while retrieving music : ${response.statusCode} ${response.reasonPhrase}');
}
}
Future<List<Music>> getMusicsWithPlaylistId(String id,
{String market = "FR"}) async {
var accessToken = await _token.getAccessToken();
var response = await http
.get(Uri.parse('$API_URL/playlists/$id?market=$market'), headers: {
'Authorization': 'Bearer $accessToken',
});
if (response.statusCode == 200) {
Map<String, dynamic> responseData = jsonDecode(response.body);
List<Music> musics = []; List<Music> musics = [];
List<dynamic> tracks = responseData['tracks']; List<dynamic> tracks = responseData['tracks']['items'];
for (var track in tracks) { for (var track in tracks) {
List<Artist> artists = List<Artist>.from(track['artists'].map((artist) { musics.add(_getMusicFromResponse(track['track']));
return Artist(artist['id'], artist['name'], '');
}));
musics.add(Music(
track['id'],
track['name'],
track['album']['images'][0]['url'],
track['preview_url'],
DateTime.now(),
track['duration_ms'] / 1000,
track['explicit'],
artists));
} }
return musics; return musics;
@ -200,4 +197,28 @@ class MusicViewModel {
'Error while retrieving music : ${response.statusCode} ${response.reasonPhrase}'); 'Error while retrieving music : ${response.statusCode} ${response.reasonPhrase}');
} }
} }
Future<List<Music>> getMusicsWithIds(List<String> ids,
{String market = "FR"}) async {
var accessToken = await _token.getAccessToken();
String url = API_URL + '/tracks?market=$market&ids=';
if (ids.length == 0) return [];
url += ids.join('%2C');
var response = await http.get(Uri.parse(url), headers: {
'Authorization': 'Bearer $accessToken',
});
if (response.statusCode == 200) {
Map<String, dynamic> responseData = jsonDecode(response.body);
return List<Music>.from(responseData['tracks'].map((track) {
return _getMusicFromResponse(track);
}));
} else {
throw Exception(
'Error while retrieving music : ${response.statusCode} ${response.reasonPhrase}');
}
}
} }

@ -9,6 +9,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.4" version: "1.3.4"
animated_appear:
dependency: "direct main"
description:
name: animated_appear
sha256: "53097d7bb6d5e4a1a3a74c8f3028c47c87101c6ec8903f2002372d1eb5aee991"
url: "https://pub.dev"
source: hosted
version: "0.0.4"
async: async:
dependency: transitive dependency: transitive
description: description:
@ -145,14 +153,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.17.1" version: "1.17.1"
cross_file:
dependency: transitive
description:
name: cross_file
sha256: "0b0036e8cccbfbe0555fd83c1d31a6f30b77a96b598b35a5d36dd41f718695e9"
url: "https://pub.dev"
source: hosted
version: "0.3.3+4"
crypto: crypto:
dependency: transitive dependency: transitive
description: description:
name: crypto name: crypto
sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67 sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.2" version: "3.0.3"
cupertino_icons: cupertino_icons:
dependency: "direct main" dependency: "direct main"
description: description:
@ -193,6 +209,38 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.1.4" version: "6.1.4"
file_selector_linux:
dependency: transitive
description:
name: file_selector_linux
sha256: "770eb1ab057b5ae4326d1c24cc57710758b9a46026349d021d6311bd27580046"
url: "https://pub.dev"
source: hosted
version: "0.9.2"
file_selector_macos:
dependency: transitive
description:
name: file_selector_macos
sha256: "4ada532862917bf16e3adb3891fe3a5917a58bae03293e497082203a80909412"
url: "https://pub.dev"
source: hosted
version: "0.9.3+1"
file_selector_platform_interface:
dependency: transitive
description:
name: file_selector_platform_interface
sha256: "412705a646a0ae90f33f37acfae6a0f7cbc02222d6cd34e479421c3e74d3853c"
url: "https://pub.dev"
source: hosted
version: "2.6.0"
file_selector_windows:
dependency: transitive
description:
name: file_selector_windows
sha256: "1372760c6b389842b77156203308940558a2817360154084368608413835fc26"
url: "https://pub.dev"
source: hosted
version: "0.9.3"
firebase_auth: firebase_auth:
dependency: "direct main" dependency: "direct main"
description: description:
@ -262,14 +310,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.2" version: "2.0.2"
flutter_plugin_android_lifecycle:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
sha256: "950e77c2bbe1692bc0874fc7fb491b96a4dc340457f4ea1641443d0a6c1ea360"
url: "https://pub.dev"
source: hosted
version: "2.0.15"
flutter_screenutil: flutter_screenutil:
dependency: "direct main" dependency: "direct main"
description: description:
name: flutter_screenutil name: flutter_screenutil
sha256: "0a122936b450324cbdfd51be0819cc6fcebb093eb65585e9cd92263f7a1a8a39" sha256: "1b61f8c4cbf965104b6ca7160880ff1af6755aad7fec70b58444245132453745"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "5.7.0" version: "5.8.4"
flutter_signin_button: flutter_signin_button:
dependency: "direct main" dependency: "direct main"
description: description:
@ -296,6 +352,54 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "9.2.0" version: "9.2.0"
geolocator:
dependency: "direct main"
description:
name: geolocator
sha256: "5c23f3613f50586c0bbb2b8f970240ae66b3bd992088cf60dd5ee2e6f7dde3a8"
url: "https://pub.dev"
source: hosted
version: "9.0.2"
geolocator_android:
dependency: transitive
description:
name: geolocator_android
sha256: b06c72853c993ae533f482d81a12805d7a441f5231d9668718bc7131d7464082
url: "https://pub.dev"
source: hosted
version: "4.2.0"
geolocator_apple:
dependency: transitive
description:
name: geolocator_apple
sha256: "36527c555f4c425f7d8fa8c7c07d67b78e3ff7590d40448051959e1860c1cfb4"
url: "https://pub.dev"
source: hosted
version: "2.2.7"
geolocator_platform_interface:
dependency: transitive
description:
name: geolocator_platform_interface
sha256: af4d69231452f9620718588f41acc4cb58312368716bfff2e92e770b46ce6386
url: "https://pub.dev"
source: hosted
version: "4.0.7"
geolocator_web:
dependency: transitive
description:
name: geolocator_web
sha256: f68a122da48fcfff68bbc9846bb0b74ef651afe84a1b1f6ec20939de4d6860e1
url: "https://pub.dev"
source: hosted
version: "2.1.6"
geolocator_windows:
dependency: transitive
description:
name: geolocator_windows
sha256: f5911c88e23f48b598dd506c7c19eff0e001645bdc03bb6fecb9f4549208354d
url: "https://pub.dev"
source: hosted
version: "0.1.1"
google_fonts: google_fonts:
dependency: "direct main" dependency: "direct main"
description: description:
@ -324,10 +428,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: http name: http
sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482" sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.13.5" version: "0.13.6"
http_parser: http_parser:
dependency: transitive dependency: transitive
description: description:
@ -336,6 +440,78 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.0.2" version: "4.0.2"
image_picker:
dependency: "direct main"
description:
name: image_picker
sha256: "6296e98782726d37f59663f0727d0e978eee1ced1ffed45ccaba591786a7f7b3"
url: "https://pub.dev"
source: hosted
version: "1.0.1"
image_picker_android:
dependency: transitive
description:
name: image_picker_android
sha256: "8179b54039b50eee561676232304f487602e2950ffb3e8995ed9034d6505ca34"
url: "https://pub.dev"
source: hosted
version: "0.8.7+4"
image_picker_for_web:
dependency: transitive
description:
name: image_picker_for_web
sha256: "869fe8a64771b7afbc99fc433a5f7be2fea4d1cb3d7c11a48b6b579eb9c797f0"
url: "https://pub.dev"
source: hosted
version: "2.2.0"
image_picker_ios:
dependency: transitive
description:
name: image_picker_ios
sha256: b3e2f21feb28b24dd73a35d7ad6e83f568337c70afab5eabac876e23803f264b
url: "https://pub.dev"
source: hosted
version: "0.8.8"
image_picker_linux:
dependency: transitive
description:
name: image_picker_linux
sha256: "02cbc21fe1706b97942b575966e5fbbeaac535e76deef70d3a242e4afb857831"
url: "https://pub.dev"
source: hosted
version: "0.2.1"
image_picker_macos:
dependency: transitive
description:
name: image_picker_macos
sha256: cee2aa86c56780c13af2c77b5f2f72973464db204569e1ba2dd744459a065af4
url: "https://pub.dev"
source: hosted
version: "0.2.1"
image_picker_platform_interface:
dependency: transitive
description:
name: image_picker_platform_interface
sha256: c1134543ae2187e85299996d21c526b2f403854994026d575ae4cf30d7bb2a32
url: "https://pub.dev"
source: hosted
version: "2.9.0"
image_picker_windows:
dependency: transitive
description:
name: image_picker_windows
sha256: c3066601ea42113922232c7b7b3330a2d86f029f685bba99d82c30e799914952
url: "https://pub.dev"
source: hosted
version: "0.2.1"
insta_image_viewer:
dependency: "direct main"
description:
name: insta_image_viewer
sha256: "9a81432b1ab907ea91c255ec079440afe43f999533422badffaa482dfb7fdfbb"
url: "https://pub.dev"
source: hosted
version: "1.0.2"
ionicons: ionicons:
dependency: "direct main" dependency: "direct main"
description: description:
@ -356,10 +532,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: lints name: lints
sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.1" version: "2.1.1"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:
@ -384,6 +560,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.9.1" version: "1.9.1"
mime:
dependency: transitive
description:
name: mime
sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e
url: "https://pub.dev"
source: hosted
version: "1.0.4"
modal_bottom_sheet: modal_bottom_sheet:
dependency: "direct main" dependency: "direct main"
description: description:
@ -448,6 +632,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.7" version: "2.1.7"
pinch_zoom:
dependency: "direct main"
description:
name: pinch_zoom
sha256: ad12872281742726afaf03438d99a4572c584a612630768953beb6dfd6f9389a
url: "https://pub.dev"
source: hosted
version: "1.0.0"
platform: platform:
dependency: transitive dependency: transitive
description: description:
@ -477,6 +669,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.0" version: "1.1.0"
smooth_list_view:
dependency: "direct main"
description:
name: smooth_list_view
sha256: d6eb3bed78881c50d4574b0dd466ed3321972477688c1c021178f3132155112a
url: "https://pub.dev"
source: hosted
version: "1.0.4"
source_span: source_span:
dependency: transitive dependency: transitive
description: description:
@ -549,6 +749,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.1.0" version: "3.1.0"
tuple:
dependency: "direct main"
description:
name: tuple
sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151
url: "https://pub.dev"
source: hosted
version: "2.0.2"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
@ -577,10 +785,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: win32 name: win32
sha256: "5a751eddf9db89b3e5f9d50c20ab8612296e4e8db69009788d6c8b060a84191c" sha256: f2add6fa510d3ae152903412227bda57d0d5a8da61d2c39c1fb022c9429a41c0
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.1.4" version: "5.0.6"
xdg_directories: xdg_directories:
dependency: transitive dependency: transitive
description: description:
@ -598,5 +806,5 @@ packages:
source: hosted source: hosted
version: "1.1.0" version: "1.1.0"
sdks: sdks:
dart: ">=3.0.0-0 <4.0.0" dart: ">=3.0.0 <4.0.0"
flutter: ">=3.3.0" flutter: ">=3.10.0"

@ -56,6 +56,13 @@ dependencies:
firebase_core: ^2.15.0 firebase_core: ^2.15.0
firebase_auth: ^4.7.2 firebase_auth: ^4.7.2
cloud_firestore: ^4.8.4 cloud_firestore: ^4.8.4
image_picker: ^1.0.1
insta_image_viewer: ^1.0.2
pinch_zoom: ^1.0.0
smooth_list_view: ^1.0.4
animated_appear: ^0.0.4
geolocator: ^9.0.2
tuple: ^2.0.2
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

@ -57,4 +57,27 @@ Future<void> main() async {
} }
} }
print('\nPlaylist Musics :');
List<Music> playlistMusics = await musicVM.getMusicsWithPlaylistId('37i9dQZF1DX1X23oiQRTB5');
for (Music m in playlistMusics) {
print("id : ${m.id.toString()}, cover : ${m.cover}, title : ${m.title}");
print("date : ${m.date.toString()}, preview : ${m.previewUrl}, duration : ${m.duration}, explicit : ${m.explicit}");
for (Artist a in m.artists) {
print("id : ${a.id}, name : ${a.name}");
}
}
print('\nMusics With Ids :');
List<Music> musicsIds = await musicVM.getMusicsWithIds(['6D1HiF2e3Z0F8FwQ5uLxwn','6IGg7qsBvA5xbrwz3MNHWK']);
for (Music m in musicsIds) {
print("id : ${m.id.toString()}, cover : ${m.cover}, title : ${m.title}");
print("date : ${m.date.toString()}, preview : ${m.previewUrl}, duration : ${m.duration}, explicit : ${m.explicit}");
for (Artist a in m.artists) {
print("id : ${a.id}, name : ${a.name}");
}
}
} }

Loading…
Cancel
Save