Commit 7968641c authored by Martin Finkel's avatar Martin Finkel

Browsing works

parent 6fc1e1f4
......@@ -49,6 +49,9 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="VideoLAN.LibVLC.Android">
<Version>3.1.2</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms" Version="3.4.0.1008975" />
<PackageReference Include="Xamarin.Android.Support.Design" Version="27.0.2.1" />
<PackageReference Include="Xamarin.Android.Support.v7.AppCompat" Version="27.0.2.1" />
......
......@@ -4052,6 +4052,9 @@ namespace LocalNetwork.Droid
// aapt resource value: 0x7f0a0025
public const int abc_toolbar_collapse_description = 2131361829;
// aapt resource value: 0x7f0a003c
public const int app_name = 2131361852;
// aapt resource value: 0x7f0a0033
public const int appbar_scrolling_view_behavior = 2131361843;
......
......@@ -10,6 +10,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="LibVLCSharp.Forms" Version="0.8.1" />
<PackageReference Include="Xamarin.Forms" Version="3.4.0.1008975" />
</ItemGroup>
</Project>
\ No newline at end of file
using System;
using LibVLCSharp.Shared;
namespace LocalNetwork.Models
{
public class Item
{
public string Id { get; set; }
public string Text { get; set; }
public string Description { get; set; }
public Item(Media media)
{
Media = media;
Name = media.Meta(MetadataType.Title);
IsDirectory = media.Type == MediaType.Directory;
Type = IsDirectory ? "Directory" : "File";
}
public string Name { get; private set; }
public string Type { get; private set; }
public bool IsDirectory { get; private set; }
public Media Media { get; set; }
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace LocalNetwork.Services
{
public interface IDataStore<T>
{
Task<bool> AddItemAsync(T item);
Task<bool> UpdateItemAsync(T item);
Task<bool> DeleteItemAsync(string id);
Task<T> GetItemAsync(string id);
Task<IEnumerable<T>> GetItemsAsync(bool forceRefresh = false);
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using LocalNetwork.Models;
namespace LocalNetwork.Services
{
public class MockDataStore : IDataStore<Item>
{
List<Item> items;
public MockDataStore()
{
items = new List<Item>();
var mockItems = new List<Item>
{
new Item { Id = Guid.NewGuid().ToString(), Text = "First item", Description="This is an item description." },
new Item { Id = Guid.NewGuid().ToString(), Text = "Second item", Description="This is an item description." },
new Item { Id = Guid.NewGuid().ToString(), Text = "Third item", Description="This is an item description." },
new Item { Id = Guid.NewGuid().ToString(), Text = "Fourth item", Description="This is an item description." },
new Item { Id = Guid.NewGuid().ToString(), Text = "Fifth item", Description="This is an item description." },
new Item { Id = Guid.NewGuid().ToString(), Text = "Sixth item", Description="This is an item description." },
};
foreach (var item in mockItems)
{
items.Add(item);
}
}
public async Task<bool> AddItemAsync(Item item)
{
items.Add(item);
return await Task.FromResult(true);
}
public async Task<bool> UpdateItemAsync(Item item)
{
var oldItem = items.Where((Item arg) => arg.Id == item.Id).FirstOrDefault();
items.Remove(oldItem);
items.Add(item);
return await Task.FromResult(true);
}
public async Task<bool> DeleteItemAsync(string id)
{
var oldItem = items.Where((Item arg) => arg.Id == id).FirstOrDefault();
items.Remove(oldItem);
return await Task.FromResult(true);
}
public async Task<Item> GetItemAsync(string id)
{
return await Task.FromResult(items.FirstOrDefault(s => s.Id == id));
}
public async Task<IEnumerable<Item>> GetItemsAsync(bool forceRefresh = false)
{
return await Task.FromResult(items);
}
}
}
\ No newline at end of file
......@@ -2,18 +2,10 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Xamarin.Forms;
using LocalNetwork.Models;
using LocalNetwork.Services;
namespace LocalNetwork.ViewModels
{
public class BaseViewModel : INotifyPropertyChanged
{
public IDataStore<Item> DataStore => DependencyService.Get<IDataStore<Item>>() ?? new MockDataStore();
bool isBusy = false;
public bool IsBusy
{
......
using System;
using LibVLCSharp.Shared;
using LocalNetwork.Models;
namespace LocalNetwork.ViewModels
{
public class ItemDetailViewModel : BaseViewModel
{
public Item Item { get; set; }
public ItemDetailViewModel(Item item = null)
readonly Item _item;
public ItemDetailViewModel(Item item)
{
_item = item;
MediaPlayer = new MediaPlayer(item.Media);
MediaPlayer.Play();
}
private MediaPlayer _mediaPlayer;
public MediaPlayer MediaPlayer
{
Title = item?.Text;
Item = item;
get => _mediaPlayer;
private set => SetProperty(ref _mediaPlayer, value);
}
}
}
}
\ No newline at end of file
......@@ -6,7 +6,8 @@ using System.Threading.Tasks;
using Xamarin.Forms;
using LocalNetwork.Models;
using LocalNetwork.Views;
using LibVLCSharp.Shared;
using System.Collections.Generic;
namespace LocalNetwork.ViewModels
{
......@@ -14,19 +15,33 @@ namespace LocalNetwork.ViewModels
{
public ObservableCollection<Item> Items { get; set; }
public Command LoadItemsCommand { get; set; }
LibVLC _libVLC;
List<MediaDiscoverer> _mediaDiscoverers = new List<MediaDiscoverer>();
Item _directory;
public ItemsViewModel()
{
Title = "Browse";
Title = "Browse Local Network";
Items = new ObservableCollection<Item>();
LoadItemsCommand = new Command(async () => await ExecuteLoadItemsCommand());
MessagingCenter.Subscribe<NewItemPage, Item>(this, "AddItem", async (obj, item) =>
{
var newItem = item as Item;
Items.Add(newItem);
await DataStore.AddItemAsync(newItem);
});
InitializeLibVLC();
InitializeMediaDiscoverers();
}
public ItemsViewModel(Item item)
{
_directory = item;
Title = item.Name;
Items = new ObservableCollection<Item>();
LoadItemsCommand = new Command(async () => await ExecuteParseItemsCommand());
}
async Task<MediaParsedStatus> ExecuteParseItemsCommand()
{
_directory.Media.SubItems.ItemAdded += MediaList_ItemAdded;
return await _directory.Media.Parse(MediaParseOptions.ParseNetwork);
}
async Task ExecuteLoadItemsCommand()
......@@ -39,11 +54,10 @@ namespace LocalNetwork.ViewModels
try
{
Items.Clear();
var items = await DataStore.GetItemsAsync(true);
foreach (var item in items)
{
Items.Add(item);
}
DiscoverNetworkShares();
await Task.Delay(1000);
}
catch (Exception ex)
{
......@@ -54,5 +68,29 @@ namespace LocalNetwork.ViewModels
IsBusy = false;
}
}
private void InitializeMediaDiscoverers()
{
foreach (var md in _libVLC.MediaDiscoverers(MediaDiscovererCategory.Lan))
{
var discoverer = new MediaDiscoverer(_libVLC, md.Name);
discoverer.MediaList.ItemAdded += MediaList_ItemAdded;
_mediaDiscoverers.Add(discoverer);
}
}
void MediaList_ItemAdded(object sender, MediaListItemAddedEventArgs e) => Items.Add(new Item(e.Media));
void InitializeLibVLC()
{
if (_libVLC != null)
throw new Exception();
Core.Initialize();
_libVLC = new LibVLC();
}
private void DiscoverNetworkShares() => _mediaDiscoverers.ForEach(md => md.Start());
}
}
\ No newline at end of file
......@@ -2,11 +2,6 @@
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="LocalNetwork.Views.ItemDetailPage"
Title="{Binding Title}">
<StackLayout Spacing="20" Padding="15">
<Label Text="Text:" FontSize="Medium" />
<Label Text="{Binding Item.Text}" FontSize="Small"/>
<Label Text="Description:" FontSize="Medium" />
<Label Text="{Binding Item.Description}" FontSize="Small"/>
</StackLayout>
xmlns:vlc="clr-namespace:LibVLCSharp.Forms.Shared;assembly=LibVLCSharp.Forms">
<vlc:VideoView MediaPlayer="{Binding MediaPlayer}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"/>
</ContentPage>
\ No newline at end of file
using System;
using Xamarin.Forms;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using LocalNetwork.Models;
using LocalNetwork.ViewModels;
namespace LocalNetwork.Views
......@@ -19,19 +16,5 @@ namespace LocalNetwork.Views
BindingContext = this.viewModel = viewModel;
}
public ItemDetailPage()
{
InitializeComponent();
var item = new Item
{
Text = "Item 1",
Description = "This is an item description."
};
viewModel = new ItemDetailViewModel(item);
BindingContext = viewModel;
}
}
}
\ No newline at end of file
......@@ -4,16 +4,6 @@
x:Class="LocalNetwork.Views.ItemsPage"
Title="{Binding Title}"
x:Name="BrowseItemsPage">
<ContentPage.ToolbarItems>
<ToolbarItem Text="Add" Clicked="AddItem_Clicked">
<ToolbarItem.Icon>
<OnPlatform x:TypeArguments="FileImageSource">
<On Platform="UWP" Value="add.png"/>
</OnPlatform>
</ToolbarItem.Icon>
</ToolbarItem>
</ContentPage.ToolbarItems>
<StackLayout>
<ListView x:Name="ItemsListView"
ItemsSource="{Binding Items}"
......@@ -28,11 +18,11 @@
<DataTemplate>
<ViewCell>
<StackLayout Padding="10">
<Label Text="{Binding Text}"
<Label Text="{Binding Name}"
LineBreakMode="NoWrap"
Style="{DynamicResource ListItemTextStyle}"
FontSize="16" />
<Label Text="{Binding Description}"
<Label Text="{Binding Type}"
LineBreakMode="NoWrap"
Style="{DynamicResource ListItemDetailTextStyle}"
FontSize="13" />
......
......@@ -10,6 +10,7 @@ using Xamarin.Forms.Xaml;
using LocalNetwork.Models;
using LocalNetwork.Views;
using LocalNetwork.ViewModels;
using LibVLCSharp.Forms.Shared;
namespace LocalNetwork.Views
{
......@@ -25,23 +26,27 @@ namespace LocalNetwork.Views
BindingContext = viewModel = new ItemsViewModel();
}
public ItemsPage(Item item)
{
InitializeComponent();
BindingContext = viewModel = new ItemsViewModel(item);
}
async void OnItemSelected(object sender, SelectedItemChangedEventArgs args)
{
var item = args.SelectedItem as Item;
if (item == null)
return;
await Navigation.PushAsync(new ItemDetailPage(new ItemDetailViewModel(item)));
if(item.IsDirectory)
await Navigation.PushAsync(new ItemsPage(item));
else await Navigation.PushAsync(new ItemDetailPage(new ItemDetailViewModel(item)));
// Manually deselect item.
ItemsListView.SelectedItem = null;
}
async void AddItem_Clicked(object sender, EventArgs e)
{
await Navigation.PushModalAsync(new NavigationPage(new NewItemPage()));
}
protected override void OnAppearing()
{
base.OnAppearing();
......
using LocalNetwork.Models;
using System;
using LibVLCSharp.Shared;
using LocalNetwork.Models;
using System.Collections.Generic;
using System.Threading.Tasks;
using Xamarin.Forms;
......@@ -20,6 +20,11 @@ namespace LocalNetwork.Views
MenuPages.Add((int)MenuItemType.Browse, (NavigationPage)Detail);
}
protected override void OnAppearing()
{
base.OnAppearing();
}
public async Task NavigateFromMenu(int id)
{
if (!MenuPages.ContainsKey(id))
......@@ -48,4 +53,9 @@ namespace LocalNetwork.Views
}
}
}
public static class MediaExtension
{
public static string NetworkName(this Media media) => media.Meta(MetadataType.Title);
}
}
\ No newline at end of file
......@@ -17,11 +17,11 @@ namespace LocalNetwork.Views
{
InitializeComponent();
Item = new Item
{
Text = "Item name",
Description = "This is an item description."
};
//Item = new Item
//{
// //Text = "Item name",
// //Description = "This is an item description."
//};
BindingContext = this;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment