Skip to content
Snippets Groups Projects
Commit 3af0a0b5 authored by MagicalSpyto's avatar MagicalSpyto
Browse files
parents 5ce1cbbe 0c8a927f
No related branches found
No related tags found
No related merge requests found
Showing
with 623 additions and 301 deletions
File added
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
sdk.dir=/Users/Erik/Library/Android/sdk
flutter.sdk=/opt/homebrew/Caskroom/flutter/3.3.9/flutter
flutter.buildMode=debug
flutter.versionName=1.0.0
flutter.versionCode=1
\ No newline at end of file
......@@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
import '../firebase.dart';
//Suchleiste mit den Vorschlägen aller Genres aus Spotify
class CustomSearchDelegate extends SearchDelegate<String>{
String colorText;
CustomSearchDelegate(this.colorText);
......
......@@ -5,25 +5,29 @@ import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_custom_clippers/flutter_custom_clippers.dart';
import '../main.dart';
import '../widgets/MusicPlayerState.dart';
import 'CustomSearchDelegate.dart';
import '../homepage.dart';
import 'package:google_fonts/google_fonts.dart';
/*
Klasse & Screen zur Klassifizierung der Farben zu den Genres.
Es gibt eine graue Default Seite wenn keine Farbe ausgewählt ist.
Wenn eine Farbe ausgewählt wird, kann man das Genre dazu auswählen.
Die Klassifizierung wird dann in der Datenbank aktualisiert
*/
class ClassificationPage extends StatefulWidget {
const ClassificationPage({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() => _ClassificationPageState();
}
class _ClassificationPageState extends State<ClassificationPage> {
final String id = (FirebaseAuth.instance.currentUser?.uid.toString())!+'_genres';
Color _ambientBackgroundColor = Colors.grey.withOpacity(0.5);
Color _ambientHeader = Colors.white;
String genreValue = '';
bool _redSelected = false;
......@@ -47,35 +51,54 @@ class _ClassificationPageState extends State<ClassificationPage> {
return Scaffold(
resizeToAvoidBottomInset: false,
body: Container(
color: _ambientBackgroundColor,
child: Column(
children: [
ClipPath(
clipper: WaveClipperTwo(flip: true),
const SizedBox(height: 40,),
SizedBox( height: 50, width: 300,
child: Text('Ambient!',
style:
GoogleFonts.cabin(
fontSize: 40.0, color: Colors.white.withOpacity(0.85)),),),
const SizedBox(height: 20,),
SizedBox(
height: 80,
width: 300,
child : Text('Select the genre that fits to the emotion of each color',
style:
GoogleFonts.cabin(
fontSize: 20.0, color: Colors.white.withOpacity(0.85),),),),
Expanded(
child: Container(
height: 140,
color: _ambientBackgroundColor,
child: Center(
child: Text(
'Ambient!',
style: TextStyle(
fontSize: 40.0, color: _ambientHeader),
height: 50,
decoration: BoxDecoration(
color: Color(0xffffffff),
borderRadius: BorderRadius.only(topLeft: Radius.circular(50),topRight: Radius.circular(50)),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 3),
),
),),),
Expanded(
],),
child: ListView(
children: <Widget>[
const SizedBox(height: 20,),
GestureDetector(
onTap: (){
onTap: () async {
if(!_redSelected){closeAll(); setState(() => _redSelected = true); }
else{closeAll();}
_ambientBackgroundColor = Colors.red;
if (!_redSelected){_ambientBackgroundColor = Colors.grey.withOpacity(0.5);}},
child: Container(
child: _redSelected ?
selectedColor("Red", Colors.red, Colors.white.withOpacity(0.7),
selectedColor("Red", Colors.red, Colors.white.withOpacity(0.9),
"rock","latin", "blues",
'Starke Emotionen, Liebe, Energie') : noSelection("Red")
'Strong emotions, love, energie') : noSelection("Red")
)
,),
const SizedBox(height: 20,),
......@@ -87,8 +110,8 @@ class _ClassificationPageState extends State<ClassificationPage> {
if (!_orangeSelected){_ambientBackgroundColor = Colors.grey.withOpacity(0.5);}},
child: Container(
child: _orangeSelected ?
selectedColor("Orange", Colors.orange, Colors.white.withOpacity(0.7),
"soul", "jazz", "Orange 3", 'Wärme, Energie, Herbst') : noSelection("Orange")
selectedColor("Orange", Colors.orange, Colors.white.withOpacity(0.9),
"soul", "jazz", "indie-pop", 'warmth, energie, fall') : noSelection("Orange")
)
,),
const SizedBox(height: 20,),
......@@ -101,7 +124,7 @@ class _ClassificationPageState extends State<ClassificationPage> {
child: Container(
child: _yellowSelected ?
selectedColor("Yellow", Colors.yellow, Colors.white,
"pop", "funk", "country", 'Freude, Optimismus, Wärme') : noSelection("Yellow")
"pop", "funk", "country", 'happiness, optimism, warmth') : noSelection("Yellow")
)
,),
const SizedBox(height: 20,),
......@@ -113,8 +136,8 @@ class _ClassificationPageState extends State<ClassificationPage> {
if (!_greenSelected){_ambientBackgroundColor = Colors.grey.withOpacity(0.5);}},
child: Container(
child: _greenSelected ?
selectedColor("Green", Colors.green, Colors.white.withOpacity(0.7),
"ambient", "classical", "new-age", 'Ruhe, Wachstum, Natur') : noSelection("Green")
selectedColor("Green", Colors.green, Colors.white.withOpacity(0.9),
"ambient", "classical", "new-age", 'calmness, growth, nature') : noSelection("Green")
)
,),
const SizedBox(height: 20,),
......@@ -122,12 +145,12 @@ class _ClassificationPageState extends State<ClassificationPage> {
onTap: (){
if(!_whiteSelected){closeAll(); setState(() => _whiteSelected = true); }
else{closeAll();}
_ambientBackgroundColor = Colors.white60;
_ambientBackgroundColor = Colors.grey.withOpacity(0.5);
if (!_whiteSelected){_ambientBackgroundColor = Colors.grey.withOpacity(0.5);}},
child: Container(
child: _whiteSelected ?
selectedColor("White", Colors.white60, Colors.grey,
"classical", "ambient", "piano", 'Reinheit, Frieden, Gelassenheit') : noSelection("White")
selectedColor("White", Colors.white, Colors.grey.withOpacity(0.7),
"classical", "ambient", "piano", 'calmness, peace, serenity') : noSelection("White")
)
,),
const SizedBox(height: 20,),
......@@ -139,8 +162,8 @@ class _ClassificationPageState extends State<ClassificationPage> {
if (!_blueSelected){_ambientBackgroundColor = Colors.grey.withOpacity(0.5);}},
child: Container(
child: _blueSelected ?
selectedColor( "Blue", Colors.blue, Colors.white.withOpacity(0.7),
"blues", "rainy-day", "indie-pop", 'Ruhe, Gelassenheit, Traurigkeit') : noSelection("Blue")
selectedColor( "Blue", Colors.blue, Colors.white.withOpacity(0.9),
"blues", "rainy-day", "indie-pop", 'calm, Gelassenheit, sadness') : noSelection("Blue")
)
,),
const SizedBox(height: 20,),
......@@ -153,8 +176,8 @@ class _ClassificationPageState extends State<ClassificationPage> {
child: Container(
child: _pinkSelected ?
selectedColor(
"Pink", Colors.pink, Colors.white.withOpacity(0.7),
"pop", "k-pop", "r-n-b", 'Romantik, Anmut, Nostalgie') : noSelection("Pink")
"Pink", Colors.pink, Colors.white.withOpacity(0.9),
"pop", "k-pop", "r-n-b", 'romance, charm, nostalgia') : noSelection("Pink")
)
,),
const SizedBox(height: 20,),
......@@ -166,8 +189,8 @@ class _ClassificationPageState extends State<ClassificationPage> {
if (!_purpleSelected){_ambientBackgroundColor = Colors.grey.withOpacity(0.5);}},
child: Container(
child: _purpleSelected ?
selectedColor("Purple", Colors.purple, Colors.white.withOpacity(0.7),
"rock", "classical", "hip-hop", 'Luxus, Spiritualität, Ambition') : noSelection("Purple")
selectedColor("Purple", Colors.purple, Colors.white.withOpacity(0.9),
"rock", "classical", "hip-hop", 'luxury, spirituality, ambition') : noSelection("Purple")
)
,),
const SizedBox(height: 20,),
......@@ -179,8 +202,8 @@ class _ClassificationPageState extends State<ClassificationPage> {
if (!_brownSelected){_ambientBackgroundColor = Colors.grey.withOpacity(0.5);}},
child: Container(
child: _brownSelected ?
selectedColor("Brown", Colors.brown, Colors.white.withOpacity(0.7),
"country", "Brown2", "Brown3", 'info') : noSelection("Brown")
selectedColor("Brown", Colors.brown, Colors.white.withOpacity(0.9),
"country", "folk", "reggae", 'warmth, security, nostalgia, calm') : noSelection("Brown")
)
,),
const SizedBox(height: 20,),
......@@ -188,29 +211,33 @@ class _ClassificationPageState extends State<ClassificationPage> {
onTap: () {
if(!_blackSelected){closeAll(); setState(() => _blackSelected = true); }
else{closeAll();}
_ambientBackgroundColor = Colors.black54;
_ambientBackgroundColor = Colors.black87;
if (!_blackSelected){_ambientBackgroundColor = Colors.grey.withOpacity(0.5);}},
child: Container(
child: _blackSelected ?
selectedColor("Black", Colors.black54, Colors.white.withOpacity(0.7), "Black1", "Black2", "Black3", 'info') : noSelection("Black")
selectedColor("Black", Colors.black87, Colors.white.withOpacity(0.7),
"metal", "classical", "rock", 'melancholy, power, noble') : noSelection("Black")
)
,),
const SizedBox(height: 20,),
SizedBox(
width: 100,
Align(
alignment: Alignment.center,
child: Container(
width: 200, height: 40,
child : StreamBuilder(
//Es wird in der Datenbank geprüft, ob zu allen Farben ein Genre ausgewählt wurde
stream: FirebaseFirestore.instance.collection('classification').doc(id).snapshots(),
builder: (BuildContext context,
AsyncSnapshot snapshot) {
return ElevatedButton(
style:ButtonStyle(backgroundColor: MaterialStatePropertyAll<Color>(Colors.white.withOpacity(0.9))),
style:ButtonStyle(
backgroundColor: MaterialStatePropertyAll<Color>(Colors.white.withOpacity(0.9))),
child: const Text(
"Save",
style: TextStyle(color: Colors.indigo, fontWeight: FontWeight.bold),),
"Save", style: TextStyle(color: Colors.indigo, fontWeight: FontWeight.bold),),
onPressed: () {
print(changeFirebase().checkIfEverythingSelected(snapshot).toString());
if (changeFirebase().checkIfEverythingSelected(snapshot)) {
Navigator.push(context, MaterialPageRoute(builder: (context) => HUD()));
Navigator.push(context, MaterialPageRoute(builder: (context)=>MusicPlayerState(child: const HUD())));
}
else{
setState(() {
......@@ -218,7 +245,7 @@ class _ClassificationPageState extends State<ClassificationPage> {
});
}
});
})),
}))),
Container(
child: _errorText ?
const Text('Not everything is selected!',
......@@ -226,10 +253,8 @@ class _ClassificationPageState extends State<ClassificationPage> {
style: TextStyle( fontSize: 20, color: Colors.red),)
: null
),
SizedBox(height: 40,)
]),
),
]
const SizedBox(height: 40,)
]),),)]
)
));
}
......@@ -240,88 +265,75 @@ class _ClassificationPageState extends State<ClassificationPage> {
style: TextStyle(fontSize: 20, color: Colors.red)
);
}
//wenn die Farbe nicht ausgewählt ist, wird kein Genre-Auswahl dargestellt und die Farben sind grau
Column noSelection(String colorText) {
return Column(
Align noSelection(String colorText) {
return Align(
alignment: Alignment.center,
child:Container(
width: 320,
decoration: BoxDecoration(
color: Colors.transparent,
border: Border.all(
color: Colors.grey.shade300, width: 1),
borderRadius: BorderRadius.circular(10),),
child: Column(
children: [
SizedBox(height: 50,),
Row(
children: [
const SizedBox(width: 30, height: 50),
const SizedBox(width: 25),
Text(colorText,
style: const TextStyle(fontSize: 30, color: Colors.grey)),
]
),
Align(
alignment: Alignment.center,
child: Row(
style: GoogleFonts.cabin(fontSize: 20.0, color: Colors.grey.shade400,)),]),
Row(
children: [
const SizedBox(width: 30),
Container(
width: 340,
decoration: BoxDecoration(
color: Colors.transparent,
border: Border.all(
color: Colors.grey,
width: 1),
borderRadius: BorderRadius.circular(10),
),
child: StreamBuilder(
const SizedBox(width: 25),
StreamBuilder(
stream: FirebaseFirestore.instance.collection('classification').doc(id).snapshots(),
builder: (BuildContext context, AsyncSnapshot snapshot){
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
}
return
Text(changeFirebase().checkForNull(snapshot.data.data()[colorText]), textAlign: TextAlign.center,
style: const TextStyle(fontSize: 20, color: Colors.grey),);
}
)
)
]
)
)
]);
}
child: CircularProgressIndicator(),);}
return Text(changeFirebase().checkForNull(snapshot.data.data()[colorText]), textAlign: TextAlign.center,
style: GoogleFonts.cabin(fontSize: 40.0, color: Colors.grey.shade400,),);
}),]),
SizedBox(height: 5,)])));}
Column selectedColor(String colorText, Color color, Color textColor, String rec1, String rec2, String rec3, String infoText) {
return Column(
children: [
Row(
children: [
const SizedBox(width: 30, height: 50),
Text(colorText, style: TextStyle(fontSize: 30, color: color)),
IconButton(onPressed:(){
_showMyDialog(colorText, infoText);
},
alignment: Alignment.centerRight,
icon: Icon( Icons.info_outline, color: color),
),
],),
selectedGenre(colorText, color, textColor, rec1, rec2, rec3),
]);
}
Align selectedGenre(String colorText, Color color, Color textColor, String rec1, String rec2,
String rec3) {
//Wenn eine Farbe ausgewählt wird, werden die Farben entsprechend angepasst
//Und man kann ein Genre zu dieser Farbe auswählen
Align selectedColor(String colorText, Color color, Color textColor, String rec1, String rec2, String rec3, String infoText) {
return Align(
alignment: Alignment.center,
child: Column(
children: [
Row(
children: [
const SizedBox(width: 30),
Container(
width: 340,
child:Container(
width: 320,
decoration: BoxDecoration(
color: Colors.transparent,
border: Border.all(
color: color,
width: 1),
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.4),
blurRadius: 10.0,
spreadRadius: 2.0,
offset: const Offset(0.0, 0.0),)]),
child: Column(
children: [
Align(
alignment: Alignment.topRight,
child : IconButton(onPressed:(){
_showMyDialog(colorText, infoText);},
alignment: Alignment.centerRight,
icon: Icon( Icons.info_outline, color: textColor.withOpacity(0.7), size: 35,),),
),
child:
SizedBox(height: 0,),
Row(
children: [
const SizedBox(width: 25),
Text(colorText,
style: GoogleFonts.cabin(fontSize: 20.0, color: textColor,)),]),
Row(
children: [
const SizedBox(width: 25),
StreamBuilder(
stream: FirebaseFirestore.instance.collection('classification').doc(id).snapshots(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
......@@ -332,29 +344,10 @@ class _ClassificationPageState extends State<ClassificationPage> {
}
return
Text(changeFirebase().checkForNull(snapshot.data.data()[colorText]), textAlign: TextAlign.center,
style: TextStyle(color: color, fontSize: 20),);
style: GoogleFonts.cabin(fontSize: 40.0, color: textColor),);
}
),
) ]
),
const SizedBox(height: 30),
Container(
width: 340,
// alignment: Alignment.center,
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
blurRadius: 10.0,
spreadRadius: 2.0,
offset: const Offset(0.0, 0.0),
)
],
),
child: Column(
children: [
),]),
const SizedBox(height: 20,),
Container(
width: 290,
......@@ -402,17 +395,14 @@ class _ClassificationPageState extends State<ClassificationPage> {
),
const SizedBox(height: 50,)
]
)
]
)
)
]));
)])));
}
GestureDetector recommendationLabel(String colorText, String rec, Color textColor) {
return GestureDetector(
onTap: () => changeFirebase().updateColorGenre(colorText, rec),
onTap: () {
changeFirebase().updateColorGenre(colorText, rec);
closeAll();},
child:Container(
child: Row(
children: [
......@@ -430,12 +420,11 @@ class _ClassificationPageState extends State<ClassificationPage> {
style: TextStyle(fontSize: 20, color: textColor)
),
)
)]
)
),
)])),
);
}
//Info Dialog zur Erklärung der Farben-Emotionen
Future<void> _showMyDialog(String colorText, String infoText) {
return showDialog<void>(
context: context,
......@@ -447,8 +436,7 @@ class _ClassificationPageState extends State<ClassificationPage> {
child: ListBody(
children: <Widget>[
Text(infoText),
],
),
],),
),
actions: <Widget>[
TextButton(
......@@ -475,4 +463,5 @@ class _ClassificationPageState extends State<ClassificationPage> {
});
_ambientBackgroundColor = Colors.grey.withOpacity(0.5);
}
}
......@@ -36,40 +36,40 @@ class changeFirebase{
return true;
}
String getGenreByHex(String code){
Future<String> getGenreByHex(String code) async {
switch (code){
case 'FF0000':
return getGenreByColor('Red');
case 'FF8800':
return getGenreByColor('Orange');
return await getGenreByColor('Red');
case 'FFA500':
return await getGenreByColor('Orange');
case 'FFFF00':
return getGenreByColor('Yellow');
case 'FF8800':
case '00FF00':
return getGenreByColor('Green');
case 'FFFFFF':
return getGenreByColor('White');
case '0000FF':
return getGenreByColor('Blue');
case 'FFC0CB':
case 'FF46FD':
return getGenreByColor('Pink');
case 'A020F0':
case '7F45D8':
return getGenreByColor('Purple');
case '964B00':
case '67402D':
return getGenreByColor('Brown');
case '000000':
return getGenreByColor('Black');
}
return '';
return 'nothing';
}
String getGenreByColor(String color){
Future<String> getGenreByColor(String color) async {
String genre = '';
FutureBuilder<DocumentSnapshot>(
future: FirebaseFirestore.instance.collection('classification').doc(id).get(),
builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot){
genre = snapshot.data![color];
return const SizedBox();
await FirebaseFirestore.instance.collection('classification').doc(id).get().then((snapshot) async {
genre = await snapshot.data()![color];
return genre;
});
return genre;
}
}
\ No newline at end of file
......@@ -8,19 +8,18 @@ import 'package:flutter/services.dart';
import 'package:spotify_sdk/models/connection_status.dart';
import 'package:spotify_sdk/models/track.dart';
import 'package:spotify_sdk/spotify_sdk.dart';
import 'dart:developer' as developer;
import 'main.dart';
void printErr(String msg) {
developer.log(msg);
}
///After Login/Registration thr routing will bring you to this page
///This page will render the main MusicPlayer
class HomePage extends StatelessWidget {
final pageController;
const HomePage({super.key, this.pageController});
/// the root of the page will be rendered if the connection status changes or
/// a function emits in the rebuildStream
@override
Widget build(BuildContext context) {
return StreamBuilder<ConnectionStatus>(
......@@ -38,6 +37,9 @@ class HomePage extends StatelessWidget {
);
}
/// builds PlayerStateWidget if the app is connected to Spotify,
/// otherwise it will display a connection button, that will initiate
/// the connection to the local spotify app on click
Widget player(BuildContext context) {
return Stack(children: [
Center(
......@@ -82,6 +84,8 @@ class HomePage extends StatelessWidget {
]);
}
/// The PlayerStateWidget builds the ControlButtons and the SongInfo, which
/// contains the SongTitle, AlbumTitle and AlbumImage
Widget _buildPlayerStateWidget(BuildContext context) {
Track? track;
if (MusicPlayerState.of(context).playerState == null) {
......@@ -115,50 +119,10 @@ class HomePage extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
MusicPlayerState.of(context).connected
? Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
MusicPlayerState.of(context).albumImage != null
? Padding(
padding: const EdgeInsets.only(top: 30),
child: DropShadowImage(
image: Image(
image: MusicPlayerState.of(context)
.albumImage!
.image,
width: 250,
height: 250,
),
offset: Offset(10, 10),
scale: 1,
blurRadius: 10,
borderRadius: 20,
),
)
: MusicPlayerState.of(context).spotifyImageWidget(),
Container(
alignment: Alignment.topCenter,
padding: const EdgeInsets.all(2),
child: Column(children: [
Padding(
padding: const EdgeInsets.only(top: 20),
child: Text(track.name,
style: const TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.bold,
color: Colors.black)),
),
Padding(
padding: const EdgeInsets.only(top: 1),
child: Text(track.album.name),
),
]))
],
StreamBuilder<void>(
stream: MusicPlayerState.of(context).playStatedStream.stream,
builder: (context, _) => SongInfo(),
),
)
: const Text('Connect to see an image...'),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
......@@ -168,8 +132,8 @@ class HomePage extends StatelessWidget {
padding: EdgeInsets.zero,
child: Icon(Icons.skip_previous_outlined)),
onPressed: () {
skipPrevious;
MusicPlayerState.of(context).rebuildStream.sink.add(null);
var state = MusicPlayerState.of(context);
SpotifySdk.skipPrevious().then((value) => state.updatePlayerState());
}),
StreamBuilder<void>(
stream: MusicPlayerState.of(context).playStatedStream.stream,
......@@ -181,8 +145,8 @@ class HomePage extends StatelessWidget {
padding: EdgeInsets.zero,
child: Icon(Icons.skip_next_outlined)),
onPressed: () {
skipNext();
MusicPlayerState.of(context).rebuildStream.sink.add(null);
var state = MusicPlayerState.of(context);
SpotifySdk.skipNext().then((value) => state.updatePlayerState());
}),
],
),
......@@ -253,6 +217,7 @@ class HomePage extends StatelessWidget {
}
}
Future<void> checkIfAppIsActive(BuildContext context) async {
try {
......@@ -271,9 +236,10 @@ class HomePage extends StatelessWidget {
void setStatus(String code, {String? message}) {
var text = message ?? '';
printErr(text);
print(text);
}
//build snack bar that can be call for input feedback
void buildSnackbar(BuildContext context) {
final snackBar = SnackBar(
content: Text(MusicPlayerState.of(context).connected
......@@ -284,6 +250,73 @@ class HomePage extends StatelessWidget {
}
}
/// renders album image, song and album title
class SongInfo extends StatelessWidget{
const SongInfo({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
Track? track;
if (MusicPlayerState.of(context).playerState == null) {
return const Text("PlayState is Null");
} else {
track = MusicPlayerState.of(context).playerState!.track;
}
if (MusicPlayerState.of(context).connected && track != null){
return Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
MusicPlayerState.of(context).albumImage != null
? Padding(
padding: const EdgeInsets.only(top: 1),
child: DropShadowImage(
image: Image(
image: MusicPlayerState.of(context)
.albumImage!
.image,
width: 300,
height: 300,
),
offset: const Offset(10, 10),
scale: 1,
blurRadius: 10,
borderRadius: 20,
),
)
: MusicPlayerState.of(context).spotifyImageWidget(MusicPlayerState.of(context).currentTrackImageUri!),
Container(
alignment: Alignment.topCenter,
padding: const EdgeInsets.all(2),
child: Column(children: [
Padding(
padding: const EdgeInsets.only(top: 20),
child: Text(track.name,
style: const TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.bold,
color: Colors.black)),
),
Padding(
padding: const EdgeInsets.only(top: 1),
child: Text(track.album.name),
),
]))
],
),
);
} else {
return const Text('Connect to see an image...');
}
}
}
/// contains the play and pause button
/// on click the the PlayerStateStream will be called and rebuild this buttons
/// and the spotifySdk change the PlayerSate from the local spotify app
class ControlButtons extends StatelessWidget {
const ControlButtons({
Key? key,
......
import 'package:ambient/classification/classification.dart';
import 'package:ambient/loginRegister/registration.dart';
import 'package:ambient/loginRegister/widgets.dart';
import 'package:ambient/widgets/MusicPlayerState.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:page_transition/page_transition.dart';
import 'package:google_fonts/google_fonts.dart';
import '../homepage.dart';
import '../main.dart';
/*
Klasse zum Einloggen
Die Daten werden aus der Datenbank geholt
Entsprechende Fehlermeldungen werden abgefangen
*/
class LoginPage extends StatefulWidget {
const LoginPage({Key? key}) : super(key: key);
......@@ -29,7 +36,7 @@ class _LoginPageState extends State<LoginPage> {
return Stack(
children: <Widget>[
Image.asset("assets/ambientL.jpeg",
Image.asset("ambientL.jpeg",
alignment: Alignment.centerLeft,
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,),
......@@ -47,10 +54,11 @@ class _LoginPageState extends State<LoginPage> {
child : Column(
children:[
SizedBox(height: 80,),
const Expanded(
Expanded(
child: Text(
'Ambient!',
style: TextStyle(fontSize: 50.0, color: Colors.white),
style: GoogleFonts.cabin(
fontSize: 50.0, color: Colors.white,),
),),
Expanded(
child: Column(
......@@ -62,9 +70,9 @@ class _LoginPageState extends State<LoginPage> {
keyboardType: TextInputType.name,
decoration: const InputDecoration(
prefixIcon: Icon(Icons.person, color: Colors.white),
hintText: 'Username',
hintText: 'E-Mail',
hintStyle: TextStyle(color: Colors.white),
labelText: 'Username',
labelText: 'E-Mail',
labelStyle: TextStyle(color: Colors.white),
),
),),
......@@ -89,15 +97,17 @@ class _LoginPageState extends State<LoginPage> {
style: TextStyle(color: Colors.red),)
: const SizedBox(),
loginRegisterButton(context, true, (){
//Todo undo comment
FirebaseAuth.instance.signInWithEmailAndPassword(
email: _emailTextController.text,
password: _passwordTextController.text).then((value) {
Navigator.push(context, MaterialPageRoute(builder: (context)=>const HUD()));
Navigator.push(context, MaterialPageRoute(builder: (context)=>const ClassificationPage()));
}).onError((error, stackTrace){
setState(() {
_wrongInput = true;
});
});
Navigator.push(context, MaterialPageRoute(builder: (context)=>MusicPlayerState(child: const HUD())));
}),
registrationPage(),
......
......@@ -4,10 +4,15 @@ import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import '../classification/classification.dart';
import 'package:ambient/loginRegister/login.dart';
import 'package:page_transition/page_transition.dart';
import 'package:google_fonts/google_fonts.dart';
/*
Klasse zum Registrieren
Die User Daten werden in die Firebase Datenbank gespeichert
Fehlermeldungen beim Registrieren werden abgefangen
*/
class RegistrationPage extends StatefulWidget {
const RegistrationPage({Key? key}) : super(key: key);
......@@ -41,19 +46,19 @@ class _RegistrationPage extends State<RegistrationPage> {
Scaffold(
backgroundColor: Colors.transparent,
body: Center(
child :Container(
decoration: const BoxDecoration(
decoration: BoxDecoration(
),
child: SizedBox(width: 250, height: 600,
child : Column(
children:[
SizedBox(height: 40,),
const Expanded(
Expanded(
child: Text(
'Ambient!',
style: TextStyle(fontSize: 60.0, color: Colors.white),
style: GoogleFonts.cabin(
fontSize: 50.0, color: Colors.white,)
),),
Expanded(
......@@ -111,25 +116,27 @@ class _RegistrationPage extends State<RegistrationPage> {
),
loginRegisterButton(context, false, () {
try{
FirebaseAuth.instance.createUserWithEmailAndPassword(
email: _emailTextController.text,
password: _passwordTextController.text).then((value){
createSetUp();
print ("Created new account");
Navigator.push(context, MaterialPageRoute(builder: (context)=>ClassificationPage()));
});}
on FirebaseAuthException catch(e){
if(e.code == 'ERROR_EMAIL_ALREADY_IN_USE'){
}).onError((error, stackTrace){
String e = error.toString();
print('Error 1 ' + error.toString());
if(error.toString().contains('email-already-in-use')){
print("Email already in use");
setState(() {
_infoText = 'Email already in use';
});
}
if(e.code == 'weak-password'){
else if(error.toString().contains('weak-password')){
setState(() {
_infoText = 'weak Password';
});}
if(e.code == 'invalid-email'){
else if(error.toString().contains('invalid-email')){
setState(() {
_infoText = 'invalid email';
});}
......@@ -139,7 +146,7 @@ class _RegistrationPage extends State<RegistrationPage> {
});
}
};
});
}),
SizedBox(height: 20),
loginPage(),
......@@ -177,13 +184,10 @@ class _RegistrationPage extends State<RegistrationPage> {
);
}
Future addDisplayName() async{
FirebaseAuth.instance.currentUser?.updateDisplayName(_usernameTextController.text);
}
//Beim Anlegen eines Accounts werden auch die Farben angelegt,
//damit der User später die Genres zuordnen kann
Future createSetUp() async{
//final String id = '${FirebaseAuth.instance.currentUser?.uid.toString()}_genres';
final String id = (FirebaseAuth.instance.currentUser?.uid.toString())!+'_genres';
final user = FirebaseFirestore.instance.collection('classification').doc(id);
......@@ -200,6 +204,7 @@ class _RegistrationPage extends State<RegistrationPage> {
'Brown' : null,
'Black' : null,
};
print('set up');
await user.set(json);
}
}
\ No newline at end of file
......@@ -3,6 +3,8 @@ import 'package:flutter/material.dart';
import 'login.dart';
//Widgets für den Login/Registrations Screen
Container loginRegisterButton(
BuildContext context, bool isLogin, Function onTap) {
return Container(
......@@ -71,7 +73,6 @@ Container signOutButton(
//textWidth
height: 10,
child: Text(
text,
style: const TextStyle(
color: Colors.red),
......
import 'dart:io';
import 'package:ambient/loginRegister/registration.dart';
import 'package:ambient/searchpage.dart';
import 'package:ambient/widgets/MusicPlayerState.dart';
import 'package:ambient/widgets/navbars.dart';
......@@ -6,6 +7,7 @@ import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:spotify_sdk/models/player_state.dart';
import 'package:spotify_sdk/models/track.dart';
import 'package:spotify_sdk/spotify_sdk.dart';
......@@ -13,9 +15,11 @@ import 'package:spotify_sdk/spotify_sdk.dart';
import 'homepage.dart';
import 'moodpage.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp;
//loads config file for late usage
await dotenv.load(fileName: '.env');
runApp(const MyApp());
}
......@@ -26,11 +30,14 @@ class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(fontFamily: "GoogleFonts"),
debugShowCheckedModeBanner: false,
home: MusicPlayerState(
child: const HUD(),
//Todo change HUD() => RegistrationPage()
),
home: RegistrationPage(),
/**
* moin
* test123@test.com
* moin
*/
);
}
}
......@@ -48,6 +55,9 @@ Moods selectedMoodAsEnum = Moods.sad;
bool musicCangable = true;
/// Renders a static Top-/BottomBar
/// further pages will be loaded in the body of the material app
/// and can be switched via PageViewWidget
class HUD extends StatefulWidget {
const HUD({super.key});
......@@ -116,6 +126,8 @@ class _HUDState extends State<HUD> {
}
}
/// Renders a player control bar above the bottom bar.
/// It contains a the AlbumImage and a button to player/pause the track
class MusicBar extends StatelessWidget {
MusicBar({
Key? key,
......@@ -134,12 +146,10 @@ class MusicBar extends StatelessWidget {
return const Center(
child: Text('PlayState or track is Null'),
);
} else {
MusicPlayerState.of(context).currentTrackImageUri = track!.imageUri;
}
return Container(
height: 80,
color: Colors.grey,
color: primaryContainer,
child: Row(
children: [
MusicPlayerState.of(context).albumImage!,
......@@ -153,7 +163,7 @@ class MusicBar extends StatelessWidget {
child: Column(children: [
Padding(
padding: const EdgeInsets.only(bottom: 5, top: 5),
child: Text(track.name,
child: Text(track!.name,
style: const TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.bold,
......@@ -187,6 +197,5 @@ Color ligten(Color color, [double amount = .1]) {
final hsl = HSLColor.fromColor(color);
final hslLight = hsl.withLightness((hsl.lightness + amount).clamp(0.0, 1.0));
return hslLight.toColor();
}
\ No newline at end of file
......@@ -7,7 +7,9 @@ import 'package:spotify_sdk/models/image_uri.dart';
import 'package:spotify_sdk/models/player_state.dart';
import 'package:spotify_sdk/spotify_sdk.dart';
/// InheritedWidget that holds the state of your MusicPlayer
/// the rebuild stream builds the hole body
/// the playStatedStream only rebuild the Image, SongInfo and the ControlsButtons
class MusicPlayerState extends InheritedWidget {
MusicPlayerState({super.key, required super.child});
......@@ -19,7 +21,6 @@ class MusicPlayerState extends InheritedWidget {
late ImageUri? currentTrackImageUri;
Image? albumImage;
static MusicPlayerState? maybeOf(BuildContext context) =>
context.dependOnInheritedWidgetOfExactType<MusicPlayerState>();
......@@ -34,14 +35,14 @@ class MusicPlayerState extends InheritedWidget {
rebuildStream.sink.add(null);
}
/// will be called on PlayStateChange
/// load new Imag e
void updatePlayerState() async {
playerState = await getPlayerState();
currentTrackImageUri = playerState?.track?.imageUri;
spotifyImageWidget();
//rebuildStream.sink.add(null);
playStatedStream.sink.add(null);
loadAlbumImage().then((value) => playStatedStream.sink.add(null));
}
///disconnect your app from your local spotify app
Future<void> disconnect() async {
try {
setLoading(true);
......@@ -57,6 +58,10 @@ class MusicPlayerState extends InheritedWidget {
}
}
/// establish connection to local spotify app
/// connection data will be loaded in main from dotenv.env
/// if connection successful
/// connection will be set to true and loading to false
Future<bool> connectToSpotifyRemote() async {
try {
setLoading(true);
......@@ -81,11 +86,10 @@ class MusicPlayerState extends InheritedWidget {
return connected;
}
Widget spotifyImageWidget() {
Widget spotifyImageWidget(ImageUri imageUri) {
return FutureBuilder(
future: SpotifySdk.getImage(
imageUri: currentTrackImageUri!,
imageUri: imageUri,
dimension: ImageDimension.large,
),
builder: (BuildContext context, AsyncSnapshot<Uint8List?> snapshot) {
......@@ -111,11 +115,22 @@ class MusicPlayerState extends InheritedWidget {
}
///loads the Album image via spotify.sdk and saves the image in MusicPlayState
///for global access
Future<void> loadAlbumImage() async {
currentTrackImageUri = playerState?.track?.imageUri;
albumImage = Image.memory((await SpotifySdk.getImage(
imageUri: currentTrackImageUri!,
dimension: ImageDimension.large,
))!);
}
void setStatus(String code, {String? message}) {
var text = message ?? '';
print(text);
}
//get PlayState from local spotify app
Future<PlayerState?> getPlayerState() async {
try {
return await SpotifySdk.getPlayerState();
......
......@@ -10,7 +10,7 @@ import cloud_firestore
import firebase_auth
import firebase_core
import just_audio
import path_provider_macos
import path_provider_foundation
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin"))
......
......@@ -49,7 +49,7 @@ packages:
name: cloud_firestore
url: "https://pub.dartlang.org"
source: hosted
version: "4.3.1"
version: "4.3.0"
cloud_firestore_platform_interface:
dependency: transitive
description:
......@@ -63,7 +63,7 @@ packages:
name: cloud_firestore_web
url: "https://pub.dartlang.org"
source: hosted
version: "3.2.1"
version: "3.2.0"
collection:
dependency: transitive
description:
......@@ -84,7 +84,7 @@ packages:
name: cross_file
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.3+2"
version: "0.3.3+4"
crypto:
dependency: transitive
description:
......@@ -140,28 +140,28 @@ packages:
name: file_picker
url: "https://pub.dartlang.org"
source: hosted
version: "5.2.4"
version: "5.2.5"
firebase_auth:
dependency: "direct main"
description:
name: firebase_auth
url: "https://pub.dartlang.org"
source: hosted
version: "4.2.4"
version: "4.2.3"
firebase_auth_platform_interface:
dependency: transitive
description:
name: firebase_auth_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "6.11.7"
version: "6.11.6"
firebase_auth_web:
dependency: transitive
description:
name: firebase_auth_web
url: "https://pub.dartlang.org"
source: hosted
version: "5.2.4"
version: "5.2.3"
firebase_core:
dependency: "direct main"
description:
......@@ -233,6 +233,13 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
google_fonts:
dependency: "direct main"
description:
name: google_fonts
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.3"
google_nav_bar:
dependency: "direct main"
description:
......@@ -260,14 +267,14 @@ packages:
name: image_picker
url: "https://pub.dartlang.org"
source: hosted
version: "0.8.6"
version: "0.8.6+1"
image_picker_android:
dependency: transitive
description:
name: image_picker_android
url: "https://pub.dartlang.org"
source: hosted
version: "0.8.5+4"
version: "0.8.5+5"
image_picker_for_web:
dependency: transitive
description:
......@@ -281,7 +288,7 @@ packages:
name: image_picker_ios
url: "https://pub.dartlang.org"
source: hosted
version: "0.8.6+4"
version: "0.8.6+6"
image_picker_platform_interface:
dependency: transitive
description:
......@@ -309,7 +316,7 @@ packages:
name: json_annotation
url: "https://pub.dartlang.org"
source: hosted
version: "4.7.0"
version: "4.8.0"
just_audio:
dependency: "direct main"
description:
......@@ -400,7 +407,7 @@ packages:
name: path_provider
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.11"
version: "2.0.12"
path_provider_android:
dependency: transitive
description:
......@@ -408,13 +415,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.22"
path_provider_ios:
path_provider_foundation:
dependency: transitive
description:
name: path_provider_ios
name: path_provider_foundation
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.11"
version: "2.1.1"
path_provider_linux:
dependency: transitive
description:
......@@ -422,13 +429,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.7"
path_provider_macos:
dependency: transitive
description:
name: path_provider_macos
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.6"
path_provider_platform_interface:
dependency: transitive
description:
......@@ -524,7 +524,7 @@ packages:
name: synchronized
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.0+3"
version: "3.0.1"
term_glyph:
dependency: transitive
description:
......@@ -573,7 +573,7 @@ packages:
name: xdg_directories
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.0+2"
version: "0.2.0+3"
sdks:
dart: ">=2.18.5 <3.0.0"
flutter: ">=3.0.0"
......@@ -51,6 +51,7 @@ dependencies:
flutter_dotenv: ^5.0.2
drop_shadow_image: ^0.9.1
flutter_color_models: ^1.3.3+2
google_fonts: ^2.1.0
dev_dependencies:
flutter_test:
......@@ -81,6 +82,8 @@ flutter:
- assets/ambientR.jpeg
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
- ambientL.jpeg
- ambientR.jpeg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment