Skip to content

Adding Uno support (updated) #38

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 23 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -348,3 +348,4 @@ MigrationBackup/

# Ionide (cross platform F# VS Code tools) working folder
.ionide/
*.editorconfig
31 changes: 31 additions & 0 deletions samples/MvvmSample.Core/Helpers/MarkdownHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace MvvmSample.Helpers
{
/// <summary>
/// A simple class to help with basic operations on markdown documents.
/// </summary>
public static class MarkdownHelper
{
/// <summary>
/// Gets all the paragraphs in a given markdown document.
/// </summary>
/// <param name="text">The input markdown document.</param>
/// <returns>The raw paragraphs from <paramref name="text"/>.</returns>
public static IReadOnlyDictionary<string, string> GetParagraphs(string text)
{
return
Regex.Matches(text, @"(#+ ([^\n]+)[^#]+)", RegexOptions.Singleline)
.OfType<Match>()
.ToDictionary(
m => m.Groups[2].Value.Trim().Replace("&lt;", "<"),
m => m.Groups[1].Value.Trim().Replace("&lt;", "<").Replace("[!WARNING]", "**WARNING:**"));
}
}
}
78 changes: 78 additions & 0 deletions samples/MvvmSample.Core/Models/Post.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;

namespace MvvmSample.Models
{
/// <summary>
/// A class for a query for posts in a given subreddit.
/// </summary>
public class PostsQueryResponse
{
/// <summary>
/// Gets or sets the listing data for the response.
/// </summary>
[JsonProperty("data")]
public PostListing Data { get; set; }
}

/// <summary>
/// A class for a Reddit listing of posts.
/// </summary>
public class PostListing
{
/// <summary>
/// Gets or sets the items in this listing.
/// </summary>
[JsonProperty("children")]
public IList<PostData> Items { get; set; }
}

/// <summary>
/// A wrapping class for a post.
/// </summary>
public class PostData
{
/// <summary>
/// Gets or sets the <see cref="Post"/> instance.
/// </summary>
[JsonProperty("data")]
public Post Data { get; set; }
}

/// <summary>
/// A simple model for a Reddit post.
/// </summary>
public class Post
{
/// <summary>
/// Gets or sets the title of the post.
/// </summary>
[JsonProperty("title")]
public string Title { get; set; }

/// <summary>
/// Gets or sets the URL to the post thumbnail, if present.
/// </summary>
[JsonProperty("thumbnail")]
public string Thumbnail { get; set; }

/// <summary>
/// Gets the text of the post.
/// </summary>
/// <remarks>
/// Here we're just hardcoding some sample text to simplify how posts are displayed.
/// Normally, not all posts have a self text post available.
/// </remarks>
[JsonIgnore]
public string SelfText { get; } = string.Join(" ", Enumerable.Repeat(
@"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", 20));
}
}
13 changes: 13 additions & 0 deletions samples/MvvmSample.Core/MvvmSample.Core.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="MSBuild.Sdk.Extras">

<PropertyGroup>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
<LangVersion>8.0</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Toolkit.Mvvm" Version="7.0.0-preview4" />
<PackageReference Include="Nito.AsyncEx.Coordination" Version="5.1.0" />
<PackageReference Include="Refit" Version="5.2.4" />
<PackageReference Include="Uno.UI" Version="3.4.0" />
</ItemGroup>
</Project>
27 changes: 27 additions & 0 deletions samples/MvvmSample.Core/Services/IFileService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.IO;
using System.Threading.Tasks;

namespace MvvmSample.Services
{
/// <summary>
/// The default <see langword="interface"/> for a service that handles files.
/// </summary>
public interface IFilesService
{
/// <summary>
/// Gets the path of the installation directory.
/// </summary>
string InstallationPath { get; }

/// <summary>
/// Gets a readonly <see cref="Stream"/> for a file at a specified path.
/// </summary>
/// <param name="path">The path of the file to retrieve.</param>
/// <returns>The <see cref="Stream"/> for the specified file.</returns>
Task<Stream> OpenForReadAsync(string path);
}
}
23 changes: 23 additions & 0 deletions samples/MvvmSample.Core/Services/IRedditService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Threading.Tasks;
using MvvmSample.Models;
using Refit;

namespace MvvmSample.Services
{
/// <summary>
/// An interface for a simple Reddit service.
/// </summary>
public interface IRedditService
{
/// <summary>
/// Get a list of posts from a given subreddit
/// </summary>
/// <param name="subreddit">The subreddit name.</param>
[Get("/r/{subreddit}/.json")]
Task<PostsQueryResponse> GetSubredditPostsAsync(string subreddit);
}
}
31 changes: 31 additions & 0 deletions samples/MvvmSample.Core/Services/ISettingsService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Diagnostics.Contracts;

