Browse Source

Initial Podcast creation.

Renamed some Blog objects
tags/2.0.3
Teknikode 3 years ago
parent
commit
c48bfc3be9
38 changed files with 4648 additions and 69 deletions
  1. 1
    1
      Teknik/Areas/Blog/BlogAreaRegistration.cs
  2. 25
    25
      Teknik/Areas/Blog/Controllers/BlogController.cs
  3. 1
    1
      Teknik/Areas/Blog/Models/Blog.cs
  4. 3
    3
      Teknik/Areas/Blog/Models/BlogPost.cs
  5. 4
    4
      Teknik/Areas/Blog/Models/BlogPostComment.cs
  6. 5
    5
      Teknik/Areas/Blog/ViewModels/CommentViewModel.cs
  7. 3
    3
      Teknik/Areas/Blog/ViewModels/PostViewModel.cs
  8. 1
    1
      Teknik/Areas/Blog/Views/Blog/Post.cshtml
  9. 5
    5
      Teknik/Areas/Home/Controllers/HomeController.cs
  10. 3
    3
      Teknik/Areas/Home/ViewModels/HomeViewModel.cs
  11. 80
    0
      Teknik/Areas/Podcast/Content/Podcast.css
  12. 276
    0
      Teknik/Areas/Podcast/Controllers/PodcastController.cs
  13. 30
    0
      Teknik/Areas/Podcast/Models/Podcast.cs
  14. 25
    0
      Teknik/Areas/Podcast/Models/PodcastComment.cs
  15. 24
    0
      Teknik/Areas/Podcast/Models/PodcastFile.cs
  16. 58
    0
      Teknik/Areas/Podcast/PodcastAreaRegistration.cs
  17. 280
    0
      Teknik/Areas/Podcast/Scripts/Podcast.js
  18. 29
    0
      Teknik/Areas/Podcast/ViewModels/CommentViewModel.cs
  19. 17
    0
      Teknik/Areas/Podcast/ViewModels/MainViewModel.cs
  20. 45
    0
      Teknik/Areas/Podcast/ViewModels/PodcastViewModel.cs
  21. 30
    0
      Teknik/Areas/Podcast/Views/Podcast/Comment.cshtml
  22. 6
    0
      Teknik/Areas/Podcast/Views/Podcast/Comments.cshtml
  23. 138
    0
      Teknik/Areas/Podcast/Views/Podcast/Main.cshtml
  24. 50
    0
      Teknik/Areas/Podcast/Views/Podcast/Podcast.cshtml
  25. 6
    0
      Teknik/Areas/Podcast/Views/Podcast/Podcasts.cshtml
  26. 135
    0
      Teknik/Areas/Podcast/Views/Podcast/ViewPodcast.cshtml
  27. 3
    0
      Teknik/Areas/Podcast/Views/_ViewStart.cshtml
  28. 36
    0
      Teknik/Areas/Podcast/Views/web.config
  29. 17
    12
      Teknik/Configuration/Config.cs
  30. 28
    0
      Teknik/Configuration/PodcastConfig.cs
  31. 266
    0
      Teknik/Content/audioplayer.css
  32. 12
    4
      Teknik/Models/TeknikEntities.cs
  33. BIN
      Teknik/Scripts/_references.js
  34. 6
    0
      Teknik/Scripts/audioplayer.min.js
  35. 1302
    0
      Teknik/Scripts/bootstrap-markdown.js
  36. 1457
    0
      Teknik/Scripts/jquery.fileupload.js
  37. 214
    0
      Teknik/Scripts/jquery.iframe-transport.js
  38. 27
    2
      Teknik/Teknik.csproj

+ 1
- 1
Teknik/Areas/Blog/BlogAreaRegistration.cs 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

+ 25
- 25
Teknik/Areas/Blog/Controllers/BlogController.cs 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);

+ 1
- 1
Teknik/Areas/Blog/Models/Blog.cs 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; }
}
}

