Created
June 12, 2013 18:26
-
-
Save ryanvalentin/5767814 to your computer and use it in GitHub Desktop.
Windows Phone Disqus Embed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Net; | |
using System.Windows; | |
using System.Windows.Controls; | |
using System.Windows.Documents; | |
using System.Windows.Input; | |
using System.Windows.Media; | |
using System.Windows.Media.Animation; | |
using System.Windows.Shapes; | |
using Microsoft.Phone.Controls; | |
using Microsoft.Phone.Shell; | |
using Newtonsoft.Json; // JSON.NET library http://james.newtonking.com/projects/json-net.aspx | |
using Newtonsoft.Json.Linq; // JSON.NET library | |
using System.IO.IsolatedStorage; // added default reference to save preferences to Isolated Storage Settings | |
namespace Disqus_Demo | |
{ | |
public partial class MainPage : PhoneApplicationPage | |
{ | |
public MainPage() | |
{ | |
InitializeComponent(); | |
this.Loaded += new RoutedEventHandler(MainPage_Loaded); | |
} | |
// Main page loaded, so we start downloading the comments | |
private void MainPage_Loaded(object sender, RoutedEventArgs e) | |
{ | |
/*** Set variables to pass to the DownloadComments function ***/ | |
string cursor = ""; // pass an empty cursor for the initial loading of comments | |
// Determine from IsolatedStorageSettings what the preferred sort order is | |
var settings = IsolatedStorageSettings.ApplicationSettings; | |
if (settings.Contains("PreferredSortOrder")) | |
{ | |
string order = (string)settings["PreferredSortOrder"]; | |
DownloadComments(cursor, order); | |
} | |
// Or else just use descending as the default | |
else | |
{ | |
string order = "desc"; | |
DownloadComments(cursor, order); | |
} | |
} | |
/********************* | |
* Methods | |
* *******************/ | |
// Create web client to get the comments for a thread | |
public void DownloadComments(string cursor, string order) | |
{ | |
progressBar1.Visibility = Visibility.Visible; // Show the progress bar | |
// Set API variables. You can pull these from any source appropriate for your app | |
var PublicKey = "YOUR PUBLIC API KEY"; // Application public key - register for one here: http://disqus.com/api/applications/ | |
var SecretKey = "YOUR SECRET API KEY"; // Application secret key | |
var Thread = "867059716"; // Disqus thread ID. You can also use your custom identifier or URL using "ident:your_custom_identifier" or "link:http://example.com/your-post/", respectively | |
var Forum = "example"; // Change "example" to your own shortname | |
var Limit = "15"; // Get 15 comments from this thread at a time, I found this is the optimal number for speed of downloading. Max is 100 | |
var Include = "approved"; | |
var AccessToken = "OAUTH ACCESS TOKEN"; // Enter your administrator access token or get one from the user: http://disqus.com/api/docs/auth/ | |
// Call the posts/list endpoint documented here: http://disqus.com/api/docs/posts/list/ | |
Uri postsListUri = new Uri(("https://disqus.com/api/3.0/posts/list.json?api_key=" + PublicKey | |
+ "&api_secret=" + SecretKey | |
+ "&thread=" + Thread | |
+ "&forum=" + Forum | |
+ "&limit=" + Limit | |
+ "&include=" + Include | |
+ "&order=" + order | |
+ "&cursor=" + cursor | |
+ "&access_token=" + AccessToken)); | |
WebClient postsListData = new WebClient(); | |
postsListData.Headers[HttpRequestHeader.Referer] = "http://disqus.com/"; // API call will fail if you don't change the referrer: http://stackoverflow.com/questions/7216738/your-api-key-is-not-valid-on-this-domain-when-calling-disqus-from-wp7 | |
postsListData.DownloadStringCompleted += new DownloadStringCompletedEventHandler(DownloadComments_Completed); // Download completed event handler | |
postsListData.DownloadStringAsync(postsListUri); | |
} | |
// Comment download is finished, now we parse it | |
private void DownloadComments_Completed(object sender, DownloadStringCompletedEventArgs e) | |
{ | |
// Parse the JSON Response | |
JObject resultObject = JObject.Parse(e.Result); | |
// Get comment data from XML file | |
var commentsdata = from comment in resultObject["response"].Children() | |
select new Comment | |
{ | |
CommenterAvatar = (string)comment["author"]["avatar"]["small"]["permalink"], | |
CommenterName = (string)comment["author"]["name"], | |
CommentTimestamp = (DateTime)comment["createdAt"], | |
SingleComment = (string)comment["raw_message"], | |
}; | |
// Bind data to our listbox | |
listBoxComments.ItemsSource = commentsdata; | |
// Count the listbox and if there are no comments, show placeholder | |
int checkForComments = listBoxComments.Items.Count; | |
if (checkForComments == 0) | |
{ | |
noCommentsTextBlock.Visibility = Visibility.Visible; | |
} | |
/*** Get Thread ID ***/ | |
//We must get the ID because the posts/create API endpoint won't accept identifiers or URLs to post a comment | |
string ThreadId = (string)resultObject.SelectToken("response[0].id"); | |
ApplicationTitle.Tag = ThreadId; // Store this in the ApplicationTitle tag so we can reference it later | |
/*** Pagination using cursors ***/ | |
// Check the cursor to see if there are more comments, and add the cursor to the button + enable it if so | |
bool HasNext = (bool)resultObject["cursor"]["hasNext"]; | |
bool HasPrev = (bool)resultObject["cursor"]["hasPrev"]; | |
if (HasNext == true) | |
{ | |
string NextCursor = (string)resultObject["cursor"]["next"]; | |
nextCommentsButton.Tag = NextCursor; | |
nextCommentsButton.IsEnabled = true; | |
} | |
if (HasPrev == true) | |
{ | |
string PrevCursor = (string)resultObject["cursor"]["prev"]; | |
prevCommentsButton.Tag = PrevCursor; | |
prevCommentsButton.IsEnabled = true; | |
} | |
// Show pagination buttons | |
nextCommentsButton.Visibility = Visibility.Visible; | |
prevCommentsButton.Visibility = Visibility.Visible; | |
// Create app bar now because we don't want user commenting until we've stored a thread ID | |
CreateAppBar(); | |
// Turn off progress bar | |
progressBar1.Visibility = Visibility.Collapsed; // Hide the progress bar | |
} | |
public void CreateAppBar() | |
{ | |
// Appbar: Initialize Dynamic application bar | |
ApplicationBar = new ApplicationBar(); | |
ApplicationBar.IsVisible = true; | |
// Appbar: Add comment button [0] | |
ApplicationBarIconButton buttonComments = new ApplicationBarIconButton(); | |
buttonComments.IconUri = new Uri("/assets/icons/appbar.feature.addcomment.png", UriKind.Relative); | |
buttonComments.Text = "comment"; | |
ApplicationBar.Buttons.Add(buttonComments); | |
buttonComments.IsEnabled = true; | |
buttonComments.Click += new EventHandler(addCommentButton_Click); | |
// Determine from IsolatedStorageSettings what the preferred sort order is | |
var settings = IsolatedStorageSettings.ApplicationSettings; | |
if (settings.Contains("PreferredSortOrder")) | |
{ | |
string order = (string)settings["PreferredSortOrder"]; | |
if (order == "desc") // Order is descending, so we make the button the opposite "sort by oldest" | |
{ | |
// Appbar: Create sorting menu item [0] | |
ApplicationBarMenuItem menuItem0 = new ApplicationBarMenuItem(); | |
menuItem0.Text = "sort by oldest"; | |
ApplicationBar.MenuItems.Add(menuItem0); | |
menuItem0.Click += new EventHandler(sortByOldestButton_Click); | |
} | |
else // Or else we assume it's ascending, so we show "sort by newest" | |
{ | |
// Appbar: Create sorting menu item [0] | |
ApplicationBarMenuItem menuItem0 = new ApplicationBarMenuItem(); | |
menuItem0.Text = "sort by newest"; | |
ApplicationBar.MenuItems.Add(menuItem0); | |
menuItem0.Click += new EventHandler(sortByNewestButton_Click); | |
} | |
} | |
else // No setting is stored, so we assume the default "desc" and show "sort by oldest" in the appbar | |
{ | |
// Appbar: Create sorting menu item [0] | |
ApplicationBarMenuItem menuItem0 = new ApplicationBarMenuItem(); | |
menuItem0.Text = "sort by oldest"; | |
ApplicationBar.MenuItems.Add(menuItem0); | |
menuItem0.Click += new EventHandler(sortByOldestButton_Click); | |
} | |
// Appbar: Create refresh menu item [1] | |
ApplicationBarMenuItem menuItem1 = new ApplicationBarMenuItem(); | |
menuItem1.Text = "refresh"; | |
ApplicationBar.MenuItems.Add(menuItem1); | |
menuItem1.Click += new EventHandler(refreshButton_Click); | |
} | |
/********************* | |
* Click Events | |
* *******************/ | |
// When clicking next or previous buttons for comment pagination | |
private void nextCommentsButton_Click(object sender, RoutedEventArgs e) | |
{ | |
// Scroll to top of page | |
MainPageScrollViewer.ScrollToVerticalOffset(0); | |
// disable pagination buttons so user can't overload the app | |
nextCommentsButton.IsEnabled = false; | |
prevCommentsButton.IsEnabled = false; | |
// get cursor from button tag | |
string cursor = (string)nextCommentsButton.Tag; | |
// Determine preferred sorting order and download comments again | |
var settings = IsolatedStorageSettings.ApplicationSettings; | |
if (settings.Contains("PreferredSortOrder")) | |
{ | |
string order = (string)settings["PreferredSortOrder"]; | |
DownloadComments(cursor, order); | |
} | |
// Or else just use descending as the default | |
else | |
{ | |
string order = "desc"; | |
DownloadComments(cursor, order); | |
} | |
} | |
private void prevCommentsButton_Click(object sender, RoutedEventArgs e) | |
{ | |
// Scroll to top of page | |
MainPageScrollViewer.ScrollToVerticalOffset(0); | |
// disable pagination buttons so user can't overload the app | |
prevCommentsButton.IsEnabled = false; | |
nextCommentsButton.IsEnabled = false; | |
// get cursor from button tag | |
string cursor = (string)prevCommentsButton.Tag; | |
// Determine preferred sorting order and download comments again | |
var settings = IsolatedStorageSettings.ApplicationSettings; | |
if (settings.Contains("PreferredSortOrder")) | |
{ | |
string order = (string)settings["PreferredSortOrder"]; | |
DownloadComments(cursor, order); | |
} | |
// Or else just use descending as the default | |
else | |
{ | |
string order = "desc"; | |
DownloadComments(cursor, order); | |
} | |
} | |
// Appbar: When clicking add a comment | |
private void addCommentButton_Click(object sender, EventArgs e) | |
{ | |
// Navigate to PostComment.xaml and pass thread ID, page thread title, parent post | |
string ThreadId = (string)ApplicationTitle.Tag; | |
string Parent = ""; // Set to nothing because we assume when pressing this button it's going to be a parent comment | |
string ThreadTitle = ApplicationTitle.Text; | |
string CommentsPageUrl = "/PostComment.xaml"; | |
CommentsPageUrl += string.Format("?title=" + ThreadTitle + "&thread=" + ThreadId + "&parent=" + Parent); | |
NavigationService.Navigate(new Uri(CommentsPageUrl, UriKind.Relative)); | |
} | |
// Appbar: When clicking refresh | |
private void refreshButton_Click(object sender, EventArgs e) | |
{ | |
// Scroll to top of page | |
MainPageScrollViewer.ScrollToVerticalOffset(0); | |
// Change the appbar text to sort by oldest | |
var sortbutton = (ApplicationBarMenuItem)ApplicationBar.MenuItems[0]; | |
sortbutton.Text = "sort by oldest"; | |
sortbutton.Click += new EventHandler(sortByOldestButton_Click); | |
// Set cursor to nothing and order to "desc", because it's assumed the user wants the latest comments when refreshing | |
string cursor = ""; | |
string order = "desc"; | |
DownloadComments(cursor, order); | |
} | |
// Appbar: When clicking sort by oldest | |
private void sortByOldestButton_Click(object sender, EventArgs e) | |
{ | |
// Scroll to top of page | |
MainPageScrollViewer.ScrollToVerticalOffset(0); | |
// Store the last sorting order used in isolated settings | |
//This is probably better made an option in the settings page | |
var settings = IsolatedStorageSettings.ApplicationSettings; | |
if (settings.Contains("PreferredSortOrder")) // If this was already set in Isolated Settings, replace the value | |
{ | |
settings["PreferredSortOrder"] = "asc"; | |
} | |
else // No settings exist, so we use the settings.Add method instead | |
{ | |
settings.Add("PreferredSortOrder", "asc"); | |
} | |
// Now we change the appbar text/event handler | |
var sortbutton = (ApplicationBarMenuItem)ApplicationBar.MenuItems[0]; | |
sortbutton.Text = "sort by newest"; | |
sortbutton.Click += new EventHandler(sortByNewestButton_Click); | |
// Set DownloadComments arguments | |
string cursor = ""; // Set to nothing because you don't want to keep your page when changing the sorting order | |
string order = "asc"; | |
// Download the comments with our new sorting order | |
DownloadComments(cursor, order); | |
} | |
// Appbar: When clicking sort by newest | |
private void sortByNewestButton_Click(object sender, EventArgs e) | |
{ | |
// Scroll to top of page | |
MainPageScrollViewer.ScrollToVerticalOffset(0); | |
// Store the last sorting order used in isolated settings | |
//This is probably better made an option in the settings page | |
var settings = IsolatedStorageSettings.ApplicationSettings; | |
if (settings.Contains("PreferredSortOrder")) // If this was already set in Isolated Settings, replace the value | |
{ | |
settings["PreferredSortOrder"] = "desc"; | |
} | |
else // No settings exist, so we use the settings.Add method instead | |
{ | |
settings.Add("PreferredSortOrder", "desc"); | |
} | |
// Now we change the appbar text/event handler | |
var sortbutton = (ApplicationBarMenuItem)ApplicationBar.MenuItems[0]; | |
sortbutton.Text = "sort by oldest"; | |
sortbutton.Click += new EventHandler(sortByOldestButton_Click); | |
// Set DownloadComments arguments | |
string cursor = ""; // Set to nothing because you don't want to keep your page when changing the sorting order | |
string order = "desc"; | |
// Download the comments with our new sorting order | |
DownloadComments(cursor, order); | |
} | |
/********************* | |
* Classes | |
* *******************/ | |
public class Comment | |
{ | |
string commenteravatar; | |
string commentername; | |
DateTime commenttimestamp; | |
string singlecomment; | |
public string CommenterAvatar | |
{ | |
get { return commenteravatar; } | |
set { commenteravatar = value; } | |
} | |
public string CommenterName | |
{ | |
get { return commentername; } | |
set { commentername = value; } | |
} | |
public DateTime CommentTimestamp | |
{ | |
get { return commenttimestamp; } | |
set { commenttimestamp = value; } | |
} | |
public string SingleComment | |
{ | |
get { return singlecomment; } | |
set | |
{ | |
// Truncates the characters in comment to 250 (user can click comment for more) | |
var maxLength = 250; | |
singlecomment = value; | |
if (singlecomment.Length > maxLength) | |
{ | |
singlecomment = value.Substring(0, maxLength); | |
singlecomment += "... (more)"; | |
} | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment