Implemented Icarus, can play songs from the Icarus server, and implemented a local SQLite database. #49, #15, #16
This commit is contained in:
@@ -25,6 +25,7 @@ namespace Mear.Droid
|
|||||||
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
|
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
|
||||||
LoadApplication(new App());
|
LoadApplication(new App());
|
||||||
|
|
||||||
|
CrossMediaManager.Current.Init(this);
|
||||||
}
|
}
|
||||||
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
|
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
<MonoAndroidResourcePrefix>Resources</MonoAndroidResourcePrefix>
|
<MonoAndroidResourcePrefix>Resources</MonoAndroidResourcePrefix>
|
||||||
<MonoAndroidAssetsPrefix>Assets</MonoAndroidAssetsPrefix>
|
<MonoAndroidAssetsPrefix>Assets</MonoAndroidAssetsPrefix>
|
||||||
<AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
|
<AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
|
||||||
<TargetFrameworkVersion>v8.1</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v9.0</TargetFrameworkVersion>
|
||||||
<AndroidEnableSGenConcurrent>true</AndroidEnableSGenConcurrent>
|
<AndroidEnableSGenConcurrent>true</AndroidEnableSGenConcurrent>
|
||||||
<AndroidHttpClientHandlerType>Xamarin.Android.Net.AndroidClientHandler</AndroidHttpClientHandlerType>
|
<AndroidHttpClientHandlerType>Xamarin.Android.Net.AndroidClientHandler</AndroidHttpClientHandlerType>
|
||||||
<NuGetPackageImportStamp>
|
<NuGetPackageImportStamp>
|
||||||
@@ -31,6 +31,9 @@
|
|||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<AndroidLinkMode>None</AndroidLinkMode>
|
<AndroidLinkMode>None</AndroidLinkMode>
|
||||||
|
<AotAssemblies>false</AotAssemblies>
|
||||||
|
<EnableLLVM>false</EnableLLVM>
|
||||||
|
<BundleAssemblies>false</BundleAssemblies>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
@@ -55,9 +58,6 @@
|
|||||||
<PackageReference Include="Plugin.MediaManager">
|
<PackageReference Include="Plugin.MediaManager">
|
||||||
<Version>0.6.1</Version>
|
<Version>0.6.1</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Plugin.MediaManager.Forms">
|
|
||||||
<Version>0.6.1</Version>
|
|
||||||
</PackageReference>
|
|
||||||
<PackageReference Include="RestSharp">
|
<PackageReference Include="RestSharp">
|
||||||
<Version>106.6.9</Version>
|
<Version>106.6.9</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.Mear">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.Mear" android:installLocation="auto">
|
||||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="27" />
|
<uses-sdk android:minSdkVersion="23" android:targetSdkVersion="28" />
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||||
|
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||||
|
<uses-permission android:name="android.permission.INSTANT_APP_FOREGROUND_SERVICE" />
|
||||||
<application android:label="Mear.Android"></application>
|
<application android:label="Mear.Android"></application>
|
||||||
</manifest>
|
</manifest>
|
||||||
+8371
-3399
File diff suppressed because it is too large
Load Diff
@@ -124,9 +124,6 @@
|
|||||||
<Reference Include="System.Numerics.Vectors" />
|
<Reference Include="System.Numerics.Vectors" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Plugin.MediaManager.Forms">
|
|
||||||
<Version>0.6.1</Version>
|
|
||||||
</PackageReference>
|
|
||||||
<PackageReference Include="RestSharp">
|
<PackageReference Include="RestSharp">
|
||||||
<Version>106.6.9</Version>
|
<Version>106.6.9</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
|
||||||
<PackageReference Include="Plugin.MediaManager" Version="0.6.1" />
|
<PackageReference Include="Plugin.MediaManager" Version="0.6.1" />
|
||||||
<PackageReference Include="Plugin.MediaManager.Forms" Version="0.6.1" />
|
|
||||||
<PackageReference Include="RestSharp" Version="106.6.9" />
|
<PackageReference Include="RestSharp" Version="106.6.9" />
|
||||||
<PackageReference Include="sqlite-net-pcl" Version="1.5.231" />
|
<PackageReference Include="sqlite-net-pcl" Version="1.5.231" />
|
||||||
<PackageReference Include="Xamarin.Forms" Version="4.0.0.425677" />
|
<PackageReference Include="Xamarin.Forms" Version="4.0.0.425677" />
|
||||||
@@ -49,4 +48,8 @@
|
|||||||
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
|
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Repositories\Local\" />
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
using MediaManager;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using RestSharp;
|
||||||
|
|
||||||
|
using Mear.Constants.API;
|
||||||
|
using Mear.Models;
|
||||||
|
using Mear.Models.Authentication;
|
||||||
|
|
||||||
|
namespace Mear.Playback
|
||||||
|
{
|
||||||
|
public class MearPlayer
|
||||||
|
{
|
||||||
|
#region Fields
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
public static async Task StreamSongDemoAsync(Song song)
|
||||||
|
{
|
||||||
|
string tmpFile = Path.GetTempPath() + "track.mp3";
|
||||||
|
|
||||||
|
if (File.Exists(tmpFile))
|
||||||
|
{
|
||||||
|
File.Delete(tmpFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var writer = File.OpenWrite(tmpFile))
|
||||||
|
{
|
||||||
|
var client = new RestClient(API.ApiUrl);
|
||||||
|
var request = new RestRequest($@"api/song/stream/{song.Id}", Method.GET);
|
||||||
|
request.ResponseWriter = (responseStream) =>
|
||||||
|
responseStream.CopyTo(writer);
|
||||||
|
|
||||||
|
var response = client.DownloadData(request);
|
||||||
|
|
||||||
|
await CrossMediaManager.Current.Play(tmpFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
var msg = ex.Message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using RestSharp;
|
||||||
|
|
||||||
|
using Mear.Constants.API;
|
||||||
|
using Mear.Models;
|
||||||
|
using Mear.Repositories.Database;
|
||||||
|
|
||||||
|
namespace Mear.Repositories.Remote
|
||||||
|
{
|
||||||
|
public class RemoteSongRepository
|
||||||
|
{
|
||||||
|
#region Fields
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
public List<Song> RetrieveSongs()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var client = new RestClient(API.ApiUrl);
|
||||||
|
var request = new RestRequest(@"api/song", Method.GET);
|
||||||
|
|
||||||
|
DBTokenRepository tkRepo = new DBTokenRepository();
|
||||||
|
var token = tkRepo.RetrieveToken();
|
||||||
|
request.AddHeader("Authorization", $"Bearer {token.AccessToken}");
|
||||||
|
|
||||||
|
var response = client.Execute(request);
|
||||||
|
|
||||||
|
var songs = JsonConvert.DeserializeObject<List<Song>>(response.Content);
|
||||||
|
|
||||||
|
return songs;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
var msg = ex.Message;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,25 +1,52 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
|
using Mear.Models;
|
||||||
|
using Mear.Repositories.Remote;
|
||||||
|
|
||||||
namespace Mear.ViewModels
|
namespace Mear.ViewModels
|
||||||
{
|
{
|
||||||
public class SongViewModel : BaseViewModel
|
public class SongViewModel : BaseViewModel
|
||||||
{
|
{
|
||||||
#region Fields
|
#region Fields
|
||||||
|
private ObservableCollection<Song> _songItems;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
|
public ObservableCollection<Song> SongItems
|
||||||
|
{
|
||||||
|
get => _songItems;
|
||||||
|
set => _songItems = value;
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
public SongViewModel()
|
public SongViewModel()
|
||||||
{
|
{
|
||||||
//Title = "Songs";
|
_songItems = new ObservableCollection<Song>();
|
||||||
|
|
||||||
|
PopulateSongs();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
public void PopulateSongs()
|
||||||
|
{
|
||||||
|
var songRepo = new RemoteSongRepository();
|
||||||
|
var songs = songRepo.RetrieveSongs().OrderBy(s => s.Title).ToList();
|
||||||
|
|
||||||
|
foreach (var song in songs)
|
||||||
|
{
|
||||||
|
_songItems.Add(song);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,47 @@
|
|||||||
</ContentPage.BindingContext>
|
</ContentPage.BindingContext>
|
||||||
|
|
||||||
<StackLayout>
|
<StackLayout>
|
||||||
<Label Text="Song view!" />
|
<ListView x:Name="SongListView"
|
||||||
|
ItemsSource="{Binding SongItems}"
|
||||||
|
VerticalOptions="FillAndExpand"
|
||||||
|
HasUnevenRows="False"
|
||||||
|
ItemSelected="SongListView_ItemSelected" >
|
||||||
|
<ListView.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<ViewCell Height="100">
|
||||||
|
<Grid Padding="5">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<StackLayout Grid.Row="0" Grid.Column="0">
|
||||||
|
<Label Text="{Binding Title}"
|
||||||
|
d:Text="{Binding .}"
|
||||||
|
LineBreakMode="NoWrap"
|
||||||
|
FontSize="15" />
|
||||||
|
<Label Text="{Binding Artist}"
|
||||||
|
d:Text="{Binding .}"
|
||||||
|
LineBreakMode="NoWrap"
|
||||||
|
FontSize="15" />
|
||||||
|
</StackLayout>
|
||||||
|
<ImageButton x:Name="SongOptions"
|
||||||
|
Grid.Row="0"
|
||||||
|
Grid.Column="1"
|
||||||
|
HorizontalOptions="End"
|
||||||
|
VerticalOptions="Center"
|
||||||
|
HeightRequest="10"
|
||||||
|
WidthRequest="80"
|
||||||
|
Source="Search.png"
|
||||||
|
CommandParameter="{Binding Id}"
|
||||||
|
Clicked="SongOptions_Clicked" />
|
||||||
|
</Grid>
|
||||||
|
</ViewCell>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListView.ItemTemplate>
|
||||||
|
</ListView>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</ContentPage>
|
</ContentPage>
|
||||||
@@ -7,14 +7,79 @@ using System.Threading.Tasks;
|
|||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
using Xamarin.Forms.Xaml;
|
using Xamarin.Forms.Xaml;
|
||||||
|
|
||||||
|
using Mear.Models;
|
||||||
|
using Mear.Playback;
|
||||||
|
using Mear.Repositories.Remote;
|
||||||
|
using Mear.ViewModels;
|
||||||
|
|
||||||
namespace Mear.Views
|
namespace Mear.Views
|
||||||
{
|
{
|
||||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||||
public partial class SongView : ContentPage
|
public partial class SongView : ContentPage
|
||||||
{
|
{
|
||||||
|
#region Fields
|
||||||
|
private SongViewModel _viewModel;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
public SongView()
|
public SongView()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
|
BindingContext = _viewModel = new SongViewModel();
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
#region Events
|
||||||
|
private async void SongListView_ItemSelected(object sender, SelectedItemChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var i = "here";
|
||||||
|
if (SongListView.SelectedItem == null)
|
||||||
|
{
|
||||||
|
SongListView.SelectedItem = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var song = (Song)SongListView.SelectedItem;
|
||||||
|
await MearPlayer.StreamSongDemoAsync(song);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
var msg = ex.Message;
|
||||||
|
}
|
||||||
|
|
||||||
|
SongListView.SelectedItem = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void SongOptions_Clicked(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var btn = (Button)sender;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
var msg = ex.Message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Test
|
||||||
|
public void TestRemoteSong()
|
||||||
|
{
|
||||||
|
var songRepo = new RemoteSongRepository();
|
||||||
|
var songs = songRepo.RetrieveSongs();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user