Teknik/Areas/Blog/Models/Post.cs → Teknik/Areas/Blog/Models/BlogPost.cs 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; }
}
}

Teknik/Areas/Blog/Models/Comment.cs → Teknik/Areas/Blog/Models/BlogPostComment.cs 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; }


+ 5
- 5
Teknik/Areas/Blog/ViewModels/CommentViewModel.cs 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;

+ 3
- 3
Teknik/Areas/Blog/ViewModels/PostViewModel.cs 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;

+ 1
- 1
Teknik/Areas/Blog/Views/Blog/Post.cshtml 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 />

+ 5
- 5
Teknik/Areas/Home/Controllers/HomeController.cs 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;

+ 3
- 3
Teknik/Areas/Home/ViewModels/HomeViewModel.cs 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; }
}
}

+ 80
- 0
Teknik/Areas/Podcast/Content/Podcast.css 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;
}

+ 276
- 0
Teknik/Areas/Podcast/Controllers/PodcastController.cs 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
}
}

+ 30
- 0
Teknik/Areas/Podcast/Models/Podcast.cs 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; }
}
}

+ 25
- 0
Teknik/Areas/Podcast/Models/PodcastComment.cs 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; }
}
}

+ 24
- 0
Teknik/Areas/Podcast/Models/PodcastFile.cs 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; }
}
}

+ 58
- 0
Teknik/Areas/Podcast/PodcastAreaRegistration.cs 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"));
}
}
}

+ 280
- 0
Teknik/Areas/Podcast/Scripts/Podcast.js 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'
});
}

+ 29
- 0
Teknik/Areas/Podcast/ViewModels/CommentViewModel.cs 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;
}
}
}

+ 17
- 0
Teknik/Areas/Podcast/ViewModels/MainViewModel.cs 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; }
}
}

+ 45
- 0
Teknik/Areas/Podcast/ViewModels/PodcastViewModel.cs 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;
}
}
}

+ 30
- 0
Teknik/Areas/Podcast/Views/Podcast/Comment.cshtml 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>

+ 6
- 0
Teknik/Areas/Podcast/Views/Podcast/Comments.cshtml View File

@@ -0,0 +1,6 @@
@model List<Teknik.Areas.Podcast.ViewModels.CommentViewModel>

@foreach (var comment in Model)
{
@Html.Partial("Comment", comment)
}

+ 138
- 0
Teknik/Areas/Podcast/Views/Podcast/Main.cshtml 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>

+ 50
- 0
Teknik/Areas/Podcast/Views/Podcast/Podcast.cshtml 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>

+ 6
- 0
Teknik/Areas/Podcast/Views/Podcast/Podcasts.cshtml View File

@@ -0,0 +1,6 @@
@model List<Teknik.Areas.Podcast.ViewModels.PodcastViewModel>

@foreach (var podcast in Model)
{
@Html.Partial("Podcast", podcast)
}

+ 135
- 0
Teknik/Areas/Podcast/Views/Podcast/ViewPodcast.cshtml 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>

+ 3
- 0
Teknik/Areas/Podcast/Views/_ViewStart.cshtml View File

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

+ 36
- 0
Teknik/Areas/Podcast/Views/web.config 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>

+ 17
- 12
Teknik/Configuration/Config.cs 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;
}

+ 28
- 0
Teknik/Configuration/PodcastConfig.cs 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;
}
}
}

+ 266
- 0
Teknik/Content/audioplayer.css 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;
}

+ 12
- 4
Teknik/Models/TeknikEntities.cs 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);
}

BIN
Teknik/Scripts/_references.js View File


+ 6
- 0
Teknik/Scripts/audioplayer.min.js 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
- 0
Teknik/Scripts/bootstrap-markdown.js
File diff suppressed because it is too large
View File


+ 1457
- 0
Teknik/Scripts/jquery.fileupload.js
File diff suppressed because it is too large
View File


+ 214
- 0
Teknik/Scripts/jquery.iframe-transport.js 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
*/