@@ -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 |
@@ -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); |
@@ -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; } | |||
} | |||
} |
@@ -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; } | |||
} | |||
} |
@@ -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; } | |||
@@ -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; |
@@ -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; |
@@ -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 /> |
@@ -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; |
@@ -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; } | |||
} | |||
} |
@@ -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; | |||
} |
@@ -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 | |||
} | |||
} |
@@ -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; } | |||
} | |||
} |
@@ -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; } | |||
} | |||
} |
@@ -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; } | |||
} | |||
} |
@@ -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")); | |||
} | |||
} | |||
} |
@@ -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">×</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">×</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">×</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">×</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">×</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">×</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">×</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">×</button>' + html.error + '</div>'); | |||
} | |||
} | |||
}); | |||
} | |||
}); | |||
}); | |||
} | |||
function linkAudioPlayer(selector) { | |||
$(selector).audioPlayer( | |||
{ | |||
classPrefix: 'audioplayer' | |||
}); | |||
} |
@@ -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; | |||
} | |||
} | |||
} |
@@ -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; } | |||
} | |||
} |
@@ -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; | |||
} | |||
} | |||
} |
@@ -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> |
@@ -0,0 +1,6 @@ | |||
@model List<Teknik.Areas.Podcast.ViewModels.CommentViewModel> | |||
@foreach (var comment in Model) | |||
{ | |||
@Html.Partial("Comment", comment) | |||
} |
@@ -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">×</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">×</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> |
@@ -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> |
@@ -0,0 +1,6 @@ | |||
@model List<Teknik.Areas.Podcast.ViewModels.PodcastViewModel> | |||
@foreach (var podcast in Model) | |||
{ | |||
@Html.Partial("Podcast", podcast) | |||
} |
@@ -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">×</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">×</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">×</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> |
@@ -0,0 +1,3 @@ | |||
@{ | |||
Layout = "~/Views/Shared/_Layout.cshtml"; | |||
} |
@@ -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> |
@@ -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; | |||
} |
@@ -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; | |||
} | |||
} | |||
} |
@@ -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; | |||
} |
@@ -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); | |||
} |
@@ -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); |
@@ -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 | |||
*/ | |||