diff --git a/ios/Podfile.lock b/ios/Podfile.lock new file mode 100644 index 0000000000000000000000000000000000000000..22bfdf972c261d4a37a2a58adaf03dd21c057e89 --- /dev/null +++ b/ios/Podfile.lock @@ -0,0 +1,93 @@ +PODS: + - audio_session (0.0.1): + - Flutter + - DKImagePickerController/Core (4.3.4): + - DKImagePickerController/ImageDataManager + - DKImagePickerController/Resource + - DKImagePickerController/ImageDataManager (4.3.4) + - DKImagePickerController/PhotoGallery (4.3.4): + - DKImagePickerController/Core + - DKPhotoGallery + - DKImagePickerController/Resource (4.3.4) + - DKPhotoGallery (0.0.17): + - DKPhotoGallery/Core (= 0.0.17) + - DKPhotoGallery/Model (= 0.0.17) + - DKPhotoGallery/Preview (= 0.0.17) + - DKPhotoGallery/Resource (= 0.0.17) + - SDWebImage + - SwiftyGif + - DKPhotoGallery/Core (0.0.17): + - DKPhotoGallery/Model + - DKPhotoGallery/Preview + - SDWebImage + - SwiftyGif + - DKPhotoGallery/Model (0.0.17): + - SDWebImage + - SwiftyGif + - DKPhotoGallery/Preview (0.0.17): + - DKPhotoGallery/Model + - DKPhotoGallery/Resource + - SDWebImage + - SwiftyGif + - DKPhotoGallery/Resource (0.0.17): + - SDWebImage + - SwiftyGif + - file_picker (0.0.1): + - DKImagePickerController/PhotoGallery + - Flutter + - Flutter (1.0.0) + - image_picker_ios (0.0.1): + - Flutter + - just_audio (0.0.1): + - Flutter + - path_provider_ios (0.0.1): + - Flutter + - SDWebImage (5.14.3): + - SDWebImage/Core (= 5.14.3) + - SDWebImage/Core (5.14.3) + - SwiftyGif (5.4.3) + +DEPENDENCIES: + - audio_session (from `.symlinks/plugins/audio_session/ios`) + - file_picker (from `.symlinks/plugins/file_picker/ios`) + - Flutter (from `Flutter`) + - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`) + - just_audio (from `.symlinks/plugins/just_audio/ios`) + - path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`) + +SPEC REPOS: + trunk: + - DKImagePickerController + - DKPhotoGallery + - SDWebImage + - SwiftyGif + +EXTERNAL SOURCES: + audio_session: + :path: ".symlinks/plugins/audio_session/ios" + file_picker: + :path: ".symlinks/plugins/file_picker/ios" + Flutter: + :path: Flutter + image_picker_ios: + :path: ".symlinks/plugins/image_picker_ios/ios" + just_audio: + :path: ".symlinks/plugins/just_audio/ios" + path_provider_ios: + :path: ".symlinks/plugins/path_provider_ios/ios" + +SPEC CHECKSUMS: + audio_session: 4f3e461722055d21515cf3261b64c973c062f345 + DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac + DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179 + file_picker: 817ab1d8cd2da9d2da412a417162deee3500fc95 + Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 + image_picker_ios: b786a5dcf033a8336a657191401bfdf12017dabb + just_audio: baa7252489dbcf47a4c7cc9ca663e9661c99aafa + path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02 + SDWebImage: 9c36e66c8ce4620b41a7407698dda44211a96764 + SwiftyGif: 6c3eafd0ce693cad58bb63d2b2fb9bacb8552780 + +PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3 + +COCOAPODS: 1.11.3 diff --git a/lib/main.dart b/lib/main.dart index dc9db79828d931bebbdb116ad725d11888f7208a..c12dc3b515ff691216a70ab794d576a1b15d96ca 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,10 +1,10 @@ import 'dart:ffi'; -import 'package:ambient/searchpage.dart'; import 'package:ambient/widgets/navbars.dart'; import 'package:flutter/material.dart'; import 'homepage.dart'; import 'moodpage.dart'; +import 'searchpage.dart'; void main() { runApp(const MyApp()); @@ -28,7 +28,6 @@ const Color primaryContainer = Color(0xFFFFDFBD); const Color onPrimaryContainer = Color(0xFF312B25); class HUD extends StatefulWidget { - HUD({super.key}); @override @@ -37,19 +36,15 @@ class HUD extends StatefulWidget { class _HUDState extends State<HUD> { int _currentIndex = 0; - final List<String> _titleList = ["Player","Mood","Search"]; + final List<String> _titleList = ["Player", "Mood", "Search"]; String _title = ""; PageController _pageController = PageController(initialPage: 0); - - - @override void initState() { - _title = _titleList[0]; + _title = _titleList[0]; super.initState(); } - @override Widget build(BuildContext context) { @@ -67,7 +62,7 @@ class _HUDState extends State<HUD> { children: [ HomePage(), StateMoodPage(), - SearchPage(), + StateSearcgPage(), ], ), bottomNavigationBar: BottomNavigationBar( @@ -75,15 +70,17 @@ class _HUDState extends State<HUD> { backgroundColor: ligten(primaryContainer), selectedItemColor: primaryColor, unselectedItemColor: Colors.black, - items: const [ BottomNavigationBarItem( - icon: Icon(Icons.play_arrow_rounded), label: "Play",), + icon: Icon(Icons.play_arrow_rounded), + label: "Play", + ), BottomNavigationBarItem(icon: Icon(Icons.mood), label: "Moods"), BottomNavigationBarItem(icon: Icon(Icons.search), label: "Suchen"), ], onTap: (newIndex) { - _pageController.animateToPage(newIndex, duration: const Duration(milliseconds: 500), curve: Curves.ease); + _pageController.animateToPage(newIndex, + duration: const Duration(milliseconds: 500), curve: Curves.ease); _title = _titleList[newIndex]; }, ), diff --git a/lib/searchpage.dart b/lib/searchpage.dart index 413247b6c23c751e1e02c26040077a3b6285b28d..3f19965506dce2217d49e1a33ae5146a3e30a580 100644 --- a/lib/searchpage.dart +++ b/lib/searchpage.dart @@ -1,9 +1,77 @@ import 'package:flutter/material.dart'; -class SearchPage extends StatelessWidget { +import 'dart:developer'; + +import 'package:ambient/homepage.dart'; +import 'package:ambient/services/spotify.dart'; +import 'package:flutter/material.dart'; + +class StateSearcgPage extends StatefulWidget { + const StateSearcgPage({super.key}); + + @override + State<StateSearcgPage> createState() => SearchPage(); +} + +class SearchPage extends State<StateSearcgPage> { + final controller = TextEditingController(); + Spotify spotifyApi = Spotify(); + final List<Song> songs = List.empty(growable: true); + @override Widget build(BuildContext context) { return Scaffold( - ); + body: Padding( + padding: const EdgeInsets.all(10.0), + child: Column( + children: [ + const SizedBox( + height: 20, + ), + TextField( + onChanged: (value) { + updateList(value); + setState(() { + log(songs.length.toString()); + songs; + }); + }, + decoration: const InputDecoration( + labelText: 'Search', suffixIcon: Icon(Icons.search)), + ), + const SizedBox( + height: 20, + ), + Expanded( + child: ListView.builder( + itemCount: songs.length, + itemBuilder: ((context, index) { + Song song = songs[index]; + + return Card( + child: Padding( + padding: const EdgeInsets.all(10), + child: Row( + children: [ + Text(song.id), + Text(song.name), + Text(song.artist) + ], + ), + ), + ); + })), + ) + ], + ))); + } + + updateList(String searchedString) async { + log("abb"); + var searchList = await spotifyApi.search(searchedString); + + //for (var element in searchList) { + // songs.add(element); + //} } } diff --git a/lib/services/spotify.dart b/lib/services/spotify.dart index 7c0c2785c4482e550368b4d14bd82ddc3fa8d149..56b53ce7a5f7c5e1c0ae552e05e044b64a35162a 100644 --- a/lib/services/spotify.dart +++ b/lib/services/spotify.dart @@ -1,3 +1,4 @@ +import 'dart:convert'; import 'dart:developer'; import 'dart:io'; @@ -5,16 +6,59 @@ import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; class Spotify { + final clientId = '60cf1944b15d4f9fb223ba32ce6336d1'; + final clientSecret = 'd2a2fd28d1c14d14babd781b8d5b52f5'; + final email = 'ambient.spotify@gmail.com'; + final password = "Start123\$"; + + final scope = + 'user-library-modify playlist-modify-private playlist-read-private user-follow-read user-read-current-playing user-library-read user-read-private user-top-read user-follow-modify user-read-recent-played'; + var authToken = - "BQAJa2icyErbxED5g-IkEpAwR1QXUJJ8v1Kz1JpvxNWCgeMAk73z_uyMVLk9exZ7s3kfLYK9m-uJMvMIvdGhbSIDzq0GyjeKfVztWH4rSAlLrMoqRXoij1q0W3Wp6okhJzaDcVkG7RLeLzr1waa1Zv-0mbfrqFznK2c7X_K2G_5jx8Flu6bPACJBCI0KuupYJ1Mg19M"; + 'BQDXRnchqALaNiF-Sj8Gi2en29_RR_I4B5FxbCNVG2zk5gQygEQ3AWVGoWJm260tha8C09TtBt9nDr6oRPlQJYZoGgKN61EhNfCFiJMW4BC840NgoArcw1bTAUtP1s6RDbo8M4engY_-WxQKgr39m43z6wPuebCx6RrqBfFCY_NgCPYev-5405ob8ZPSKKdWwAwUhv3Yyv9FcfuQVk9pjBjcnv03XI51Yw'; + + generateAuthToken() async { + String encoded = base64Url.encode('$clientId:$clientSecret'.codeUnits); + + try { + final response = await http.post( + Uri.parse('https://accounts.spotify.com/api/token'), + body: { + 'grant_type': 'password', + 'username': email, + 'password': password, + 'scope': scope, + }, + headers: { + 'Authorization': encoded, + }, + ); + final responseJson = json.decode(response.body); + + authToken = responseJson['access_token']; + } catch (e) { + // TODO: Handle Error + } + } search(text) async { try { - var response = await http.get( - Uri.parse("https://api.spotify.com/v1/search?q=$text"), - headers: {HttpHeaders.authorizationHeader: authToken}, + final response = await http.get( + Uri.parse('https://api.spotify.com/v1/search?q=$text&type=track'), + headers: { + // 'Authorization': 'Bearer $authToken', + 'Authorization': + 'Bearer BQDXRnchqALaNiF-Sj8Gi2en29_RR_I4B5FxbCNVG2zk5gQygEQ3AWVGoWJm260tha8C09TtBt9nDr6oRPlQJYZoGgKN61EhNfCFiJMW4BC840NgoArcw1bTAUtP1s6RDbo8M4engY_-WxQKgr39m43z6wPuebCx6RrqBfFCY_NgCPYev-5405ob8ZPSKKdWwAwUhv3Yyv9FcfuQVk9pjBjcnv03XI51Yw"' + }, ); - return response; + + log(response.body); + final responseJson = json.decode(response.body); + final items = responseJson['tracks']['items'] as List; + + List songList = items.map((item) => Song.fromJson(item)).toList(); + + return songList; } catch (e) { log(e.toString()); } @@ -153,3 +197,26 @@ class Spotify { } } } + +class Song { + final String id; + final String name; + final String artist; + final String album; + + Song( + this.id, + this.name, + this.artist, + this.album, + ); + + factory Song.fromJson(Map<String, dynamic> json) { + return Song( + json['id'], + json['name'], + json['artists'][0]['name'], + json['album']['name'], + ); + } +}