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);
|
||||
LoadApplication(new App());
|
||||
|
||||
CrossMediaManager.Current.Init(this);
|
||||
}
|
||||
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
|
||||
{
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<MonoAndroidResourcePrefix>Resources</MonoAndroidResourcePrefix>
|
||||
<MonoAndroidAssetsPrefix>Assets</MonoAndroidAssetsPrefix>
|
||||
<AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
|
||||
<TargetFrameworkVersion>v8.1</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v9.0</TargetFrameworkVersion>
|
||||
<AndroidEnableSGenConcurrent>true</AndroidEnableSGenConcurrent>
|
||||
<AndroidHttpClientHandlerType>Xamarin.Android.Net.AndroidClientHandler</AndroidHttpClientHandlerType>
|
||||
<NuGetPackageImportStamp>
|
||||
@@ -31,6 +31,9 @@
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AndroidLinkMode>None</AndroidLinkMode>
|
||||
<AotAssemblies>false</AotAssemblies>
|
||||
<EnableLLVM>false</EnableLLVM>
|
||||
<BundleAssemblies>false</BundleAssemblies>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -55,9 +58,6 @@
|
||||
<PackageReference Include="Plugin.MediaManager">
|
||||
<Version>0.6.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Plugin.MediaManager.Forms">
|
||||
<Version>0.6.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="RestSharp">
|
||||
<Version>106.6.9</Version>
|
||||
</PackageReference>
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
<?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">
|
||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="27" />
|
||||
<application android:label="Mear.Android"></application>
|
||||
<?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" android:installLocation="auto">
|
||||
<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>
|
||||
</manifest>
|
||||
+8371
-3399
File diff suppressed because it is too large
Load Diff
@@ -124,9 +124,6 @@
|
||||
<Reference Include="System.Numerics.Vectors" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Plugin.MediaManager.Forms">
|
||||
<Version>0.6.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="RestSharp">
|
||||
<Version>106.6.9</Version>
|
||||
</PackageReference>
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
|
||||
<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="sqlite-net-pcl" Version="1.5.231" />
|
||||
<PackageReference Include="Xamarin.Forms" Version="4.0.0.425677" />
|
||||
@@ -49,4 +48,8 @@
|
||||
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Repositories\Local\" />
|
||||
</ItemGroup>
|
||||
</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.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Xamarin.Forms;
|
||||
|
||||
using Mear.Models;
|
||||
using Mear.Repositories.Remote;
|
||||
|
||||
namespace Mear.ViewModels
|
||||
{
|
||||
public class SongViewModel : BaseViewModel
|
||||
{
|
||||
#region Fields
|
||||
private ObservableCollection<Song> _songItems;
|
||||
#endregion
|
||||
|
||||
|
||||
#region Properties
|
||||
public ObservableCollection<Song> SongItems
|
||||
{
|
||||
get => _songItems;
|
||||
set => _songItems = value;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Constructors
|
||||
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
|
||||
}
|
||||
|
||||
@@ -8,11 +8,52 @@
|
||||
xmlns:vm="clr-namespace:Mear.ViewModels"
|
||||
Title="{Binding Title}">
|
||||
|
||||
<ContentPage.BindingContext>
|
||||
<ContentPage.BindingContext>
|
||||
<vm:SongViewModel />
|
||||
</ContentPage.BindingContext>
|
||||
</ContentPage.BindingContext>
|
||||
|
||||
<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>
|
||||
</ContentPage>
|
||||
@@ -7,14 +7,79 @@ using System.Threading.Tasks;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
using Mear.Models;
|
||||
using Mear.Playback;
|
||||
using Mear.Repositories.Remote;
|
||||
using Mear.ViewModels;
|
||||
|
||||
namespace Mear.Views
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class SongView : ContentPage
|
||||
{
|
||||
#region Fields
|
||||
private SongViewModel _viewModel;
|
||||
#endregion
|
||||
|
||||
|
||||
#region Properties
|
||||
#endregion
|
||||
|
||||
|
||||
#region Constructors
|
||||
public SongView()
|
||||
{
|
||||
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