Skip to content

Instantly share code, notes, and snippets.

@ryanvalentin
Created June 12, 2013 18:26
Show Gist options
  • Save ryanvalentin/5767814 to your computer and use it in GitHub Desktop.
Save ryanvalentin/5767814 to your computer and use it in GitHub Desktop.
Windows Phone Disqus Embed
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