mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Smoothing over some MediaPicker rough edges.
- Can now upload images to a specific folder - Can now create folders in gallery tab - Images are scaled before drawn - Added throbber on image uploads - Clicking image ensures Chrome displays the image instead of downloads it - After uploading image the image is selected --HG-- branch : dev
This commit is contained in:
@@ -1,13 +1,17 @@
|
||||
using System;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.Localization;
|
||||
using Orchard;
|
||||
using System.Collections.Generic;
|
||||
using Orchard.Media;
|
||||
using Orchard.Media.Models;
|
||||
using Orchard.Media.ViewModels;
|
||||
using Orchard.Media.Services;
|
||||
using Orchard.Security;
|
||||
using Orchard.UI.Admin;
|
||||
using Orchard.Themes;
|
||||
using Orchard.UI.Notify;
|
||||
|
||||
namespace Orchard.MediaPicker.Controllers {
|
||||
[Themed(false)]
|
||||
@@ -42,5 +46,23 @@ namespace Orchard.MediaPicker.Controllers {
|
||||
ViewData["Service"] = _mediaService;
|
||||
return View(model);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public JsonResult CreateFolder(string path, string folderName) {
|
||||
if (!_authorizer.Authorize(StandardPermissions.AccessAdminPanel)) {
|
||||
return Json(T("Can't access the admin").ToString());
|
||||
}
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageMedia)) {
|
||||
return Json(T("Couldn't create media folder").ToString());
|
||||
}
|
||||
|
||||
try {
|
||||
_mediaService.CreateFolder(HttpUtility.UrlDecode(path), folderName);
|
||||
return Json(true);
|
||||
}
|
||||
catch (Exception exception) {
|
||||
return Json(T("Creating Folder failed: {0}", exception.Message).ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -58,6 +58,7 @@
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Content\synchronizing.gif" />
|
||||
<Content Include="Scripts\MediaBrowser.js" />
|
||||
<Content Include="Scripts\MediaPicker.js" />
|
||||
<Content Include="Styles\mediapicker.css" />
|
||||
@@ -97,6 +98,9 @@
|
||||
<ItemGroup>
|
||||
<Content Include="Views\Tab_Gallery.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Content\Web.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
|
@@ -44,13 +44,52 @@
|
||||
publishInsertEvent(this);
|
||||
});
|
||||
|
||||
$(".media-filename").live("click", function (ev) {
|
||||
// when clicking on a filename in the gallery view,
|
||||
// we interrupt the normal operation and write a <img>
|
||||
// tag into a new window to ensure the image displays in
|
||||
// a new window instead of being 'downloaded' like in Chrome
|
||||
ev.preventDefault();
|
||||
var self = $(this),
|
||||
src = attributeEncode(self.attr("href")),
|
||||
w = window.open("", self.attr("target"));
|
||||
w.document.write("<!DOCTYPE html><html><head><title>" + src + "</title></head><body><img src=\"" + src + "\" alt=\"\" /></body></html>");
|
||||
});
|
||||
|
||||
$("#createFolder").live("click", function () {
|
||||
$.post("MediaPicker/Home/CreateFolder", { path: query("mediaPath"), folderName: $("#folderName").val(), __RequestVerificationToken: $("#__requesttoken").val() },
|
||||
function (response) {
|
||||
if (typeof response === "string") {
|
||||
alert(response);
|
||||
}
|
||||
else {
|
||||
location.reload(true);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(function () {
|
||||
$("#tabs").tabs({ selected: parseInt(location.hash.replace("#", "")) || 0 });
|
||||
$("#tabs").tabs({ selected: parseInt(query("tab", location.hash)) || 0 });
|
||||
|
||||
// populate width and height when image loads
|
||||
// note: load event does not bubble so cannot be used with .live
|
||||
$("#img-loader, #lib-loader").bind("load", syncImage);
|
||||
|
||||
$("#lib-uploadform").bind("uploadComplete", function (ev, url) {
|
||||
// from the libary view, uploading should cause a reload
|
||||
var href = location.href,
|
||||
hashindex = location.href.indexOf("#");
|
||||
if (hashindex !== -1) {
|
||||
href = href.substr(0, hashindex);
|
||||
}
|
||||
location.href = href + "&rl=" + (new Date() - 0) + "#tab=1&select=" + url.substr(url.lastIndexOf("/") + 1);
|
||||
});
|
||||
|
||||
var preselect = query("select", location.hash);
|
||||
if (preselect) {
|
||||
$("img[data-filename=" + preselect + "]").closest(".media-item").trigger("click");
|
||||
}
|
||||
|
||||
// edit mode has slightly different wording
|
||||
// elements advertise this with data-edittext attributes,
|
||||
// the edit text is the element's new val() unless -content is specified.
|
||||
@@ -76,7 +115,13 @@
|
||||
});
|
||||
|
||||
function selectImage(prefix, src) {
|
||||
$(prefix + "preview").width("").height("").attr("src", src);
|
||||
$(prefix + "preview")
|
||||
.css({
|
||||
display: "none",
|
||||
width: "",
|
||||
height: ""
|
||||
})
|
||||
.attr("src", src);
|
||||
$(prefix + "loader").attr("src", src);
|
||||
$(prefix + "src").val(src);
|
||||
|
||||
@@ -150,7 +195,12 @@
|
||||
height = maxHeight;
|
||||
width = Math.round(width * aspect);
|
||||
}
|
||||
self.width(width).height(height);
|
||||
|
||||
self.css({
|
||||
width: width,
|
||||
height: height,
|
||||
display: "inline"
|
||||
});
|
||||
}
|
||||
|
||||
function syncImage() {
|
||||
@@ -170,11 +220,15 @@
|
||||
suppressResize = false;
|
||||
}
|
||||
|
||||
function attributeEncode(value) {
|
||||
return !value ? "" : value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">").replace(/\//g, "/");
|
||||
}
|
||||
|
||||
function getAttr(name, value) {
|
||||
// get an attribute value, escaping any necessary characters to html entities.
|
||||
// not an exhastive list, but should cover all the necessary characters for this UI (e.g. you can't really put in newlines).
|
||||
if (!value && name !== "alt") return "";
|
||||
return ' ' + name + '="' + value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">") + '"';
|
||||
return ' ' + name + '="' + attributeEncode(value) + '"';
|
||||
}
|
||||
|
||||
function getImageHtml(data) {
|
||||
@@ -188,21 +242,24 @@
|
||||
}
|
||||
|
||||
function uploadMedia(form) {
|
||||
var name = "addmedia__" + (new Date()).getTime();
|
||||
var name = "addmedia__" + (new Date()).getTime(),
|
||||
prefix = getIdPrefix(form);
|
||||
$("<iframe/>", {
|
||||
id: prefix.substr(1) + "iframe",
|
||||
name: name,
|
||||
src: "about:blank",
|
||||
css: { display: "none" },
|
||||
load: iframeLoadHandler
|
||||
}).appendTo(document.body);
|
||||
}).appendTo(form);
|
||||
form.target = name;
|
||||
$(prefix + "indicator").show();
|
||||
}
|
||||
|
||||
// get a querystring value
|
||||
function query(name) {
|
||||
function query(name, querystring) {
|
||||
name = name.toLowerCase();
|
||||
var search = location.search;
|
||||
var parts = search.replace("?", "").split("&");
|
||||
var search = querystring || location.search;
|
||||
var parts = search.replace("?", "").replace("#", "").split("&");
|
||||
for (var i = 0, l = parts.length; i < l; i++) {
|
||||
var part = parts[i];
|
||||
var eqIndex = part.indexOf("=");
|
||||
@@ -216,16 +273,15 @@
|
||||
function iframeLoadHandler() {
|
||||
try {
|
||||
var self = $(this),
|
||||
form = self.closest("form"),
|
||||
frame = window.frames[this.name];
|
||||
if (!frame.document || frame.document.URL == "about:blank") {
|
||||
return true;
|
||||
}
|
||||
var result = frame.result;
|
||||
if (result && result.url) {
|
||||
// successfully uploaded image, response by setting the url
|
||||
// to the new image. The change event will respond just as if
|
||||
// the user typed the url.
|
||||
$("#img-src").val(result.url).trigger("change");
|
||||
selectImage(getIdPrefix(this), result.url);
|
||||
form.trigger("uploadComplete", [result.url]);
|
||||
}
|
||||
else if (result && result.error) {
|
||||
alert(result.error);
|
||||
@@ -241,7 +297,7 @@
|
||||
alert(somethingPotentiallyHorrible);
|
||||
}
|
||||
}
|
||||
|
||||
$(getIdPrefix(form.get(0)) + "indicator").hide();
|
||||
//cleanup
|
||||
window.setTimeout(function () {
|
||||
self.remove();
|
||||
|
@@ -18,8 +18,14 @@ input[type="file"] {
|
||||
{
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
display: none; /*revealed by javascript after scaling*/
|
||||
}
|
||||
.selected
|
||||
{
|
||||
background-color: Yellow;
|
||||
}
|
||||
|
||||
.throbber
|
||||
{
|
||||
display: none
|
||||
}
|
@@ -7,7 +7,7 @@
|
||||
@helper FolderLink(string folderName, string mediaPath) {
|
||||
// querystring values need to persist after a new GET when clicking on the media browser's
|
||||
// folders for navigation.
|
||||
@Html.ActionLink(folderName, "Index", null, null, null, "1", new {
|
||||
@Html.ActionLink(folderName, "Index", null, null, null, "tab=1", new {
|
||||
upload = Request["upload"],
|
||||
uploadpath = Request["uploadpath"],
|
||||
editmode = Request["editmode"],
|
||||
@@ -15,6 +15,13 @@
|
||||
editorId = Request["editorId"],
|
||||
name = folderName,
|
||||
mediaPath = mediaPath }, null);
|
||||
}
|
||||
@{
|
||||
// only allow uploading to a local url
|
||||
var uploadAction = Request["upload"];
|
||||
if (!Url.IsLocalUrl(uploadAction)) {
|
||||
uploadAction = "";
|
||||
}
|
||||
}
|
||||
<div style="float:left">
|
||||
|
||||
@@ -24,9 +31,14 @@
|
||||
<text>></text> @FolderLink(navigation.FolderName, navigation.FolderPath)
|
||||
}
|
||||
</p>
|
||||
<fieldset>
|
||||
<input id="__requesttoken" type="hidden" value="@Html.AntiForgeryTokenValueOrchard()" />
|
||||
<input id="folderName" type="text" />
|
||||
<input type="button" id="createFolder" value="@T("Create Folder")" />
|
||||
</fieldset>
|
||||
</div>
|
||||
<fieldset>
|
||||
<table class="items" summary="@T("This is a table of the pages currently available for use in your application.")">
|
||||
<table class="items" summary="@T("This is a table of the images currently available for use in your application.")">
|
||||
@foreach (var mediaFolder in Model.MediaFolders) {
|
||||
<tr>
|
||||
<td>
|
||||
@@ -42,12 +54,12 @@
|
||||
<tr data-imgsrc="@src" class="media-item">
|
||||
<td>
|
||||
<div class="media-thumbnail">
|
||||
<img alt="" src="@src" onload="jQuery.mediaPicker.scalePreview(this)" />
|
||||
<img data-filename="@src.Substring(src.LastIndexOf("/") + 1)" alt="" src="@src" onload="jQuery.mediaPicker.scalePreview(this)" />
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul class="media-summary">
|
||||
<li><a href="@src" target="_blank">@mediaFile.Name</a></li>
|
||||
<li><a class="media-filename" href="@src" target="_blank">@mediaFile.Name</a></li>
|
||||
<li>@T("Added on"): @mediaFile.LastUpdated</li>
|
||||
<li>@T("Size"): @mediaFile.Size.ToFriendlySizeString()</li>
|
||||
</ul>
|
||||
@@ -55,6 +67,17 @@
|
||||
</tr>
|
||||
}
|
||||
</table>
|
||||
@if (!String.IsNullOrWhiteSpace(Model.MediaPath)) {
|
||||
using (Html.BeginFormAntiForgeryPost(uploadAction, FormMethod.Post, new { id="lib-uploadform", enctype = "multipart/form-data", onsubmit = "jQuery.mediaPicker.uploadMedia(this)" })) {
|
||||
<input type="hidden" name="MediaPath" value="@Model.MediaPath" />
|
||||
<label for="fileUpload">@T("Upload an image from your computer")</label>
|
||||
<input type="file" name="fileUpload" id="fileUpload" />
|
||||
<input type="submit" id="upload" value="Upload" />
|
||||
}
|
||||
}
|
||||
<img id="lib-indicator" src="@Url.Content("~/modules/orchard.mediapicker/content/synchronizing.gif")" alt="" class="throbber" />
|
||||
|
||||
|
||||
</fieldset>
|
||||
|
||||
</div>
|
||||
|
@@ -25,12 +25,13 @@
|
||||
<input type="text" id="img-src" />
|
||||
</div>
|
||||
<div>
|
||||
@using(Html.BeginFormAntiForgeryPost(uploadAction, FormMethod.Post, new { enctype = "multipart/form-data", onsubmit="jQuery.mediaPicker.uploadMedia(this)"})) {
|
||||
@using(Html.BeginFormAntiForgeryPost(uploadAction, FormMethod.Post, new { id = "img-uploadform", enctype = "multipart/form-data", onsubmit="jQuery.mediaPicker.uploadMedia(this)"})) {
|
||||
<input type="hidden" name="MediaPath" value="@mediaPath" />
|
||||
<label for="fileUpload">@T("Upload an image from your computer")</label>
|
||||
<input type="file" name="fileUpload" id="fileUpload" />
|
||||
<input type="submit" id="upload" value="Upload" />
|
||||
}
|
||||
<img id="img-indicator" src="@Url.Content("~/modules/orchard.mediapicker/content/synchronizing.gif")" alt="" class="throbber" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
Reference in New Issue
Block a user