From 6a92a6a4d27dc07f8b32bd7d57ffbcbe15630ab9 Mon Sep 17 00:00:00 2001
From: Vitaly Takmazov
Date: Sun, 12 Feb 2012 01:53:36 +0400
Subject: Avatars support + broken clickable urls
---
Juick/App.xaml.cs | 6 +++
Juick/Classes/RichTextConverter.cs | 58 +++++++++++++++++++++++++++
Juick/Juick.csproj | 2 +-
Juick/MainPage.xaml | 58 ++++++++++++++++++---------
Juick/MainPage.xaml.cs | 44 +++++++++++++++++++--
Juick/ThreadView.xaml | 23 +++++++----
Juick/ViewModels/MainViewModel.cs | 76 ++++++++++++++++++++++++++++--------
Juick/ViewModels/MessageViewModel.cs | 8 ++--
Juick/ViewModels/ThreadViewModel.cs | 19 ++++++++-
9 files changed, 242 insertions(+), 52 deletions(-)
create mode 100644 Juick/Classes/RichTextConverter.cs
(limited to 'Juick')
diff --git a/Juick/App.xaml.cs b/Juick/App.xaml.cs
index 54abe20..b73398c 100644
--- a/Juick/App.xaml.cs
+++ b/Juick/App.xaml.cs
@@ -39,6 +39,12 @@ namespace Juick
get { return _cl ?? (_cl = new RestClient("http://api.juick.com") {UserAgent = "Juick 0.999/Windows Phone " + Environment.OSVersion.Version}); }
}
+ private static RestClient _acl;
+ public static RestClient AvatarClient
+ {
+ get { return _acl ?? (_acl = new RestClient("http://i.juick.com") { UserAgent = "Juick 0.999/Windows Phone " + Environment.OSVersion.Version }); }
+ }
+
///
/// Provides easy access to the root frame of the Phone Application.
///
diff --git a/Juick/Classes/RichTextConverter.cs b/Juick/Classes/RichTextConverter.cs
new file mode 100644
index 0000000..ee6ffa7
--- /dev/null
+++ b/Juick/Classes/RichTextConverter.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+using Microsoft.Phone.Tasks;
+
+namespace Juick.Classes
+{
+ public class RichTextConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ var message = value as string;
+ var runs = new List();
+
+ foreach (var word in message.Split(new char[] {' ', '\n'}))
+ {
+ Uri uri;
+
+ if (Uri.TryCreate(word, UriKind.Absolute, out uri) ||
+ (word.StartsWith("www.") && Uri.TryCreate("http://" + word, UriKind.Absolute, out uri)))
+ {
+ var link = new Hyperlink();
+ link.Inlines.Add(new Run() { Text = word });
+ link.Click += (sender, e) =>
+ {
+ var hyperLink = (sender as Hyperlink);
+ new WebBrowserTask() { Uri = uri }.Show();
+ };
+
+ runs.Add(link);
+ }
+ else
+ {
+ runs.Add(new Run() { Text = word });
+ }
+
+ runs.Add(new Run() { Text = " " });
+ }
+
+ return runs;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return value;
+ }
+ }
+}
diff --git a/Juick/Juick.csproj b/Juick/Juick.csproj
index e550947..73d65c1 100644
--- a/Juick/Juick.csproj
+++ b/Juick/Juick.csproj
@@ -71,6 +71,7 @@
App.xaml
+
LoginView.xaml
@@ -125,7 +126,6 @@
PreserveNewest
-
diff --git a/Juick/MainPage.xaml b/Juick/MainPage.xaml
index 3d7245c..84e7bd7 100644
--- a/Juick/MainPage.xaml
+++ b/Juick/MainPage.xaml
@@ -6,14 +6,19 @@
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="728"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:bindings="clr-namespace:Juick.Classes"
+ xmlns:Juick="clr-namespace:Juick" mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="728"
d:DataContext="{d:DesignData SampleData/MainViewModelSampleData.xaml}"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="False">
+
+
+
+
+
@@ -26,10 +31,15 @@
+
+
+
-
-
+
+
@@ -39,24 +49,28 @@
-
+
-
+
-
-
+
+
@@ -64,8 +78,14 @@
+
+
+
+
@@ -76,26 +96,26 @@
-
-
+
-
-
-
+
@@ -104,14 +124,14 @@
-
-
-
+
+
+
-
-
-
+
+
+
diff --git a/Juick/MainPage.xaml.cs b/Juick/MainPage.xaml.cs
index 4468f6a..1654c1b 100644
--- a/Juick/MainPage.xaml.cs
+++ b/Juick/MainPage.xaml.cs
@@ -64,19 +64,57 @@ namespace Juick
((ListBox)sender).SelectedIndex = -1;
}
- private void ApplicationBarIconButton_Click(object sender, EventArgs e)
+ public static string GetInlineList(TextBlock element)
+ {
+ if (element != null)
+ return element.GetValue(InlineList) as string;
+ return string.Empty;
+ }
+
+ public static void SetInlineList(TextBlock element, string value)
+ {
+ if (element != null)
+ element.SetValue(InlineList, value);
+ }
+
+ public static readonly DependencyProperty InlineList =
+ DependencyProperty.RegisterAttached(
+ "InlineList",
+ typeof(List),
+ typeof(MainPage),
+ new PropertyMetadata(null, OnInlineListPropertyChanged));
+
+ private static void OnInlineListPropertyChanged(DependencyObject obj,
+ DependencyPropertyChangedEventArgs e)
+ {
+ var tb = obj as TextBlock;
+ if (tb != null)
+ {
+ // clear previous inlines
+ tb.Inlines.Clear();
+
+ // add new inlines
+ var inlines = e.NewValue as List;
+ if (inlines != null)
+ {
+ inlines.ForEach(inl => tb.Inlines.Add((inl)));
+ }
+ }
+ }
+
+ private void ApplicationBarIconButtonClick(object sender, EventArgs e)
{
App.ViewModel.MyFeed.Clear();
App.ViewModel.Last.Clear();
App.ViewModel.LoadData();
}
- private void ApplicationBarMenuItem_Click(object sender, EventArgs e)
+ private void ApplicationBarMenuItemClick(object sender, EventArgs e)
{
App.Account.SignOut(this);
}
- private void ApplicationBarIconButton_Click_1(object sender, EventArgs e)
+ private void ApplicationBarIconButtonClick1(object sender, EventArgs e)
{
NavigationService.Navigate(new Uri("/NewPostView.xaml", UriKind.Relative));
}
diff --git a/Juick/ThreadView.xaml b/Juick/ThreadView.xaml
index 20529c2..2decd6e 100644
--- a/Juick/ThreadView.xaml
+++ b/Juick/ThreadView.xaml
@@ -28,9 +28,15 @@
+
+
+
-
+
+
@@ -40,20 +46,21 @@
-
+
+
-
+
+ TextWrapping="Wrap" />
-
+
diff --git a/Juick/ViewModels/MainViewModel.cs b/Juick/ViewModels/MainViewModel.cs
index a504658..23ff020 100644
--- a/Juick/ViewModels/MainViewModel.cs
+++ b/Juick/ViewModels/MainViewModel.cs
@@ -2,10 +2,13 @@
using System.ComponentModel;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
using System.Net;
using System.Runtime.Serialization.Json;
using System.Collections.ObjectModel;
using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media.Imaging;
using Juick.Api;
using RestSharp;
@@ -52,16 +55,36 @@ namespace Juick.ViewModels
var ser = new DataContractJsonSerializer(typeof (List));
var messages =
- (List)ser.ReadObject(new MemoryStream(response.RawBytes));
+ ser.ReadObject(new MemoryStream(response.RawBytes)) as List;
MyFeed.Clear();
- messages.ForEach(post => MyFeed.Add(new MessageViewModel(post)
- {
- Status =
- string.Format(
- "Posted on: {0}, replies: {1}",
- post.timestamp,
- post.replies)
- }));
+ messages.ForEach(post =>
+ {
+ var item = new MessageViewModel(post)
+ {
+ Status =
+ string.Format(
+ "Posted on: {0}, replies: {1}",
+ post.
+ timestamp,
+ post.
+ replies)
+ };
+ MyFeed.Add(item);
+ var imageRequest =
+ new RestRequest(
+ string.Format("/as/{0}.png",
+ post.user.uid));
+ App.AvatarClient.ExecuteAsync(
+ imageRequest, restResponse =>
+ {
+ item.UserAvatar = new BitmapImage
+ ();
+ item.UserAvatar.SetSource(new MemoryStream(restResponse.RawBytes));
+ item.
+ NotifyPropertyChanged
+ ("UserAvatar");
+ });
+ });
NotifyPropertyChanged("MyFeed");
});
@@ -75,13 +98,34 @@ namespace Juick.ViewModels
(List)ser.ReadObject(ms);
if (messages == null) return;
Last.Clear();
- messages.ForEach(post => Last.Add(new MessageViewModel(post)
+ messages.ForEach(post =>
{
- Status = string.Format(
- "Posted on: {0}, replies: {1}",
- post.timestamp, post.replies
- )
- }));
+ var item = new MessageViewModel(post)
+ {
+ Status =
+ string.Format(
+ "Posted on: {0}, replies: {1}",
+ post.
+ timestamp,
+ post.
+ replies)
+ };
+ Last.Add(item);
+ var imageRequest =
+ new RestRequest(
+ string.Format("/as/{0}.png",
+ post.user.uid));
+ App.AvatarClient.ExecuteAsync(
+ imageRequest, restResponse =>
+ {
+ item.UserAvatar = new BitmapImage
+ ();
+ item.UserAvatar.SetSource(new MemoryStream(restResponse.RawBytes));
+ item.
+ NotifyPropertyChanged
+ ("UserAvatar");
+ });
+ });
NotifyPropertyChanged("Last");
}
});
@@ -89,7 +133,7 @@ namespace Juick.ViewModels
public event PropertyChangedEventHandler PropertyChanged;
- private void NotifyPropertyChanged(String propertyName)
+ public void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
diff --git a/Juick/ViewModels/MessageViewModel.cs b/Juick/ViewModels/MessageViewModel.cs
index 32da0aa..8620ab3 100644
--- a/Juick/ViewModels/MessageViewModel.cs
+++ b/Juick/ViewModels/MessageViewModel.cs
@@ -9,6 +9,7 @@ using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
+using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Juick.Api;
@@ -90,8 +91,8 @@ namespace Juick
}
}
- private Image _avatar;
- public Image UserAvatar
+ private BitmapImage _avatar;
+ public BitmapImage UserAvatar
{
get { return _avatar; }
set
@@ -147,7 +148,8 @@ namespace Juick
}
public event PropertyChangedEventHandler PropertyChanged;
- private void NotifyPropertyChanged(String propertyName)
+
+ public void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
diff --git a/Juick/ViewModels/ThreadViewModel.cs b/Juick/ViewModels/ThreadViewModel.cs
index 48ebe65..bff72b7 100644
--- a/Juick/ViewModels/ThreadViewModel.cs
+++ b/Juick/ViewModels/ThreadViewModel.cs
@@ -6,6 +6,7 @@ using System.IO;
using System.Net;
using System.Net.Browser;
using System.Runtime.Serialization.Json;
+using System.Windows.Media.Imaging;
using Juick.Api;
using RestSharp;
@@ -48,8 +49,22 @@ namespace Juick.ViewModels
Items.Clear();
messages.ForEach(post =>
{
- this.Items.Add(
- new MessageViewModel(post));
+ var item = new MessageViewModel(post);
+ Items.Add(item);
+ var imageRequest =
+ new RestRequest(
+ string.Format("/as/{0}.png",
+ post.user.uid));
+ App.AvatarClient.ExecuteAsync(
+ imageRequest, restResponse =>
+ {
+ item.UserAvatar = new BitmapImage
+ ();
+ item.UserAvatar.SetSource(new MemoryStream(restResponse.RawBytes));
+ item.
+ NotifyPropertyChanged
+ ("UserAvatar");
+ });
});
IsDataLoaded = true;
NotifyPropertyChanged("Items");
--
cgit v1.2.3