namespace MvvmSample.Services
{
/// <summary>
/// The default <see langword="interface"/> for the settings manager used in the app.
/// </summary>
public interface ISettingsService
{
/// <summary>
/// Assigns a value to a settings key.
/// </summary>
/// <typeparam name="T">The type of the object bound to the key.</typeparam>
/// <param name="key">The key to check.</param>
/// <param name="value">The value to assign to the setting key.</param>
void SetValue<T>(string key, T value);

/// <summary>
/// Reads a value from the current <see cref="IServiceProvider"/> instance and returns its casting in the right type.
/// </summary>
/// <typeparam name="T">The type of the object to retrieve.</typeparam>
/// <param name="key">The key associated to the requested object.</param>
[Pure]
T GetValue<T>(string key);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Threading.Tasks;
using Microsoft.Toolkit.Mvvm.Input;

namespace MvvmSample.ViewModels
{
public class AsyncRelayCommandPageViewModel : SamplePageViewModel
{
public AsyncRelayCommandPageViewModel()
{
DownloadTextCommand = new AsyncRelayCommand(DownloadTextAsync);
}

public IAsyncRelayCommand DownloadTextCommand { get; }

private async Task<string> DownloadTextAsync()
{
await Task.Delay(3000); // Simulate a web request

return "Hello world!";
}
}
}
10 changes: 10 additions & 0 deletions samples/MvvmSample.Core/ViewModels/IocPageViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

namespace MvvmSample.ViewModels
{
public class IocPageViewModel : SamplePageViewModel
{
}
}
89 changes: 89 additions & 0 deletions samples/MvvmSample.Core/ViewModels/MessengerPageViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Microsoft.Toolkit.Mvvm.ComponentModel;
using Microsoft.Toolkit.Mvvm.Messaging;
using Microsoft.Toolkit.Mvvm.Messaging.Messages;

namespace MvvmSample.ViewModels
{
public class MessengerPageViewModel : SamplePageViewModel
{
public UserSenderViewModel SenderViewModel { get; } = new UserSenderViewModel();

public UserReceiverViewModel ReceiverViewModel { get; } = new UserReceiverViewModel();

// Simple viewmodel for a module sending a username message
public class UserSenderViewModel : ObservableRecipient
{
private string username = "Bob";

public string Username
{
get => username;
private set => SetProperty(ref username, value);
}

protected override void OnActivated()
{
Messenger.Register<CurrentUsernameRequestMessage>(this, (r, m) => m.Reply(Username));
}

public void SendUserMessage()
{
Username = Username == "Bob" ? "Alice" : "Bob";

Messenger.Send(new UsernameChangedMessage(Username));
}
}

// Simple viewmodel for a module receiving a username message
public class UserReceiverViewModel : ObservableRecipient
{
private string username = "";

public string Username
{
get => username;
private set => SetProperty(ref username, value);
}

protected override void OnActivated()
{
Messenger.Register<UsernameChangedMessage>(this, (r, m) => Username = m.Value);
}
}

private string username;

public string Username
{
get => username;
private set => SetProperty(ref username, value);
}

public void RequestCurrentUsername()
{
Username = WeakReferenceMessenger.Default.Send<CurrentUsernameRequestMessage>();
}

public void ResetCurrentUsername()
{
Username = null;
}

// A sample message with a username value
public sealed class UsernameChangedMessage : ValueChangedMessage<string>
{
public UsernameChangedMessage(string value) : base(value)
{
}
}

// A sample request message to get the current username
public sealed class CurrentUsernameRequestMessage : RequestMessage<string>
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Threading.Tasks;

namespace MvvmSample.ViewModels
{
public class ObservableObjectPageViewModel : SamplePageViewModel
{
private string name;

/// <summary>
/// Gets or sets the name to display.
/// </summary>
public string Name
{
get => name;
set => SetProperty(ref name, value);
}

private TaskNotifier myTask;

/// <summary>
/// Gets or sets the name to display.
/// </summary>
public Task MyTask
{
get => myTask;
private set => SetPropertyAndNotifyOnCompletion(ref myTask, value);
}

/// <summary>
/// Simulates an asynchronous method.
/// </summary>
public void ReloadTask()
{
MyTask = Task.Delay(3000);
}
}
}
Loading