1
0
mirror of https://git.teknik.io/Teknikode/Teknik.git synced 2023-08-02 14:16:22 +02:00

Initial Podcast creation.

Renamed some Blog objects
This commit is contained in:
Uncled1023 2016-01-24 22:31:01 -08:00
parent acea8eb87b
commit c48bfc3be9
38 changed files with 4648 additions and 69 deletions

View File

@ -43,7 +43,7 @@ namespace Teknik.Areas.Blog
"~/Scripts/ocupload/1.1.2/ocupload.js",
"~/Scripts/PageDown/Markdown.Converter.js",
"~/Scripts/PageDown/Markdown.Sanitizer.js",
"~/Scripts/bootstrap/markdown/bootstrap-markdown.js",
"~/Scripts/bootstrap-markdown.js",
"~/Scripts/bootbox/bootbox.min.js",
"~/Areas/Blog/Scripts/Blog.js"));
// Register Style Bundles

View File

@ -28,8 +28,8 @@ namespace Teknik.Areas.Blog.Controllers
if (string.IsNullOrEmpty(username))
{
ViewBag.Title = "Teknik Blog - " + Config.Title;
var foundPosts = (User.IsInRole("Admin")) ? db.Posts.Include("Blog").Include("Blog.User").Where(p => (p.System))
: db.Posts.Include("Blog").Include("Blog.User").Where(p => (p.System && p.Published));
var foundPosts = (User.IsInRole("Admin")) ? db.BlogPosts.Include("Blog").Include("Blog.User").Where(p => (p.System))
: db.BlogPosts.Include("Blog").Include("Blog.User").Where(p => (p.System && p.Published));
model = new BlogViewModel();
model.BlogId = Constants.SERVERBLOGID;
@ -54,8 +54,8 @@ namespace Teknik.Areas.Blog.Controllers
// find the blog specified
if (blog != null)
{
var foundPosts = (User.IsInRole("Admin")) ? db.Posts.Include("Blog").Include("Blog.User").Where(p => (p.BlogId == blog.BlogId && !p.System))
: db.Posts.Include("Blog").Include("Blog.User").Where(p => (p.BlogId == blog.BlogId && !p.System) &&
var foundPosts = (User.IsInRole("Admin")) ? db.BlogPosts.Include("Blog").Include("Blog.User").Where(p => (p.BlogId == blog.BlogId && !p.System))
: db.BlogPosts.Include("Blog").Include("Blog.User").Where(p => (p.BlogId == blog.BlogId && !p.System) &&
(p.Published || p.Blog.User.Username == User.Identity.Name));
model = new BlogViewModel();
model.BlogId = blog.BlogId;
@ -82,8 +82,8 @@ namespace Teknik.Areas.Blog.Controllers
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
// find the post specified
var posts = (User.IsInRole("Admin")) ? db.Posts.Include("Blog").Include("Blog.User").Where(p => (p.Blog.User.Username == username && p.PostId == id))
: db.Posts.Include("Blog").Include("Blog.User").Where(p => (p.Blog.User.Username == username && p.PostId == id) &&
var posts = (User.IsInRole("Admin")) ? db.BlogPosts.Include("Blog").Include("Blog.User").Where(p => (p.Blog.User.Username == username && p.BlogPostId == id))
: db.BlogPosts.Include("Blog").Include("Blog.User").Where(p => (p.Blog.User.Username == username && p.BlogPostId == id) &&
(p.Published || p.Blog.User.Username == User.Identity.Name));
if (posts != null && posts.Any())
{
@ -99,13 +99,13 @@ namespace Teknik.Areas.Blog.Controllers
[AllowAnonymous]
public ActionResult GetPosts(int blogID, int startPostID, int count)
{
var posts = (User.IsInRole("Admin")) ? db.Posts.Include("Blog").Include("Blog.User").Where(p => ((p.BlogId == blogID && !p.System) || (p.System && blogID == Constants.SERVERBLOGID))).OrderByDescending(p => p.DatePosted).Skip(startPostID).Take(count).ToList()
: db.Posts.Include("Blog").Include("Blog.User").Where(p => ((p.BlogId == blogID && !p.System) || (p.System && blogID == Constants.SERVERBLOGID)) && (p.Published || p.Blog.User.Username == User.Identity.Name)
var posts = (User.IsInRole("Admin")) ? db.BlogPosts.Include("Blog").Include("Blog.User").Where(p => ((p.BlogId == blogID && !p.System) || (p.System && blogID == Constants.SERVERBLOGID))).OrderByDescending(p => p.DatePosted).Skip(startPostID).Take(count).ToList()
: db.BlogPosts.Include("Blog").Include("Blog.User").Where(p => ((p.BlogId == blogID && !p.System) || (p.System && blogID == Constants.SERVERBLOGID)) && (p.Published || p.Blog.User.Username == User.Identity.Name)
).OrderByDescending(p => p.DatePosted).Skip(startPostID).Take(count).ToList();
List<PostViewModel> postViews = new List<PostViewModel>();
if (posts != null)
{
foreach (Post post in posts)
foreach (BlogPost post in posts)
{
postViews.Add(new PostViewModel(post));
}
@ -118,8 +118,8 @@ namespace Teknik.Areas.Blog.Controllers
public ActionResult GetPostTitle(int postID)
{
string title = string.Empty;
Post post = (User.IsInRole("Admin")) ? db.Posts.Find(postID)
: db.Posts.Include("Blog").Include("Blog.User").Where(p => (p.PostId == postID) && (p.Published || p.Blog.User.Username == User.Identity.Name)).First();
BlogPost post = (User.IsInRole("Admin")) ? db.BlogPosts.Find(postID)
: db.BlogPosts.Include("Blog").Include("Blog.User").Where(p => (p.BlogPostId == postID) && (p.Published || p.Blog.User.Username == User.Identity.Name)).First();
if (post != null)
{
return Json(new { result = post.Title });
@ -132,7 +132,7 @@ namespace Teknik.Areas.Blog.Controllers
public ActionResult GetPostArticle(int postID)
{
string title = string.Empty;
Post post = (User.IsInRole("Admin")) ? db.Posts.Find(postID) : db.Posts.Include("Blog").Include("Blog.User").Where(p => (p.PostId == postID) &&
BlogPost post = (User.IsInRole("Admin")) ? db.BlogPosts.Find(postID) : db.BlogPosts.Include("Blog").Include("Blog.User").Where(p => (p.BlogPostId == postID) &&
(p.Published || p.Blog.User.Username == User.Identity.Name)).First();
if (post != null)
{
@ -156,7 +156,7 @@ namespace Teknik.Areas.Blog.Controllers
blogID = user.First().BlogId;
}
}
Post post = db.Posts.Create();
BlogPost post = db.BlogPosts.Create();
post.BlogId = blogID;
post.Title = title;
post.Article = article;
@ -164,7 +164,7 @@ namespace Teknik.Areas.Blog.Controllers
post.DatePosted = DateTime.Now;
post.DatePublished = DateTime.Now;
db.Posts.Add(post);
db.BlogPosts.Add(post);
db.SaveChanges();
return Json(new { result = true });
}
@ -177,7 +177,7 @@ namespace Teknik.Areas.Blog.Controllers
{
if (ModelState.IsValid)
{
Post post = db.Posts.Find(postID);
BlogPost post = db.BlogPosts.Find(postID);
if (post != null)
{
post.Title = title;
@ -196,7 +196,7 @@ namespace Teknik.Areas.Blog.Controllers
{
if (ModelState.IsValid)
{
Post post = db.Posts.Find(postID);
BlogPost post = db.BlogPosts.Find(postID);
if (post != null)
{
post.Published = publish;
@ -216,10 +216,10 @@ namespace Teknik.Areas.Blog.Controllers
{
if (ModelState.IsValid)
{
Post post = db.Posts.Find(postID);
BlogPost post = db.BlogPosts.Find(postID);
if (post != null)
{
db.Posts.Remove(post);
db.BlogPosts.Remove(post);
db.SaveChanges();
return Json(new { result = true });
}
@ -233,11 +233,11 @@ namespace Teknik.Areas.Blog.Controllers
[AllowAnonymous]
public ActionResult GetComments(int postID, int startCommentID, int count)
{
var comments = db.BlogComments.Include("Post").Include("Post.Blog").Include("Post.Blog.User").Where(p => (p.PostId == postID)).OrderByDescending(p => p.DatePosted).Skip(startCommentID).Take(count).ToList();
var comments = db.BlogComments.Include("Post").Include("Post.Blog").Include("Post.Blog.User").Where(p => (p.BlogPostId == postID)).OrderByDescending(p => p.DatePosted).Skip(startCommentID).Take(count).ToList();
List<CommentViewModel> commentViews = new List<CommentViewModel>();
if (comments != null)
{
foreach (Comment comment in comments)
foreach (BlogPostComment comment in comments)
{
commentViews.Add(new CommentViewModel(comment));
}
@ -249,7 +249,7 @@ namespace Teknik.Areas.Blog.Controllers
[AllowAnonymous]
public ActionResult GetCommentArticle(int commentID)
{
Comment comment = db.BlogComments.Include("Post").Include("Post.Blog").Include("Post.Blog.User").Where(p => (p.CommentId == commentID)).First();
BlogPostComment comment = db.BlogComments.Include("Post").Include("Post.Blog").Include("Post.Blog.User").Where(p => (p.BlogPostCommentId == commentID)).First();
if (comment != null)
{
return Json(new { result = comment.Article });
@ -263,8 +263,8 @@ namespace Teknik.Areas.Blog.Controllers
{
if (ModelState.IsValid)
{
Comment comment = db.BlogComments.Create();
comment.PostId = postID;
BlogPostComment comment = db.BlogComments.Create();
comment.BlogPostId = postID;
comment.UserId = db.Users.Where(u => u.Username == User.Identity.Name).First().UserId;
comment.Article = article;
comment.DatePosted = DateTime.Now;
@ -282,7 +282,7 @@ namespace Teknik.Areas.Blog.Controllers
{
if (ModelState.IsValid)
{
Comment comment = db.BlogComments.Find(commentID);
BlogPostComment comment = db.BlogComments.Find(commentID);
if (comment != null)
{
comment.Article = article;
@ -300,7 +300,7 @@ namespace Teknik.Areas.Blog.Controllers
{
if (ModelState.IsValid)
{
Comment comment = db.BlogComments.Find(commentID);
BlogPostComment comment = db.BlogComments.Find(commentID);
if (comment != null)
{
db.BlogComments.Remove(comment);

View File

@ -16,6 +16,6 @@ namespace Teknik.Areas.Blog.Models
public User User { get; set; }
public List<Post> Posts { get; set; }
public List<BlogPost> BlogPosts { get; set; }
}
}

View File

@ -4,9 +4,9 @@ using System.ComponentModel.DataAnnotations;
namespace Teknik.Areas.Blog.Models
{
public class Post
public class BlogPost
{
public int PostId { get; set; }
public int BlogPostId { get; set; }
public int BlogId { get; set; }
@ -26,6 +26,6 @@ namespace Teknik.Areas.Blog.Models
public List<string> Tags { get; set; }
public List<Comment> Comments { get; set; }
public List<BlogPostComment> Comments { get; set; }
}
}

View File

@ -6,13 +6,13 @@ using Teknik.Areas.Profile.Models;
namespace Teknik.Areas.Blog.Models
{
public class Comment
public class BlogPostComment
{
public int CommentId { get; set; }
public int BlogPostCommentId { get; set; }
public int PostId { get; set; }
public int BlogPostId { get; set; }
public Post Post { get; set; }
public BlogPost BlogPost { get; set; }
public int? UserId { get; set; }

View File

@ -12,17 +12,17 @@ namespace Teknik.Areas.Blog.ViewModels
{
public int CommentId { get; set; }
public int PostId { get; set; }
public Post Post { get; set; }
public BlogPost Post { get; set; }
public int? UserId { get; set; }
public User User { get; set; }
public DateTime DatePosted { get; set; }
public string Article { get; set; }
public CommentViewModel(Comment comment)
public CommentViewModel(BlogPostComment comment)
{
CommentId = comment.CommentId;
PostId = comment.PostId;
Post = comment.Post;
CommentId = comment.BlogPostCommentId;
PostId = comment.BlogPostId;
Post = comment.BlogPost;
UserId = comment.UserId;
User = comment.User;
DatePosted = comment.DatePosted;

View File

@ -30,12 +30,12 @@ namespace Teknik.Areas.Blog.ViewModels
public List<string> Tags { get; set; }
public List<Comment> Comments { get; set; }
public List<BlogPostComment> Comments { get; set; }
public PostViewModel(Post post)
public PostViewModel(BlogPost post)
{
BlogId = post.BlogId;
PostId = post.PostId;
PostId = post.BlogPostId;
Blog = post.Blog;
System = post.System;
DatePosted = post.DatePosted;

View File

@ -16,7 +16,7 @@
<div class="blog-post">
<h2 class="blog-post-title text-center"><a href="@Url.SubRouteUrl("blog", "Blog.Post", new { username = Model.Blog.User.Username, id = Model.PostId })" id="title_@Model.PostId">@Model.Title</a></h2>
<p class="blog-post-meta text-center text-muted">
Posted on <time datetime="@Model.DatePosted.ToString("o")">@Model.DatePublished.ToString("MMMM dd, yyyy")</time> by <a href="@Url.SubRouteUrl("profile", "Profile.Index", new { username = Model.Blog.User.Username })">@Model.Blog.User.Username</a>
Posted on <time datetime="@Model.DatePosted.ToString("o")">@Model.DatePosted.ToString("MMMM dd, yyyy")</time> by <a href="@Url.SubRouteUrl("profile", "Profile.Index", new { username = Model.Blog.User.Username })">@Model.Blog.User.Username</a>
@if (Model.Blog.User.Username == User.Identity.Name || User.IsInRole("Admin"))
{
<br />

View File

@ -21,17 +21,17 @@ namespace Teknik.Areas.Home.Controllers
{
HomeViewModel model = new HomeViewModel();
// Grab the latest site blog posts
List<Post> lastSite = new List<Post>();
var foundSite = db.Posts.Include("Blog").Include("Blog.User").OrderBy(post => post.DatePosted).Where(p => p.Published && p.System).Take(10);
List<BlogPost> lastSite = new List<BlogPost>();
var foundSite = db.BlogPosts.Include("Blog").Include("Blog.User").OrderBy(post => post.DatePosted).Where(p => p.Published && p.System).Take(10);
if (foundSite != null)
lastSite = foundSite.ToList();
// Grab the latest user blog posts
List<Post> lastPosts = new List<Post>();
var foundPosts = db.Posts.Include("Blog").Include("Blog.User").OrderBy(post => post.DatePosted).Where(p => p.Published && !p.System).Take(10);
List<BlogPost> lastPosts = new List<BlogPost>();
var foundPosts = db.BlogPosts.Include("Blog").Include("Blog.User").OrderBy(post => post.DatePosted).Where(p => p.Published && !p.System).Take(10);
if (foundPosts != null)
lastPosts = foundPosts.ToList();
// Grab the latest podcasts
List<Post> lastPods = new List<Post>();
List<BlogPost> lastPods = new List<BlogPost>();
model.SitePosts = lastSite;
model.Podcasts = lastPods;

View File

@ -10,8 +10,8 @@ namespace Teknik.Areas.Home.ViewModels
{
public class HomeViewModel : ViewModelBase
{
public List<Post> SitePosts { get; set; }
public List<Post> Podcasts { get; set; }
public List<Post> BlogPosts { get; set; }
public List<BlogPost> SitePosts { get; set; }
public List<BlogPost> Podcasts { get; set; }
public List<BlogPost> BlogPosts { get; set; }
}
}

View File

@ -0,0 +1,80 @@

/*
* Podcast name and description
*/
.podcast-header {
padding-top: 20px;
padding-bottom: 20px;
}
.podcast-title {
margin-top: 30px;
margin-bottom: 0;
font-size: 60px;
font-weight: normal;
}
.podcast-description {
font-size: 20px;
}
/*
* Main column and sidebar layout
*/
.podcast-main {
font-size: 18px;
line-height: 1.5;
}
/*
* Podcasts
*/
.podcast-post {
margin-bottom: 60px;
}
.podcast-post-sm {
margin-bottom: 5;
}
.podcast-post-title {
margin-bottom: 5px;
font-size: 40px;
}
.podcast-post-title-sm {
margin-bottom: 5px;
font-size: 18px;
line-height: 1;
}
.podcast-post-meta {
margin-bottom: 20px;
}
.podcast-post-meta-sm {
margin-bottom: 5;
font-size: 12px;
line-height: 1;
}
/*
* Comment Styling
*/
.post-comment {
margin-bottom: 20px;
}
.post-comment-title {
margin-bottom: 5px;
font-size: 40px;
}
.post-comment-meta {
margin-bottom: 20px;
}
/*
* Markdown Edits
*/
blockquote {
border-left: 2px dotted #888;
padding-left: 5px;
background: #d0f0ff;
}

View File

@ -0,0 +1,276 @@
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Teknik.Areas.Podcast.ViewModels;
using Teknik.Controllers;
using Teknik.Models;
namespace Teknik.Areas.Podcast.Controllers
{
public class PodcastController : DefaultController
{
private TeknikEntities db = new TeknikEntities();
// GET: Blogs/Details/5
[AllowAnonymous]
public ActionResult Index()
{
MainViewModel model = new MainViewModel();
try
{
ViewBag.Title = "Teknik Blog - " + Config.Title;
var foundPodcasts = (User.IsInRole("Admin")) ? db.Podcasts.FirstOrDefault() : db.Podcasts.Where(p => (p.Published)).FirstOrDefault();
if (foundPodcasts != null)
{
model = new MainViewModel();
model.Title = Config.PodcastConfig.Title;
model.Description = Config.PodcastConfig.Description;
model.HasPodcasts = (foundPodcasts != null);
}
else
{
model.Error = true;
model.ErrorMessage = "No Podcasts Available";
}
return View("~/Areas/Podcast/Views/Podcast/Main.cshtml", model);
}
catch (Exception ex)
{
model.Error = true;
model.ErrorMessage = ex.Message;
return View("~/Areas/Podcast/Views/Podcast/Main.cshtml", model);
}
}
#region Posts
// GET: Blogs/Details/5
[AllowAnonymous]
public ActionResult View(int episode)
{
PodcastViewModel model = new PodcastViewModel();
// find the podcast specified
var foundPodcast = (User.IsInRole("Admin")) ? db.Podcasts.Where(p => p.Episode == episode).FirstOrDefault() : db.Podcasts.Where(p => (p.Published && p.Episode == episode)).FirstOrDefault();
if (foundPodcast != null)
{
model.PodcastId = foundPodcast.PodcastId;
model.Episode = foundPodcast.Episode;
model.Title = foundPodcast.Title;
model.Description = foundPodcast.Description;
model.Files = foundPodcast.Files;
ViewBag.Title = model.Title + " - Teknikast - " + Config.Title;
return View("~/Areas/Podcast/Views/Podcast/ViewPodcast.cshtml", model);
}
model.Error = true;
model.ErrorMessage = "No Podcasts Available";
return View("~/Areas/Podcast/Views/Podcast/ViewPodcast.cshtml", model);
}
[HttpPost]
[AllowAnonymous]
public ActionResult GetPodcasts(int startPodcastID, int count)
{
var podcasts = (User.IsInRole("Admin")) ? db.Podcasts.OrderByDescending(p => p.DatePosted).Skip(startPodcastID).Take(count).ToList()
: db.Podcasts.Where(p => p.Published).OrderByDescending(p => p.DatePosted).Skip(startPodcastID).Take(count).ToList();
List<PodcastViewModel> podcastViews = new List<PodcastViewModel>();
if (podcasts != null)
{
foreach (Models.Podcast podcast in podcasts)
{
podcastViews.Add(new PodcastViewModel(podcast));
}
}
return PartialView("~/Areas/Podcast/Views/Podcast/Podcasts.cshtml", podcastViews);
}
[HttpPost]
[AllowAnonymous]
public ActionResult GetPodcastTitle(int podcastId)
{
var foundPodcast = (User.IsInRole("Admin")) ? db.Podcasts.Where(p => p.PodcastId == podcastId).FirstOrDefault() : db.Podcasts.Where(p => (p.Published && p.PodcastId == podcastId)).FirstOrDefault();
if (foundPodcast != null)
{
return Json(new { result = foundPodcast.Title });
}
return Json(new { error = "No title found" });
}
[HttpPost]
[AllowAnonymous]
public ActionResult GetPodcastDescription(int podcastId)
{
var foundPodcast = (User.IsInRole("Admin")) ? db.Podcasts.Where(p => p.PodcastId == podcastId).FirstOrDefault() : db.Podcasts.Where(p => (p.Published && p.PodcastId == podcastId)).FirstOrDefault();
if (foundPodcast != null)
{
return Json(new { result = foundPodcast.Description });
}
return Json(new { error = "No article found" });
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult CreatePodcast(string title, string description, HttpPostedFileBase[] files)
{
if (ModelState.IsValid)
{
// Handle saving of files
Models.Podcast podcast = db.Podcasts.Create();
podcast.Title = title;
podcast.Description = description;
podcast.DatePosted = DateTime.Now;
podcast.DatePublished = DateTime.Now;
db.Podcasts.Add(podcast);
db.SaveChanges();
return Json(new { result = true });
}
return Json(new { error = "No podcast created" });
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult EditPodcast(int podcastId, string title, string description)
{
if (ModelState.IsValid)
{
Models.Podcast podcast = db.Podcasts.Find(podcastId);
if (podcast != null)
{
podcast.Title = title;
podcast.Description = description;
db.Entry(podcast).State = EntityState.Modified;
db.SaveChanges();
return Json(new { result = true });
}
}
return Json(new { error = "No podcast found" });
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult PublishPodcast(int podcastId, bool publish)
{
if (ModelState.IsValid)
{
Models.Podcast podcast = db.Podcasts.Find(podcastId);
if (podcast != null)
{
podcast.Published = publish;
if (publish)
podcast.DatePublished = DateTime.Now;
db.Entry(podcast).State = EntityState.Modified;
db.SaveChanges();
return Json(new { result = true });
}
}
return Json(new { error = "No podcast found" });
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult DeletePodcast(int podcastId)
{
if (ModelState.IsValid)
{
Models.Podcast podcast = db.Podcasts.Find(podcastId);
if (podcast != null)
{
db.Podcasts.Remove(podcast);
db.SaveChanges();
return Json(new { result = true });
}
}
return Json(new { error = "No post found" });
}
#endregion
#region Comments
[HttpPost]
[AllowAnonymous]
public ActionResult GetComments(int podcastId, int startCommentID, int count)
{
var comments = db.PodcastComments.Include("Podcast").Where(p => (p.PodcastId == podcastId)).OrderByDescending(p => p.DatePosted).Skip(startCommentID).Take(count).ToList();
List<CommentViewModel> commentViews = new List<CommentViewModel>();
if (comments != null)
{
foreach (Models.PodcastComment comment in comments)
{
commentViews.Add(new CommentViewModel(comment));
}
}
return PartialView("~/Areas/Podcast/Views/Podcast/Comments.cshtml", commentViews);
}
[HttpPost]
[AllowAnonymous]
public ActionResult GetCommentArticle(int commentID)
{
Models.PodcastComment comment = db.PodcastComments.Include("Podcast").Where(p => (p.PodcastCommentId == commentID)).First();
if (comment != null)
{
return Json(new { result = comment.Article });
}
return Json(new { error = "No article found" });
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult CreateComment(int podcastId, string article)
{
if (ModelState.IsValid)
{
Models.PodcastComment comment = db.PodcastComments.Create();
comment.PodcastId = podcastId;
comment.UserId = db.Users.Where(u => u.Username == User.Identity.Name).First().UserId;
comment.Article = article;
comment.DatePosted = DateTime.Now;
db.PodcastComments.Add(comment);
db.SaveChanges();
return Json(new { result = true });
}
return Json(new { error = "No comment created" });
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult EditComment(int commentID, string article)
{
if (ModelState.IsValid)
{
Models.PodcastComment comment = db.PodcastComments.Find(commentID);
if (comment != null)
{
comment.Article = article;
db.Entry(comment).State = EntityState.Modified;
db.SaveChanges();
return Json(new { result = true });
}
}
return Json(new { error = "No comment found" });
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult DeleteComment(int commentID)
{
if (ModelState.IsValid)
{
Models.PodcastComment comment = db.PodcastComments.Find(commentID);
if (comment != null)
{
db.PodcastComments.Remove(comment);
db.SaveChanges();
return Json(new { result = true });
}
}
return Json(new { error = "No comment found" });
}
#endregion
}
}

View File

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Teknik.Areas.Podcast.Models
{
public class Podcast
{
public int PodcastId { get; set; }
public int Episode { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public List<PodcastFile> Files { get; set; }
public List<string> Tags { get; set; }
public bool Published { get; set; }
public DateTime DatePosted { get; set; }
public DateTime DatePublished { get; set; }
public List<PodcastComment> Comments { get; set; }
}
}

View File

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Teknik.Areas.Profile.Models;
namespace Teknik.Areas.Podcast.Models
{
public class PodcastComment
{
public int PodcastCommentId { get; set; }
public int PodcastId { get; set; }
public Podcast Podcast { get; set; }
public int UserId { get; set; }
public User User { get; set; }
public DateTime DatePosted { get; set; }
public string Article { get; set; }
}
}

View File

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Teknik.Areas.Podcast.Models
{
public class PodcastFile
{
public int PodcastFileId { get; set; }
public int PodcastId { get; set; }
public Podcast Podcast { get; set; }
public string FileName { get; set; }
public string Path { get; set; }
public string ContentType { get; set; }
public int Size { get; set; }
}
}

View File

@ -0,0 +1,58 @@
using System.Collections.Generic;
using System.Web.Mvc;
using System.Web.Optimization;
namespace Teknik.Areas.Podcast
{
public class PodcastAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Podcast";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapSubdomainRoute(
"Podcast.Index", // Route name
new List<string>() { "dev", "podcast" }, // Subdomains
"", // URL with parameters
new { controller = "Podcast", action = "Index" }, // Parameter defaults
new[] { typeof(Controllers.PodcastController).Namespace }
);
context.MapSubdomainRoute(
"Podcast.View", // Route name
new List<string>() { "dev", "podcast" }, // Subdomains
"{episode}", // URL with parameters
new { controller = "Podcast", action = "View" }, // Parameter defaults
new[] { typeof(Controllers.PodcastController).Namespace }
);
context.MapSubdomainRoute(
"Podcast.Action", // Route name
new List<string>() { "dev", "podcast" }, // Subdomains
"Action/{controller}/{action}", // URL with parameters
new { controller = "Podcast", action = "Index" }, // Parameter defaults
new[] { typeof(Controllers.PodcastController).Namespace }
);
// Register Script Bundles
BundleTable.Bundles.Add(new ScriptBundle("~/bundles/podcast").Include(
"~/Scripts/bootbox/bootbox.min.js",
"~/Scripts/PageDown/Markdown.Converter.js",
"~/Scripts/PageDown/Markdown.Sanitizer.js",
"~/Scripts/bootstrap-markdown.js",
"~/Scripts/jquery-ui.widgets.js",
"~/Scripts/jquery.iframe-transport.js",
"~/Scripts/audioplayer.min.js",
"~/Areas/Podcast/Scripts/Podcast.js"));
// Register Style Bundles
BundleTable.Bundles.Add(new StyleBundle("~/Content/podcast").Include(
"~/Content/audioplayer.css",
"~/Content/bootstrap-markdown.min.css",
"~/Areas/Podcast/Content/Podcast.css"));
}
}
}

View File

@ -0,0 +1,280 @@
$(document).ready(function () {
$("#podcast_submit").click(function () {
$('#newPodcast').modal('hide');
title = $("#podcast_title").val();
post = $("#podcast_description").val();
files = $("#podcast_files").val();
$.ajax({
type: "POST",
url: addPodcastURL,
data: AddAntiForgeryToken({ title: title, description: post, files: files }),
success: function (html) {
if (html.result) {
window.location.reload();
}
else {
$("#top_msg").css('display', 'inline', 'important');
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>' + html.error + '</div>');
}
}
});
return false;
});
$('#editPodcast').on('show.bs.modal', function (e) {
$("#edit_podcast_title").val("");
$("#edit_podcast_description").val("");
podcastId = $(e.relatedTarget).attr("id");
$("#edit_podcast_podcastid").val(podcastId);
$.ajax({
type: "POST",
url: getPodcastTitleURL,
data: { podcastID: podcastId },
success: function (html) {
if (html.result) {
$("#edit_podcast_title").val(html.result);
}
}
});
$.ajax({
type: "POST",
url: getPodcastDescriptionURL,
data: { podcastID: podcastId },
success: function (html) {
if (html.result) {
$("#edit_podcast_description").val(html.result);
}
}
});
});
$("#edit_submit").click(function () {
$('#editPodcast').modal('hide');
podcastId = $("#edit_podcast_podcastId").val();
title = $("#edit_podcast_title").val();
description = $("#edit_podcast_description").val();
$.ajax({
type: "POST",
url: editPodcastURL,
data: AddAntiForgeryToken({ podcastId: podcastId, title: title, description: description }),
success: function (html) {
if (html.result) {
window.location.reload();
}
else {
$("#top_msg").css('display', 'inline', 'important');
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>' + html.error + '</div>');
}
}
});
return false;
});
$("#comment_submit").click(function () {
$('#newComment').modal('hide');
podcastId = $("#podcastId").val();
post = $("#comment_post").val();
$.ajax({
type: "POST",
url: addCommentURL,
data: AddAntiForgeryToken({ podcastId: postID, article: post }),
success: function (html) {
if (html.result) {
window.location.reload();
}
else {
$("#top_msg").css('display', 'inline', 'important');
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>' + html.error + '</div>');
}
}
});
return false;
});
$('#editComment').on('show.bs.modal', function (e) {
$("#edit_comment_post").val("");
commentID = encodeURIComponent($(e.relatedTarget).attr("id"));
$("#edit_comment_id").val(commentID);
$.ajax({
type: "POST",
url: getCommentArticleURL,
data: { commentID: commentID },
success: function (html) {
if (html.result) {
$("#edit_comment_post").val(html.result);
}
}
});
});
$("#edit_comment_submit").click(function () {
$('#editComment').modal('hide');
postID = encodeURIComponent($("#edit_comment_id").val());
post = encodeURIComponent($("#edit_comment_post").val());
$.ajax({
type: "POST",
url: editCommentURL,
data: AddAntiForgeryToken({ commentID: postID, article: post }),
success: function (html) {
if (html.result) {
window.location.reload();
}
else {
$("#top_msg").css('display', 'inline', 'important');
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>' + html.error + '</div>');
}
}
});
return false;
});
});
function loadMorePodcasts(start, count) {
podcastId = $(".podcast-main").attr("id");
$.ajax({
type: "POST",
url: getPodcastsURL,
data: { podcastId: podcastId, count: count, startPodcastID: start },
success: function (html) {
if (html) {
$(".podcast-main").append(html);
linkPostDelete('.delete_podcast');
linkPostPublish('.publish_podcast');
linkPostUnpublish('.unpublish_podcast');
linkAudioPlayer('audio');
$(window).bind('scroll', bindScrollPosts);
}
}
});
}
function loadMoreComments(start, count) {
post_id = $(".podcast-comments").attr("id");
$.ajax({
type: "POST",
url: getCommentsURL,
data: { postID: post_id, count: count, startCommentID: start },
success: function (html) {
if (html) {
$(".podcast-comments").append(html);
linkCommentDelete('.delete_comment');
$(window).bind('scroll', bindScrollComments);
}
}
});
}
function bindScrollPosts() {
if ($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
$(window).unbind('scroll');
loadMorePodcasts(startPodcast, podcasts);
startPodcast = startPodcast + podcasts;
}
}
function bindScrollComments() {
if ($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
$(window).unbind('scroll');
loadMoreComments(startComment, comments);
startComment = startComment + comments;
}
}
function linkPodcastUnpublish(selector) {
$(selector).click(function () {
var object = $(this);
podcastId = object.attr("id");
$.ajax({
type: "POST",
url: publishPodcastURL,
data: AddAntiForgeryToken({ podcastId: podcastId, publish: false }),
success: function (html) {
if (html.result) {
window.location.reload();
}
else {
$("#top_msg").css('display', 'inline', 'important');
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>' + html.error + '</div>');
}
}
});
});
}
function linkPodcastPublish(selector) {
$(selector).click(function () {
var object = $(this);
podcastId = object.attr("id");
$.ajax({
type: "POST",
url: publishPodcastURL,
data: AddAntiForgeryToken({ podcastId: podcastId, publish: true }),
success: function (html) {
if (html.result) {
window.location.reload();
}
else {
$("#top_msg").css('display', 'inline', 'important');
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>' + html.error + '</div>');
}
}
});
});
}
function linkPodcastDelete(selector) {
$(selector).click(function () {
var object = $(this);
podcastId = object.attr("id");
bootbox.confirm("Are you sure you want to delete the podcast?", function (result) {
if (result) {
$.ajax({
type: "POST",
url: deletePodcastURL,
data: AddAntiForgeryToken({ podcastId: podcastId }),
success: function (html) {
if (html.result) {
window.location.reload();
}
else {
$("#top_msg").css('display', 'inline', 'important');
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>' + html.error + '</div>');
}
}
});
}
});
});
}
function linkCommentDelete(selector) {
$(selector).click(function () {
var object = $(this);
post_id = object.attr("id");
bootbox.confirm("Are you sure you want to delete your comment?", function (result) {
if (result) {
$.ajax({
type: "POST",
url: deleteCommentURL,
data: AddAntiForgeryToken({ commentID: post_id }),
success: function (html) {
if (html.result) {
window.location.reload();
}
else {
$("#top_msg").css('display', 'inline', 'important');
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>' + html.error + '</div>');
}
}
});
}
});
});
}
function linkAudioPlayer(selector) {
$(selector).audioPlayer(
{
classPrefix: 'audioplayer'
});
}

View File

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Teknik.Areas.Profile.Models;
using Teknik.ViewModels;
namespace Teknik.Areas.Podcast.ViewModels
{
public class CommentViewModel : ViewModelBase
{
public int CommentId { get; set; }
public int PodcastId { get; set; }
public Models.Podcast Podcast { get; set; }
public User User { get; set; }
public DateTime DatePosted { get; set; }
public string Article { get; set; }
public CommentViewModel(Models.PodcastComment comment)
{
CommentId = comment.PodcastCommentId;
PodcastId = comment.PodcastId;
Podcast = comment.Podcast;
User = comment.User;
DatePosted = comment.DatePosted;
Article = comment.Article;
}
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Teknik.ViewModels;
namespace Teknik.Areas.Podcast.ViewModels
{
public class MainViewModel : ViewModelBase
{
public string Title { get; set; }
public string Description { get; set; }
public bool HasPodcasts { get; set; }
}
}

View File

@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Teknik.Areas.Podcast.Models;
using Teknik.ViewModels;
namespace Teknik.Areas.Podcast.ViewModels
{
public class PodcastViewModel : ViewModelBase
{
public int PodcastId { get; set; }
public int Episode { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public List<PodcastFile> Files { get; set; }
public List<string> Tags { get; set; }
public DateTime DatePosted { get; set; }
public bool Published { get; set; }
public DateTime DatePublished { get; set; }
public PodcastViewModel() { }
public PodcastViewModel(Models.Podcast podcast)
{
PodcastId = podcast.PodcastId;
Episode = podcast.Episode;
Title = podcast.Title;
Description = podcast.Description;
Files = podcast.Files;
Tags = podcast.Tags;
DatePosted = podcast.DatePosted;
Published = podcast.Published;
DatePublished = podcast.DatePublished;
}
}
}

View File

@ -0,0 +1,30 @@
@model Teknik.Areas.Blog.ViewModels.CommentViewModel
<script>
var converter = new Markdown.getSanitizingConverter();
// Title Conversion
var old_post = $("#title_@Model.CommentId").text();
var new_post = converter.makeHtml(old_post);
$("#title_@Model.CommentId").html(new_post);
// Post Conversion
var old_post = $("#comment_@Model.CommentId").text();
var new_post = converter.makeHtml(old_post);
$("#comment_@Model.CommentId").html(new_post);
</script>
<hr>
<div class="row">
<div class="col-sm-8 col-sm-offset-2">
<div class="post-comment">
<p class="post-comment-meta text-muted">
<a href="@Url.SubRouteUrl("profile", "Profile.Index", new { username = Model.User.Username })">@Model.User.Username</a> replied at <time datetime="@Model.DatePosted.ToString("o")">@Model.DatePosted.ToString("HH:mm:ss tt") on @Model.DatePosted.ToString("MMMM dd, yyyy")</time>
@if (Model.User.Username == User.Identity.Name || User.IsInRole("Admin"))
{
<br />
<button type="button" class="btn btn-info edit_comment" id="@Model.CommentId" data-toggle="modal" data-target="#editComment">Edit</button>
<button type="button" class="btn btn-danger delete_comment" id="@Model.CommentId">Delete</button>
}
</p>
<p id="comment_@Model.CommentId">@Model.Article</p>
</div>
</div>
</div>

View File

@ -0,0 +1,6 @@
@model List<Teknik.Areas.Podcast.ViewModels.CommentViewModel>
@foreach (var comment in Model)
{
@Html.Partial("Comment", comment)
}

View File

@ -0,0 +1,138 @@
@model Teknik.Areas.Podcast.ViewModels.MainViewModel
<script>
// We need to define the action URLs for the script
var uploadURL = '@Url.SubRouteUrl("upload", "Upload.Upload")';
var getPodcastsURL = '@Url.SubRouteUrl("podcast", "Podcast.Action", new { action = "GetPodcasts" })';
var getPodcastTitleURL = '@Url.SubRouteUrl("podcast", "Podcast.Action", new { action = "GetPodcastTitle" })';
var getPodcastArticleURL = '@Url.SubRouteUrl("podcast", "Podcast.Action", new { action = "GetPodcastArticle" })';
var publishPodcastURL = '@Url.SubRouteUrl("podcast", "Podcast.Action", new { action = "PublishPodcast" })';
var addPodcastURL = '@Url.SubRouteUrl("podcast", "Podcast.Action", new { action = "CreatePodcast" })';
var editPodcastURL = '@Url.SubRouteUrl("podcast", "Podcast.Action", new { action = "EditPodcast" })';
var deletePodcastURL = '@Url.SubRouteUrl("podcast", "Podcast.Action", new { action = "DeletePodcast" })';
var getCommentsURL = '@Url.SubRouteUrl("podcast", "Podcast.Action", new { action = "GetComments" })';
var getCommentArticleURL = '@Url.SubRouteUrl("podcast", "Podcast.Action", new { action = "GetCommentArticle" })';
var addCommentURL = '@Url.SubRouteUrl("podcast", "Podcast.Action", new { action = "CreateComment" })';
var editCommentURL = '@Url.SubRouteUrl("podcast", "Podcast.Action", new { action = "EditComment" })';
var deleteCommentURL = '@Url.SubRouteUrl("podcast", "Podcast.Action", new { action = "DeleteComment" })';
</script>
@Styles.Render("~/Content/podcast")
@Scripts.Render("~/bundles/podcast")
<div class="container">
<div class="row">
<div class="col-sm-12 podcast-heading">
<h1 class="podcast-title text-center">@Model.Title</h1>
<p class="lead podcast-description text-center text-muted">@Model.Description</p>
</div>
</div>
<div class="row">
<div class="col-sm-12 text-center">
<p>
<a href="@Url.SubRouteUrl("rss", "RSS.Podcast")"><i class="fa fa-rss fa-2x fa-border"></i></a>
</p>
</div>
</div>
@if (User.IsInRole("Admin") || User.IsInRole("Podcast"))
{
<div class="row">
<div class="col-sm-12 text-center">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#newPodcast">Create Podcast</button>
</div>
</div>
<div class="modal fade" id="newPodcast" tabindex="-1" role="dialog" aria-labelledby="newPodcastLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<form class="form" action="##" method="post" id="publishPodcast">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Cancel</span></button>
<h4 class="modal-title" id="newPodcastLabel">Create a New Podcast</h4>
</div>
<div class="modal-body">
<div class="row">
<div class="form-group col-sm-12">
<label for="podcast_title"><h4>Title</h4></label>
<input class="form-control" name="podcast_title" id="podcast_title" placeholder="Awesome Podcast Title" title="enter a title for the podcast." type="text" />
</div>
</div>
<div class="row">
<div class="form-group col-sm-12">
<label for="podcast_description"><h4>Podcast Description</h4></label>
<textarea class="form-control wmd-input" name="podcast_description" id="podcast_description" placeholder="We talked about awesome stuff." title="enter what the podcast was about." data-provide="markdown" rows="10"></textarea>
</div>
</div>
<div class="row">
<div class="form-group col-sm-12">
<label for="files"><h4>Upload Podcast</h4></label>
<input id="files" name="files" type="file" placeholder="podcast.ogg" title="select the podcast file." multiple="multiple" />
</div>
</div>
<div class="row">
<div class="form-group col-sm-12" id="uploadedPodcasts"></div>
<input name="podcast_file" id="podcast_file" type="hidden" />
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" id="podcast_submit">Create</button>
</div>
</form>
</div>
</div>
</div>
<div class="modal fade" id="editPodcast" tabindex="-1" role="dialog" aria-labelledby="editPodcastLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<form class="form" action="##" method="post" id="editPodcastForm">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Cancel</span></button>
<h4 class="modal-title" id="editPodcastLabel">Edit The Podcast</h4>
</div>
<div class="modal-body">
<input name="edit_podcast_podcastId" id="edit_podcast_podcastId" type="hidden" />
<div class="row">
<div class="form-group col-sm-12">
<label for="edit_podcast_title"><h4>Title</h4></label>
<input class="form-control" name="edit_podcast_title" id="edit_podcast_title" placeholder="Awesome Podcast Title" title="enter a title for the podcast." type="text" />
</div>
</div>
<div class="row">
<div class="form-group col-sm-12">
<label for="edit_podcast_description"><h4>Podcast Description</h4></label>
<textarea class="form-control wmd-input" name="edit_podcast_description" id="edit_podcast_description" placeholder="We talked about awesome stuff." title="enter what the podcast was about." data-provide="markdown" rows="10"></textarea>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" id="edit_submit">Save</button>
</div>
</form>
</div>
</div>
</div>
}
@if (!Model.Error)
{
<div class="podcast-main"></div>
<script>
var podcasts = @Model.Config.PodcastConfig.PodcastsToLoad;
var startPodcast = 0;
loadMorePodcasts(startPodcast, podcasts);
startPodcast = startPodcast + podcasts;
</script>
}
else
{
<div class="row">
<div class="col-sm-12 text-center">
<h2>@Model.ErrorMessage</h2>
</div>
</div>
}
</div>

View File

@ -0,0 +1,50 @@
@model Teknik.Areas.Podcast.ViewModels.PodcastViewModel
@using Teknik.Areas.Podcast.Models
<script>
var converter = new Markdown.getSanitizingConverter();
var old_post = $("#podcast_@Model.PodcastId").text();
var new_post = converter.makeHtml(old_post);
$("#podcast_@Model.PodcastId").html(new_post);
</script>
<div class="row">
<div class="col-sm-10 col-sm-offset-1">
<div class="podcast-post">
<h2 class="podcast-post-title text-center"><a href="@Url.SubRouteUrl("podcast", "Podcast.View", new { episode = Model.Episode })" id="title_@Model.PodcastId">@Model.Title</a></h2>
<p class="podcast-post-meta text-center text-muted">
Posted on <time datetime="@Model.DatePosted.ToString("o")">@Model.DatePosted.ToString("MMMM dd, yyyy")</time>
@if (User.IsInRole("Admin") || User.IsInRole("Podcast"))
{
<br />
<button type="button" class="btn btn-info edit_post" id="@Model.PodcastId" data-toggle="modal" data-target="#editPodcast">Edit</button>
if (Model.Published)
{
<button type="button" class="btn btn-warning unpublish_podcast" id="@Model.PodcastId">Unpublish</button>
}
else
{
<button type="button" class="btn btn-success publish_podcast" id="@Model.PodcastId">Publish</button>
}
<button type="button" class="btn btn-danger delete_post" id="@Model.PodcastId">Delete</button>
}
</p>
<div class="text-center">
<audio preload="none" controls>
@foreach (PodcastFile file in Model.Files)
{
<source src="@file.Path" type="@file.ContentType" />
}
</audio>
</div>
<br />
<p id="podcast_@Model.PodcastId">@Model.Description</p>
@foreach (PodcastFile file in Model.Files)
{
<div class="row text-center">
<a href="@Url.SubRouteUrl("podcast", "Podcast.Download", new { file = file.FileName })">Direct Download - @file.ContentType</a>
</div>
}
</div>
</div>
</div>

View File

@ -0,0 +1,6 @@
@model List<Teknik.Areas.Podcast.ViewModels.PodcastViewModel>
@foreach (var podcast in Model)
{
@Html.Partial("Podcast", podcast)
}

View File

@ -0,0 +1,135 @@
@model Teknik.Areas.Podcast.ViewModels.PodcastViewModel
<div class="container">
@if (!Model.Error)
{
@if (User.IsInRole("Admin"))
{
<div class="modal fade" id="editPodcast" tabindex="-1" role="dialog" aria-labelledby="editPodcastLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<form class="form" action="##" method="post" id="editPodcastForm">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Cancel</span></button>
<h4 class="modal-title" id="editPodcastLabel">Edit Your Post</h4>
</div>
<div class="modal-body">
<input name="edit_podcast_postid" id="edit_podcast_postid" type="hidden" />
<div class="row">
<div class="form-group col-sm-12">
<label for="edit_podcast_title"><h4>Title</h4></label>
<input class="form-control" name="edit_podcast_title" id="edit_podcast_title" placeholder="Awesome Podcast Title" title="enter a title for the podcast." type="text" />
</div>
</div>
<div class="row">
<div class="form-group col-sm-12">
<label for="edit_podcast_post"><h4>Podcast Description</h4></label>
<textarea class="form-control wmd-input" name="edit_podcast_post" id="edit_podcast_post" placeholder="We talked about awesome stuff." title="enter what the podcast was about." data-provide="markdown" rows="10"></textarea>
</div>
</div>
<div class="row">
<div class="form-group col-sm-12">
<label for="uploadPodcast"><h4>Upload Podcast</h4></label>
<input id="edit_uploadPodcast" name="file" type="file" placeholder="podcast.ogg" title="select the podcast file." />
</div>
</div>
<div class="row">
<div class="form-group col-sm-12" id="edit_uploadedPodcasts"></div>
<input name="edit_podcast_file" id="edit_podcast_file" type="hidden" />
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" id="edit_submit">Save</button>
</div>
</form>
</div>
</div>
</div>
}
<div class="podcast-main" id="@Model.PodcastId">
@Html.Partial("Podcast", Model)
</div>
@if (User.IsInRole("Admin"))
{
<div class="row">
<div class="col-sm-10 col-sm-offset-1">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#newComment">Add Comment</button>
</div>
</div>
<br />
<div class="modal fade" id="newComment" tabindex="-1" role="dialog" aria-labelledby="newCommentLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<form class="form" action="##" method="post" id="publishComment">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Cancel</span></button>
<h4 class="modal-title" id="newCommentLabel">Add a New Comment</h4>
</div>
<div class="modal-body">
<input name="podcastId" id="podcastId" type="hidden" value="@Model.PodcastId" />
<div class="row">
<div class="form-group col-sm-12">
<label for="comment_post"><h4>Comment</h4></label>
<textarea class="form-control wmd-input" name="comment_post" id="comment_post" placeholder="Nice post!" title="enter what you think about the post." data-provide="markdown" rows="10"></textarea>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" id="comment_submit">Publish</button>
</div>
</form>
</div>
</div>
</div>
<div class="modal fade" id="editComment" tabindex="-1" role="dialog" aria-labelledby="editCommentLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<form class="form" action="##" method="post" id="editCommentForm">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Cancel</span></button>
<h4 class="modal-title" id="editCommentLabel">Edit Your Comment</h4>
</div>
<div class="modal-body">
<input name="edit_comment_id" id="edit_comment_id" type="hidden" />
<div class="row">
<div class="form-group col-sm-12">
<label for="edit_comment_post"><h4>Comment</h4></label>
<textarea class="form-control" name="edit_comment_post" id="edit_comment_post" placeholder="What an interesting article!" title="enter what you thought about the article." data-provide="markdown" rows="10"></textarea>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" id="edit_comment_submit">Save</button>
</div>
</form>
</div>
</div>
</div>
}
<a name="replies"></a>
<div class="post-comments" id="@Model.PodcastId"></div>
<script>
$( function()
{
linkAudioPlayer('audio');
});
var comments = @Model.Config.PodcastConfig.CommentsToLoad;
var start = 0;
loadMoreComments(start_post, posts);
start_post = start_post + posts;
</script>
}
else
{
<div class="row">
<div class="col-sm-12 text-center">
<h2>@Model.ErrorMessage</h2>
</div>
</div>
}
</div>

View File

@ -0,0 +1,3 @@
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}

View File

@ -0,0 +1,36 @@
<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
</sectionGroup>
</configSections>
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.Optimization" />
<add namespace="Teknik" />
</namespaces>
</pages>
</system.web.webPages.razor>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.webServer>
<handlers>
<remove name="BlockViewHandler"/>
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
</handlers>
</system.webServer>
</configuration>

View File

@ -22,6 +22,7 @@ namespace Teknik.Configuration
private PasteConfig _PasteConfig;
private BlogConfig _BlogConfig;
private ApiConfig _ApiConfig;
private PodcastConfig _PodcastConfig;
private string _SupportEmail;
private string _BitcoinAddress;
@ -33,26 +34,29 @@ namespace Teknik.Configuration
public string Author { get { return _Author; } set { _Author = value; } }
public string Host { get { return _Host; } set { _Host = value; } }
// Mail Server Information
public SMTPConfig SMTPConfig { get { return _SMTPConfig; } set { _SMTPConfig = value; } }
// Mail Server Configuration
public SMTPConfig SMTPConfig { get { return _SMTPConfig; } set { _SMTPConfig = value; } }
// Contact Information
public string SupportEmail { get { return _SupportEmail; } set { _SupportEmail = value; } }
// Contact Configuration
public string SupportEmail { get { return _SupportEmail; } set { _SupportEmail = value; } }
// About Information
public string BitcoinAddress { get { return _BitcoinAddress; } set { _BitcoinAddress = value; } }
// About Configuration
public string BitcoinAddress { get { return _BitcoinAddress; } set { _BitcoinAddress = value; } }
// Blog Information
public BlogConfig BlogConfig { get { return _BlogConfig; } set { _BlogConfig = value; } }
// Blog Configuration
public BlogConfig BlogConfig { get { return _BlogConfig; } set { _BlogConfig = value; } }
// Upload Configuration
public UploadConfig UploadConfig { get { return _UploadConfig; } set { _UploadConfig = value; } }
public UploadConfig UploadConfig { get { return _UploadConfig; } set { _UploadConfig = value; } }
// Paste Configuration
public PasteConfig PasteConfig { get { return _PasteConfig; } set { _PasteConfig = value; } }
public PasteConfig PasteConfig { get { return _PasteConfig; } set { _PasteConfig = value; } }
// Upload Configuration
public ApiConfig ApiConfig { get { return _ApiConfig; } set { _ApiConfig = value; } }
// API Configuration
public ApiConfig ApiConfig { get { return _ApiConfig; } set { _ApiConfig = value; } }
// Podcast Configuration
public PodcastConfig PodcastConfig { get { return _PodcastConfig; } set { _PodcastConfig = value; } }
public Config()
{
@ -76,6 +80,7 @@ namespace Teknik.Configuration
UploadConfig = new UploadConfig();
PasteConfig = new PasteConfig();
ApiConfig = new ApiConfig();
PodcastConfig = new PodcastConfig();
SupportEmail = string.Empty;
BitcoinAddress = string.Empty;
}

View File

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Teknik.Configuration
{
public class PodcastConfig
{
public string Title { get; set; }
public string Description { get; set; }
public int PodcastsToLoad { get; set; }
public int CommentsToLoad { get; set; }
public PodcastConfig()
{
SetDefaults();
}
public void SetDefaults()
{
Title = string.Empty;
Description = string.Empty;
PodcastsToLoad = 10;
CommentsToLoad = 10;
}
}
}

View File

@ -0,0 +1,266 @@
*
{
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.audioplayer
{
height: 2.5em; /* 40 */
color: #fff;
background: #333;
position: relative;
z-index: 1;
}
/* fallback case (read Adaptiveness chapter) */
.audioplayer-mini
{
width: 2.5em; /* 40 */
margin: 0 auto;
}
/* inner elements positioning (helps to achieve responsiveness) */
.audioplayer > div
{
position: absolute;
}
.audioplayer-playpause
{
width: 2.5em; /* 40 */
height: 100%;
text-align: left;
text-indent: -9999px;
cursor: pointer;
z-index: 2;
top: 0;
left: 0;
}
.audioplayer-mini .audioplayer-playpause
{
width: 100%;
}
.audioplayer-playpause:hover,
.audioplayer-playpause:focus
{
background-color: #222;
}
.audioplayer-playpause a
{
display: block;
}
/* "play" icon when audio is not being played */
.audioplayer:not(.audioplayer-playing) .audioplayer-playpause a
{
width: 0;
height: 0;
border: 0.5em solid transparent; /* 8 */
border-right: none;
border-left-color: #fff;
content: '';
position: absolute;
top: 50%;
left: 50%;
margin: -0.5em 0 0 -0.25em; /* 8 4 */
}
/* "pause" icon when audio is being played */
.audioplayer-playing .audioplayer-playpause a
{
width: 0.75em; /* 12 */
height: 0.75em; /* 12 */
position: absolute;
top: 50%;
left: 50%;
margin: -0.375em 0 0 -0.375em; /* 6 */
}
.audioplayer-playing .audioplayer-playpause a:before,
.audioplayer-playing .audioplayer-playpause a:after
{
width: 40%;
height: 100%;
background-color: #fff;
content: '';
position: absolute;
top: 0;
}
.audioplayer-playing .audioplayer-playpause a:before
{
left: 0;
}
.audioplayer-playing .audioplayer-playpause a:after
{
right: 0;
}
.audioplayer-time
{
width: 4.375em; /* 70 */
height: 100%;
line-height: 2.5em; /* 40 */
text-align: center;
z-index: 2;
top: 0;
}
.audioplayer-time-current
{
border-left: 1px solid #111;
left: 2.5em; /* 40 */
}
.audioplayer-time-duration
{
right: 2.5em; /* 40 */
}
.audioplayer-novolume .audioplayer-time-duration
{
border-right: 0;
right: 0;
}
.audioplayer-bar
{
height: 0.875em; /* 14 */
background-color: #222;
cursor: pointer;
z-index: 1;
top: 50%;
right: 6.875em; /* 110 */
left: 6.875em; /* 110 */
margin-top: -0.438em; /* 7 */
}
.audioplayer-novolume .audioplayer-bar
{
right: 4.375em; /* 70 */
}
.audioplayer-bar div
{
width: 0;
height: 100%;
position: absolute;
left: 0;
top: 0;
}
.audioplayer-bar-loaded
{
background-color: #555;
z-index: 1;
}
.audioplayer-bar-played
{
background: #007fd1;
z-index: 2;
}
.audioplayer-volume
{
width: 2.5em; /* 40 */
height: 100%;
border-left: 1px solid #111;
text-align: left;
text-indent: -9999px;
cursor: pointer;
z-index: 2;
top: 0;
right: 0;
}
.audioplayer-volume:hover,
.audioplayer-volume:focus
{
background-color: #222;
}
.audioplayer-volume-button
{
width: 100%;
height: 100%;
}
/* "volume" icon */
.audioplayer-volume-button a
{
width: 0.313em; /* 5 */
height: 0.375em; /* 6 */
background-color: #fff;
display: block;
position: relative;
z-index: 1;
top: 40%;
left: 35%;
}
.audioplayer-volume-button a:before,
.audioplayer-volume-button a:after
{
content: '';
position: absolute;
}
.audioplayer-volume-button a:before
{
width: 0;
height: 0;
border: 0.5em solid transparent; /* 8 */
border-left: none;
border-right-color: #fff;
z-index: 2;
top: 50%;
right: -0.25em;
margin-top: -0.5em; /* 8 */
}
.audioplayer:not(.audioplayer-mute) .audioplayer-volume-button a:after
{
/* "volume" icon by Nicolas Gallagher, http://nicolasgallagher.com/pure-css-gui-icons */
width: 0.313em; /* 5 */
height: 0.313em; /* 5 */
border: 0.25em double #fff; /* 4 */
border-width: 0.25em 0.25em 0 0; /* 4 */
left: 0.563em; /* 9 */
top: -0.063em; /* 1 */
-webkit-border-radius: 0 0.938em 0 0; /* 15 */
-moz-border-radius: 0 0.938em 0 0; /* 15 */
border-radius: 0 0.938em 0 0; /* 15 */
-webkit-transform: rotate( 45deg );
-moz-transform: rotate( 45deg );
-ms-transform: rotate( 45deg );
-o-transform: rotate( 45deg );
transform: rotate( 45deg );
}
/* volume adjuster */
.audioplayer-volume-adjust
{
width: 100%;
height: 6.25em; /* 100 */
cursor: default;
position: absolute;
left: 0;
top: -9999px;
background: #222;
}
.audioplayer-volume:not(:hover) .audioplayer-volume-adjust
{
opacity: 0;
}
.audioplayer-volume:hover .audioplayer-volume-adjust
{
top: auto;
bottom: 100%;
}
.audioplayer-volume-adjust > div
{
width: 40%;
height: 80%;
background-color: #555;
cursor: pointer;
position: relative;
z-index: 1;
margin: 30% auto 0;
}
.audioplayer-volume-adjust div div
{
width: 100%;
height: 100%;
position: absolute;
bottom: 0;
left: 0;
background: #007fd1;
}
.audioplayer-novolume .audioplayer-volume
{
display: none;
}

View File

@ -7,6 +7,7 @@ using Teknik.Areas.Contact.Models;
using Teknik.Migrations;
using Teknik.Areas.Upload.Models;
using Teknik.Areas.Paste.Models;
using Teknik.Areas.Podcast.Models;
namespace Teknik.Models
{
@ -18,14 +19,18 @@ namespace Teknik.Models
public DbSet<Role> Roles { get; set; }
// Blogs
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
public DbSet<Comment> BlogComments { get; set; }
public DbSet<BlogPost> BlogPosts { get; set; }
public DbSet<BlogPostComment> BlogComments { get; set; }
// Contact
public DbSet<Contact> Contact { get; set; }
// Uploads
public DbSet<Upload> Uploads { get; set; }
// Pastes
public DbSet<Paste> Pastes { get; set; }
// Podcasts
public DbSet<Podcast> Podcasts { get; set; }
public DbSet<PodcastFile> PodcastFiles { get; set; }
public DbSet<PodcastComment> PodcastComments { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
@ -33,11 +38,14 @@ namespace Teknik.Models
modelBuilder.Entity<Group>().ToTable("Groups");
modelBuilder.Entity<Role>().ToTable("Roles");
modelBuilder.Entity<Blog>().ToTable("Blogs");
modelBuilder.Entity<Post>().ToTable("Posts");
modelBuilder.Entity<Comment>().ToTable("BlogComments");
modelBuilder.Entity<BlogPost>().ToTable("BlogPosts");
modelBuilder.Entity<PodcastComment>().ToTable("BlogComments");
modelBuilder.Entity<Contact>().ToTable("Contact");
modelBuilder.Entity<Upload>().ToTable("Uploads");
modelBuilder.Entity<Paste>().ToTable("Pastes");
modelBuilder.Entity<Podcast>().ToTable("Podcasts");
modelBuilder.Entity<PodcastFile>().ToTable("PodcastFiles");
modelBuilder.Entity<PodcastComment>().ToTable("PodcastComments");
base.OnModelCreating(modelBuilder);
}

Binary file not shown.

6
Teknik/Scripts/audioplayer.min.js vendored Normal file
View File

@ -0,0 +1,6 @@
/*
By Osvaldas Valutis, www.osvaldas.info
Available for use under the MIT License
*/
(function(e,t,n,r){var i="ontouchstart"in t,s=i?"touchstart":"mousedown",o=i?"touchmove":"mousemove",u=i?"touchend":"mouseup",a=i?"touchcancel":"mouseup",f=function(e){var t=e/3600,n=Math.floor(t),r=e%3600/60,i=Math.floor(r),s=Math.ceil(e%3600%60);if(s>59){s=0;i=Math.ceil(r)}if(i>59){i=0;n=Math.ceil(t)}return(n==0?"":n>0&&n.toString().length<2?"0"+n+":":n+":")+(i.toString().length<2?"0"+i:i)+":"+(s.toString().length<2?"0"+s:s)},l=function(e){var t=n.createElement("audio");return!!(t.canPlayType&&t.canPlayType("audio/"+e.split(".").pop().toLowerCase()+";").replace(/no/,""))};e.fn.audioPlayer=function(t){var t=e.extend({classPrefix:"audioplayer",strPlay:"Play",strPause:"Pause",strVolume:"Volume"},t),n={},r={playPause:"playpause",playing:"playing",stopped:"stopped",time:"time",timeCurrent:"time-current",timeDuration:"time-duration",bar:"bar",barLoaded:"bar-loaded",barPlayed:"bar-played",volume:"volume",volumeButton:"volume-button",volumeAdjust:"volume-adjust",noVolume:"novolume",muted:"muted",mini:"mini"};for(var u in r)n[u]=t.classPrefix+"-"+r[u];this.each(function(){if(e(this).prop("tagName").toLowerCase()!="audio")return false;var r=e(this),u=r.attr("src"),c=r.get(0).getAttribute("autoplay"),c=c===""||c==="autoplay"?true:false,h=r.get(0).getAttribute("loop"),h=h===""||h==="loop"?true:false,p=false;if(typeof u==="undefined"){r.find("source").each(function(){u=e(this).attr("src");if(typeof u!=="undefined"&&l(u)){p=true;return false}})}else if(l(u))p=true;var d=e('<div class="'+t.classPrefix+'">'+(p?e("<div>").append(r.eq(0).clone()).html():'<embed src="'+u+'" width="0" height="0" volume="100" autostart="'+c.toString()+'" loop="'+h.toString()+'" />')+'<div class="'+n.playPause+'" title="'+t.strPlay+'"><a href="#">'+t.strPlay+"</a></div></div>"),v=p?d.find("audio"):d.find("embed"),v=v.get(0);if(p){d.find("audio").css({width:0,height:0,visibility:"hidden"});d.append('<div class="'+n.time+" "+n.timeCurrent+'"></div><div class="'+n.bar+'"><div class="'+n.barLoaded+'"></div><div class="'+n.barPlayed+'"></div></div><div class="'+n.time+" "+n.timeDuration+'"></div><div class="'+n.volume+'"><div class="'+n.volumeButton+'" title="'+t.strVolume+'"><a href="#">'+t.strVolume+'</a></div><div class="'+n.volumeAdjust+'"><div><div></div></div></div></div>');var m=d.find("."+n.bar),g=d.find("."+n.barPlayed),y=d.find("."+n.barLoaded),b=d.find("."+n.timeCurrent),w=d.find("."+n.timeDuration),E=d.find("."+n.volumeButton),S=d.find("."+n.volumeAdjust+" > div"),x=0,T=function(e){theRealEvent=i?e.originalEvent.touches[0]:e;v.currentTime=Math.round(v.duration*(theRealEvent.pageX-m.offset().left)/m.width())},N=function(e){theRealEvent=i?e.originalEvent.touches[0]:e;v.volume=Math.abs((theRealEvent.pageY-(S.offset().top+S.height()))/S.height())},C=function(){var e=setInterval(function(){if(v.buffered.length<1)return true;y.width(v.buffered.end(0)/v.duration*100+"%");if(Math.floor(v.buffered.end(0))>=Math.floor(v.duration))clearInterval(e)},100)};var k=v.volume,L=v.volume=.111;if(Math.round(v.volume*1e3)/1e3==L)v.volume=k;else d.addClass(n.noVolume);w.html("…");b.html(f(0));v.addEventListener("loadeddata",function(){C();w.html(e.isNumeric(v.duration)?f(v.duration):"…");S.find("div").height(v.volume*100+"%");x=v.volume});v.addEventListener("timeupdate",function(){b.html(f(v.currentTime));g.width(v.currentTime/v.duration*100+"%")});v.addEventListener("volumechange",function(){S.find("div").height(v.volume*100+"%");if(v.volume>0&&d.hasClass(n.muted))d.removeClass(n.muted);if(v.volume<=0&&!d.hasClass(n.muted))d.addClass(n.muted)});v.addEventListener("ended",function(){d.removeClass(n.playing).addClass(n.stopped)});m.on(s,function(e){T(e);m.on(o,function(e){T(e)})}).on(a,function(){m.unbind(o)});E.on("click",function(){if(d.hasClass(n.muted)){d.removeClass(n.muted);v.volume=x}else{d.addClass(n.muted);x=v.volume;v.volume=0}return false});S.on(s,function(e){N(e);S.on(o,function(e){N(e)})}).on(a,function(){S.unbind(o)})}else d.addClass(n.mini);d.addClass(c?n.playing:n.stopped);d.find("."+n.playPause).on("click",function(){if(d.hasClass(n.playing)){e(this).attr("title",t.strPlay).find("a").html(t.strPlay);d.removeClass(n.playing).addClass(n.stopped);p?v.pause():v.Stop()}else{e(this).attr("title",t.strPause).find("a").html(t.strPause);d.addClass(n.playing).removeClass(n.stopped);p?v.play():v.Play()}return false});r.replaceWith(d)});return this}})(jQuery,window,document);

1302
Teknik/Scripts/bootstrap-markdown.js vendored Normal file

File diff suppressed because it is too large Load Diff

1457
Teknik/Scripts/jquery.fileupload.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,214 @@
/*
* jQuery Iframe Transport Plugin 1.8.2
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2011, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
*/
/* global define, window, document */
(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define(['jquery'], factory);
} else {
// Browser globals:
factory(window.jQuery);
}
}(function ($) {
'use strict';
// Helper variable to create unique names for the transport iframes:
var counter = 0;
// The iframe transport accepts four additional options:
// options.fileInput: a jQuery collection of file input fields
// options.paramName: the parameter name for the file form data,
// overrides the name property of the file input field(s),
// can be a string or an array of strings.
// options.formData: an array of objects with name and value properties,
// equivalent to the return data of .serializeArray(), e.g.:
// [{name: 'a', value: 1}, {name: 'b', value: 2}]
// options.initialIframeSrc: the URL of the initial iframe src,
// by default set to "javascript:false;"
$.ajaxTransport('iframe', function (options) {
if (options.async) {
// javascript:false as initial iframe src
// prevents warning popups on HTTPS in IE6:
/*jshint scripturl: true */
var initialIframeSrc = options.initialIframeSrc || 'javascript:false;',
/*jshint scripturl: false */
form,
iframe,
addParamChar;
return {
send: function (_, completeCallback) {
form = $('<form style="display:none;"></form>');
form.attr('accept-charset', options.formAcceptCharset);
addParamChar = /\?/.test(options.url) ? '&' : '?';
// XDomainRequest only supports GET and POST:
if (options.type === 'DELETE') {
options.url = options.url + addParamChar + '_method=DELETE';
options.type = 'POST';
} else if (options.type === 'PUT') {
options.url = options.url + addParamChar + '_method=PUT';
options.type = 'POST';
} else if (options.type === 'PATCH') {
options.url = options.url + addParamChar + '_method=PATCH';
options.type = 'POST';
}
// IE versions below IE8 cannot set the name property of
// elements that have already been added to the DOM,
// so we set the name along with the iframe HTML markup:
counter += 1;
iframe = $(
'<iframe src="' + initialIframeSrc +
'" name="iframe-transport-' + counter + '"></iframe>'
).bind('load', function () {
var fileInputClones,
paramNames = $.isArray(options.paramName) ?
options.paramName : [options.paramName];
iframe
.unbind('load')
.bind('load', function () {
var response;
// Wrap in a try/catch block to catch exceptions thrown
// when trying to access cross-domain iframe contents:
try {
response = iframe.contents();
// Google Chrome and Firefox do not throw an
// exception when calling iframe.contents() on
// cross-domain requests, so we unify the response:
if (!response.length || !response[0].firstChild) {
throw new Error();
}
} catch (e) {
response = undefined;
}
// The complete callback returns the
// iframe content document as response object:
completeCallback(
200,
'success',
{'iframe': response}
);
// Fix for IE endless progress bar activity bug
// (happens on form submits to iframe targets):
$('<iframe src="' + initialIframeSrc + '"></iframe>')
.appendTo(form);
window.setTimeout(function () {
// Removing the form in a setTimeout call
// allows Chrome's developer tools to display
// the response result
form.remove();
}, 0);
});
form
.prop('target', iframe.prop('name'))
.prop('action', options.url)
.prop('method', options.type);
if (options.formData) {
$.each(options.formData, function (index, field) {
$('<input type="hidden"/>')
.prop('name', field.name)
.val(field.value)
.appendTo(form);
});
}
if (options.fileInput && options.fileInput.length &&
options.type === 'POST') {
fileInputClones = options.fileInput.clone();
// Insert a clone for each file input field:
options.fileInput.after(function (index) {
return fileInputClones[index];
});
if (options.paramName) {
options.fileInput.each(function (index) {
$(this).prop(
'name',
paramNames[index] || options.paramName
);
});
}
// Appending the file input fields to the hidden form
// removes them from their original location:
form
.append(options.fileInput)
.prop('enctype', 'multipart/form-data')
// enctype must be set as encoding for IE:
.prop('encoding', 'multipart/form-data');
// Remove the HTML5 form attribute from the input(s):
options.fileInput.removeAttr('form');
}
form.submit();
// Insert the file input fields at their original location
// by replacing the clones with the originals:
if (fileInputClones && fileInputClones.length) {
options.fileInput.each(function (index, input) {
var clone = $(fileInputClones[index]);
// Restore the original name and form properties:
$(input)
.prop('name', clone.prop('name'))
.attr('form', clone.attr('form'));
clone.replaceWith(input);
});
}
});
form.append(iframe).appendTo(document.body);
},
abort: function () {
if (iframe) {
// javascript:false as iframe src aborts the request
// and prevents warning popups on HTTPS in IE6.
// concat is used to avoid the "Script URL" JSLint error:
iframe
.unbind('load')
.prop('src', initialIframeSrc);
}
if (form) {
form.remove();
}
}
};
}
});
// The iframe transport returns the iframe content document as response.
// The following adds converters from iframe to text, json, html, xml
// and script.
// Please note that the Content-Type for JSON responses has to be text/plain
// or text/html, if the browser doesn't include application/json in the
// Accept header, else IE will show a download dialog.
// The Content-Type for XML responses on the other hand has to be always
// application/xml or text/xml, so IE properly parses the XML response.
// See also
// https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#content-type-negotiation
$.ajaxSetup({
converters: {
'iframe text': function (iframe) {
return iframe && $(iframe[0].body).text();
},
'iframe json': function (iframe) {
return iframe && $.parseJSON($(iframe[0].body).text());
},
'iframe html': function (iframe) {
return iframe && $(iframe[0].body).html();
},
'iframe xml': function (iframe) {
var xmlDoc = iframe && iframe[0];
return xmlDoc && $.isXMLDoc(xmlDoc) ? xmlDoc :
$.parseXML((xmlDoc.XMLDocument && xmlDoc.XMLDocument.xml) ||
$(xmlDoc.body).html());
},
'iframe script': function (iframe) {
return iframe && $.globalEval($(iframe[0].body).text());
}
}
});
}));

View File

@ -151,7 +151,7 @@
<Compile Include="Areas\API\Controllers\APIController.cs" />
<Compile Include="Areas\API\Controllers\APIv1Controller.cs" />
<Compile Include="Areas\Blog\BlogAreaRegistration.cs" />
<Compile Include="Areas\Blog\Models\Comment.cs" />
<Compile Include="Areas\Blog\Models\BlogPostComment.cs" />
<Compile Include="Areas\Blog\ViewModels\BlogViewModel.cs" />
<Compile Include="Areas\Blog\ViewModels\CommentViewModel.cs" />
<Compile Include="Areas\Blog\ViewModels\PostViewModel.cs" />
@ -176,6 +176,14 @@
<Compile Include="Areas\Paste\PasteAreaRegistration.cs" />
<Compile Include="Areas\Paste\ViewModels\PasswordViewModel.cs" />
<Compile Include="Areas\Paste\ViewModels\PasteViewModel.cs" />
<Compile Include="Areas\Podcast\Controllers\PodcastController.cs" />
<Compile Include="Areas\Podcast\Models\PodcastComment.cs" />
<Compile Include="Areas\Podcast\Models\Podcast.cs" />
<Compile Include="Areas\Podcast\Models\PodcastFile.cs" />
<Compile Include="Areas\Podcast\PodcastAreaRegistration.cs" />
<Compile Include="Areas\Podcast\ViewModels\CommentViewModel.cs" />
<Compile Include="Areas\Podcast\ViewModels\MainViewModel.cs" />
<Compile Include="Areas\Podcast\ViewModels\PodcastViewModel.cs" />
<Compile Include="Areas\Privacy\Controllers\PrivacyController.cs" />
<Compile Include="Areas\Privacy\PrivacyAreaRegistration.cs" />
<Compile Include="Areas\Privacy\ViewModels\PrivacyViewModel.cs" />
@ -191,6 +199,7 @@
<Compile Include="Areas\Upload\ViewModels\DownloadViewModel.cs" />
<Compile Include="Areas\Upload\ViewModels\UploadViewModel.cs" />
<Compile Include="Configuration\ApiConfig.cs" />
<Compile Include="Configuration\PodcastConfig.cs" />
<Compile Include="Configuration\BlogConfig.cs" />
<Compile Include="Configuration\Config.cs" />
<Compile Include="Areas\Blog\Controllers\BlogController.cs" />
@ -207,7 +216,7 @@
<Compile Include="Areas\Profile\Models\Group.cs" />
<Compile Include="Areas\Profile\Models\PermissionTarget.cs" />
<Compile Include="Areas\Profile\Models\PermissionType.cs" />
<Compile Include="Areas\Blog\Models\Post.cs" />
<Compile Include="Areas\Blog\Models\BlogPost.cs" />
<Compile Include="Areas\Profile\Models\Role.cs" />
<Compile Include="Helpers\UrlExtensions.cs" />
<Compile Include="Helpers\Utility.cs" />
@ -233,8 +242,11 @@
<Content Include="Areas\Paste\Content\Paste.css" />
<Content Include="Areas\Paste\Scripts\Paste.js" />
<Content Include="Areas\Paste\Scripts\SyntaxWorker.js" />
<Content Include="Areas\Podcast\Content\Podcast.css" />
<Content Include="Areas\Podcast\Scripts\Podcast.js" />
<Content Include="Areas\Profile\Scripts\Profile.js" />
<Content Include="Areas\Upload\Scripts\Download.js" />
<Content Include="Content\audioplayer.css" />
<Content Include="Content\Highlight\agate.css" />
<Content Include="Content\Highlight\androidstudio.css" />
<Content Include="Content\Highlight\arduino-light.css" />
@ -305,7 +317,9 @@
<Content Include="Content\Highlight\xcode.css" />
<Content Include="Content\Highlight\zenburn.css" />
<Content Include="Content\jquery.tocify.css" />
<Content Include="Scripts\audioplayer.min.js" />
<Content Include="Scripts\Blob.js" />
<Content Include="Scripts\bootstrap-markdown.js" />
<Content Include="Scripts\Crypto-js\aes.js" />
<Content Include="Areas\Upload\Scripts\EncryptionWorker.js" />
<Content Include="Areas\Upload\Scripts\Upload.js" />
@ -400,6 +414,14 @@
<Content Include="Areas\Error\Views\Error\Http403.cshtml" />
<Content Include="Areas\Paste\Views\Paste\Simple.cshtml" />
<Content Include="Areas\Help\Views\Help\API\v1\Paste.cshtml" />
<Content Include="Areas\Podcast\Views\web.config" />
<Content Include="Areas\Podcast\Views\_ViewStart.cshtml" />
<Content Include="Areas\Podcast\Views\Podcast\Main.cshtml" />
<Content Include="Areas\Podcast\Views\Podcast\Podcast.cshtml" />
<Content Include="Areas\Podcast\Views\Podcast\Podcasts.cshtml" />
<Content Include="Areas\Podcast\Views\Podcast\Comment.cshtml" />
<Content Include="Areas\Podcast\Views\Podcast\Comments.cshtml" />
<Content Include="Areas\Podcast\Views\Podcast\ViewPodcast.cshtml" />
<None Include="Properties\PublishProfiles\Teknik Dev.pubxml" />
<None Include="Scripts\jquery-2.1.4.intellisense.js" />
<Content Include="Scripts\bootbox\bootbox.min.js" />
@ -422,6 +444,8 @@
<None Include="Scripts\jquery.validate-vsdoc.js" />
<Content Include="Scripts\jquery-ui.widgets.js" />
<Content Include="Scripts\jquery.blockUI.js" />
<Content Include="Scripts\jquery.fileupload.js" />
<Content Include="Scripts\jquery.iframe-transport.js" />
<Content Include="Scripts\jquery.tocify.min.js" />
<Content Include="Scripts\jquery.validate.js" />
<Content Include="Scripts\jquery.validate.min.js" />
@ -474,6 +498,7 @@
<Folder Include="Areas\Home\Models\" />
<Folder Include="Areas\Home\Views\Shared\" />
<Folder Include="Areas\Paste\Views\Shared\" />
<Folder Include="Areas\Podcast\Views\Shared\" />
<Folder Include="Areas\Privacy\Models\" />
<Folder Include="Areas\Privacy\Views\Shared\" />
<Folder Include="Areas\Profile\Views\Shared\" />