Merge branch 'master' into 'master'

add new feature:1.recreate thumb, 2.crop images



See merge request !1
This commit is contained in:
wmcheng 2019-09-27 16:33:06 +08:00
commit 95468cc6c9
33 changed files with 6559 additions and 151 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

File diff suppressed because it is too large Load Diff

View File

@ -7,13 +7,13 @@
$this = this;
$li = this.children('li');
$dropzone = $('#dropzone');
if(($li.length - _set.onlyOne) == 0) {
if(($li.length - _set.onlyOne) === 0) {
$('#dropzone').fadeIn(300);
} else {
$('#dropzone').fadeOut(300);
};
}
$('#file-list').nanoScroller({ scrollTop: 0, iOSNativeScrolling: true });
}
};
}(window.jQuery);
$(function () {
@ -21,7 +21,7 @@ $(function () {
// Initialize the jQuery File Upload widget:
if($('#fileupload').length){
$('#fileupload').fileupload({
maxFileSize: 5000000,
//maxFileSize: 5000000,=
acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
dropZone: $('#dropzone'),
headers:{
@ -30,8 +30,96 @@ $(function () {
});
}
});
function batch_crop(){
var check_li = $('#imgholder').find("input[type='checkbox']:checked").parents('li');
var image_ids =[];
if (check_li.length>0){
check_li.each(function(){
image_ids.push($(this).data('image-id'));
});
if (navigator.onLine) {
window.location.href = '/admin/galleries/batch_crop?image_ids=' + image_ids.join(',')
} else {
alert('Please connect the network and try again later!')
}
}else{
alert('Please select at least one')
}
}
function select_all() {
$('#imgholder').find("input[type='checkbox']:not(:checked)").trigger('click')
}
function translate(ele,pretext,text){
if (navigator.onLine) {
$.ajax({
url : "/admin/galleries/translate",
dataType : "json",
type : "post",
data:{text:text},
success:function(data){
ele.html(pretext + data.translate)
},
error:function(){
var back = text.split('.')[1].split('_')
var result = []
for (i=0;i<back.length;i++){
result.push(back[i].charAt(0).toUpperCase() + back[i].slice(1))
}
ele.html(pretext + result.join(' '))
alert('Your server has some problem, please try again later!')
}
})
} else {
var back = text.split('.')[1].split('_')
var result = []
for (i=0;i<back.length;i++){
result.push(back[i].charAt(0).toUpperCase() + back[i].slice(1))
}
ele.html(pretext + result.join(' '))
alert('Please connect the network and try again later!')
}
}
$(function() {
var length_upload
var count_upload
var send_start
$( 'form#fileupload' ).ajaxSuccess(function() {
if (typeof length_upload == "undefined"){
count_upload = 1
length_upload = $('#file-list').find('li.template-upload').length
}
else{
count_upload ++
}
if (count_upload === length_upload){
send_start = undefined
$.ajax({
url : "/admin/galleries/start_upload_process",
dataType : "json",
type : "post",
error: function(){
alert('init upload process failed, please try again later.')
},
success: function(){
window.location.href = '/admin/galleries/upload_process'
}
})
}
});
$( 'form#fileupload' ).ajaxSend(function() {
if (typeof send_start == "undefined"){
send_start = 1
$.ajax({
url : "/admin/galleries/init_upload",
dataType : "json",
type : "post",
error : function(data){
alert('init upload process failed, please try again later.')
}
})
}
});
var $container = $('.gallery'),
$containerData = $container.data();
$container.data("order-edit","0");
@ -201,7 +289,7 @@ $(function() {
$('#imgholder').on(clickEvent, '.checkbox', function() {
$(this).prop('checked') ? $(this).closest('.rgalbum').addClass('active') : $(this).closest('.rgalbum').removeClass('active');
var checkLength = $("#imgholder .rgalbum.active");
checkLength.length ? $('.deletephoto, .deselect, .addtags').removeClass('hide') : $('.deletephoto, .deselect, .addtags').addClass('hide');
checkLength.length ? $('.deletephoto, .deselect, .addtags, .crop').removeClass('hide') : $('.deletephoto, .deselect, .addtags, .crop').addClass('hide');
});
$('.deselect').on(clickEvent, function(event) {
$('.rgalbum').removeClass('active');
@ -222,7 +310,7 @@ $(function() {
$(".order-edit-notification").slideDown();
images_order = $container.sortable( "toArray", { attribute: "data-image-id" });
$container.data("order-edit","1");
el.text("Save Order");
translate(el,'','gallery.save_order')
}else{
var temp = $container.sortable( "toArray", { attribute: "data-image-id" }),
type = $container.attr("id");
@ -237,7 +325,7 @@ $(function() {
$(".order-edit-notification").slideUp();
$container.sortable("disable");
$container.data("order-edit","0");
el.text("Edit Order");
translate(el,'','gallery.edit_order')
}
return false;
})
@ -249,7 +337,7 @@ $(function() {
click: function() {
$('#fileupload').slideToggle(300, function() {
if(!$(this).is(':hidden')) {
$('.add-imgs').html('<i class="icons-cross-2"></i> Close panel');
translate($('.add-imgs'),'<i class="icons-cross-2"></i> ','gallery.close_panel')
$('.rgbody').stop(true, false).animate({'padding-bottom': 280}, 300);
$("#edit-order-btn").hide();
$.ajax({
@ -261,7 +349,7 @@ $(function() {
last_image_id = d.last_image_id;
})
} else {
$('.add-imgs').html('<i class="icons-plus"></i> Add Image');
translate($('.add-imgs'),'<i class="icons-plus"></i> ','gallery.add_image')
$('.files').empty()
$('#file-list').checkListLength();
$('.rgbody').stop(true, false).animate({'padding-bottom': 0}, 300);

View File

@ -0,0 +1,75 @@
/*!
* jQuery Cropper v1.0.0
* https://github.com/fengyuanchen/jquery-cropper
*
* Copyright (c) 2018 Chen Fengyuan
* Released under the MIT license
*
* Date: 2018-04-01T06:20:13.168Z
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('jquery'), require('cropperjs')) :
typeof define === 'function' && define.amd ? define(['jquery', 'cropperjs'], factory) :
(factory(global.jQuery,global.Cropper));
}(this, (function ($,Cropper) { 'use strict';
$ = $ && $.hasOwnProperty('default') ? $['default'] : $;
Cropper = Cropper && Cropper.hasOwnProperty('default') ? Cropper['default'] : Cropper;
if ($.fn) {
var AnotherCropper = $.fn.cropper;
var NAMESPACE = 'cropper';
$.fn.cropper = function jQueryCropper(option) {
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
var result = void 0;
this.each(function (i, element) {
var $element = $(element);
var isDestroy = option === 'destroy';
var cropper = $element.data(NAMESPACE);
if (!cropper) {
if (isDestroy) {
return;
}
var options = $.extend({}, $element.data(), $.isPlainObject(option) && option);
cropper = new Cropper(element, options);
$element.data(NAMESPACE, cropper);
}
if (typeof option === 'string') {
var fn = cropper[option];
if ($.isFunction(fn)) {
result = fn.apply(cropper, args);
if (result === cropper) {
result = undefined;
}
if (isDestroy) {
$element.removeData(NAMESPACE);
}
}
}
});
return result !== undefined ? result : this;
};
$.fn.cropper.Constructor = Cropper;
$.fn.cropper.setDefaults = Cropper.setDefaults;
$.fn.cropper.noConflict = function noConflict() {
$.fn.cropper = AnotherCropper;
return this;
};
}
})));

File diff suppressed because it is too large Load Diff

View File

@ -332,6 +332,7 @@ var GalleryTheater = function(){
var setMainPic = function(direction,selectedFromStrip){
var img = null;
$('div.gallery-show-original a').eq(0).attr('href',currentPic.image.url)
if(direction == null){
img = $("<img class='gallery-image gal-active'>");
img.hide();

View File

@ -0,0 +1,304 @@
/*!
* Cropper.js v1.5.5
* https://fengyuanchen.github.io/cropperjs
*
* Copyright 2015-present Chen Fengyuan
* Released under the MIT license
*
* Date: 2019-08-04T02:26:27.232Z
*/
.cropper-container {
direction: ltr;
font-size: 0;
line-height: 0;
position: relative;
-ms-touch-action: none;
touch-action: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.cropper-container img {
display: block;
height: 100%;
image-orientation: 0deg;
max-height: none !important;
max-width: none !important;
min-height: 0 !important;
min-width: 0 !important;
width: 100%;
}
.cropper-wrap-box,
.cropper-canvas,
.cropper-drag-box,
.cropper-crop-box,
.cropper-modal {
bottom: 0;
left: 0;
position: absolute;
right: 0;
top: 0;
}
.cropper-wrap-box,
.cropper-canvas {
overflow: hidden;
}
.cropper-drag-box {
background-color: #fff;
opacity: 0;
}
.cropper-modal {
background-color: #000;
opacity: 0.5;
}
.cropper-view-box {
display: block;
height: 100%;
outline: 1px solid #39f;
outline-color: rgba(51, 153, 255, 0.75);
overflow: hidden;
width: 100%;
}
.cropper-dashed {
border: 0 dashed #eee;
display: block;
opacity: 0.5;
position: absolute;
}
.cropper-dashed.dashed-h {
border-bottom-width: 1px;
border-top-width: 1px;
height: calc(100% / 3);
left: 0;
top: calc(100% / 3);
width: 100%;
}
.cropper-dashed.dashed-v {
border-left-width: 1px;
border-right-width: 1px;
height: 100%;
left: calc(100% / 3);
top: 0;
width: calc(100% / 3);
}
.cropper-center {
display: block;
height: 0;
left: 50%;
opacity: 0.75;
position: absolute;
top: 50%;
width: 0;
}
.cropper-center::before,
.cropper-center::after {
background-color: #eee;
content: ' ';
display: block;
position: absolute;
}
.cropper-center::before {
height: 1px;
left: -3px;
top: 0;
width: 7px;
}
.cropper-center::after {
height: 7px;
left: 0;
top: -3px;
width: 1px;
}
.cropper-face,
.cropper-line,
.cropper-point {
display: block;
height: 100%;
opacity: 0.1;
position: absolute;
width: 100%;
}
.cropper-face {
background-color: #fff;
left: 0;
top: 0;
}
.cropper-line {
background-color: #39f;
}
.cropper-line.line-e {
cursor: ew-resize;
right: -3px;
top: 0;
width: 5px;
}
.cropper-line.line-n {
cursor: ns-resize;
height: 5px;
left: 0;
top: -3px;
}
.cropper-line.line-w {
cursor: ew-resize;
left: -3px;
top: 0;
width: 5px;
}
.cropper-line.line-s {
bottom: -3px;
cursor: ns-resize;
height: 5px;
left: 0;
}
.cropper-point {
background-color: #39f;
height: 5px;
opacity: 0.75;
width: 5px;
}
.cropper-point.point-e {
cursor: ew-resize;
margin-top: -3px;
right: -3px;
top: 50%;
}
.cropper-point.point-n {
cursor: ns-resize;
left: 50%;
margin-left: -3px;
top: -3px;
}
.cropper-point.point-w {
cursor: ew-resize;
left: -3px;
margin-top: -3px;
top: 50%;
}
.cropper-point.point-s {
bottom: -3px;
cursor: s-resize;
left: 50%;
margin-left: -3px;
}
.cropper-point.point-ne {
cursor: nesw-resize;
right: -3px;
top: -3px;
}
.cropper-point.point-nw {
cursor: nwse-resize;
left: -3px;
top: -3px;
}
.cropper-point.point-sw {
bottom: -3px;
cursor: nesw-resize;
left: -3px;
}
.cropper-point.point-se {
bottom: -3px;
cursor: nwse-resize;
height: 20px;
opacity: 1;
right: -3px;
width: 20px;
}
@media (min-width: 768px) {
.cropper-point.point-se {
height: 15px;
width: 15px;
}
}
@media (min-width: 992px) {
.cropper-point.point-se {
height: 10px;
width: 10px;
}
}
@media (min-width: 1200px) {
.cropper-point.point-se {
height: 5px;
opacity: 0.75;
width: 5px;
}
}
.cropper-point.point-se::before {
background-color: #39f;
bottom: -50%;
content: ' ';
display: block;
height: 200%;
opacity: 0;
position: absolute;
right: -50%;
width: 200%;
}
.cropper-invisible {
opacity: 0;
}
.cropper-bg {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC');
}
.cropper-hide {
display: block;
height: 0;
position: absolute;
width: 0;
}
.cropper-hidden {
display: none !important;
}
.cropper-move {
cursor: move;
}
.cropper-crop {
cursor: crosshair;
}
.cropper-disabled .cropper-drag-box,
.cropper-disabled .cropper-face,
.cropper-disabled .cropper-line,
.cropper-disabled .cropper-point {
cursor: not-allowed;
}

View File

@ -161,6 +161,13 @@
padding: 0 0 10px;
list-style: none;
}
.rgalbum .photo_edit{
right: 100%;
transition-duration: 0.5s;
}
.rgalbum:hover .photo_edit{
transform: translate(100%);
}
#imgholder .rgalbum {
position: relative;
float: left;

View File

@ -0,0 +1,432 @@
.minicolors {
position: relative;
}
.minicolors-sprite {
background-image: url(jquery.minicolors.png);
}
.minicolors-swatch {
position: absolute;
vertical-align: middle;
background-position: -80px 0;
border: solid 1px #ccc;
cursor: text;
padding: 0;
margin: 0;
display: inline-block;
}
.minicolors-swatch-color {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.minicolors input[type=hidden] + .minicolors-swatch {
width: 28px;
position: static;
cursor: pointer;
}
.minicolors input[type=hidden][disabled] + .minicolors-swatch {
cursor: default;
}
/* Panel */
.minicolors-panel {
position: relative;
width: 173px;
background: white;
border: solid 1px #CCC;
box-shadow: 0 0 20px rgba(0, 0, 0, .2);
z-index: 99999;
box-sizing: content-box;
display: none;
}
.minicolors-panel.minicolors-visible {
display: block;
}
/* Panel positioning */
.minicolors-position-top .minicolors-panel {
top: -154px;
}
.minicolors-position-right .minicolors-panel {
right: 0;
}
.minicolors-position-bottom .minicolors-panel {
top: auto;
}
.minicolors-position-left .minicolors-panel {
left: 0;
}
.minicolors-with-opacity .minicolors-panel {
width: 194px;
}
.minicolors .minicolors-grid {
position: relative;
top: 1px;
left: 1px; /* LTR */
width: 150px;
height: 150px;
margin-bottom: 2px;
background-position: -120px 0;
cursor: crosshair;
}
[dir=rtl] .minicolors .minicolors-grid {
right: 1px;
}
.minicolors .minicolors-grid-inner {
position: absolute;
top: 0;
left: 0;
width: 150px;
height: 150px;
}
.minicolors-slider-saturation .minicolors-grid {
background-position: -420px 0;
}
.minicolors-slider-saturation .minicolors-grid-inner {
background-position: -270px 0;
background-image: inherit;
}
.minicolors-slider-brightness .minicolors-grid {
background-position: -570px 0;
}
.minicolors-slider-brightness .minicolors-grid-inner {
background-color: black;
}
.minicolors-slider-wheel .minicolors-grid {
background-position: -720px 0;
}
.minicolors-slider,
.minicolors-opacity-slider {
position: absolute;
top: 1px;
left: 152px; /* LTR */
width: 20px;
height: 150px;
background-color: white;
background-position: 0 0;
cursor: row-resize;
}
[dir=rtl] .minicolors-slider,
[dir=rtl] .minicolors-opacity-slider {
right: 152px;
}
.minicolors-slider-saturation .minicolors-slider {
background-position: -60px 0;
}
.minicolors-slider-brightness .minicolors-slider {
background-position: -20px 0;
}
.minicolors-slider-wheel .minicolors-slider {
background-position: -20px 0;
}
.minicolors-opacity-slider {
left: 173px; /* LTR */
background-position: -40px 0;
display: none;
}
[dir=rtl] .minicolors-opacity-slider {
right: 173px;
}
.minicolors-with-opacity .minicolors-opacity-slider {
display: block;
}
/* Pickers */
.minicolors-grid .minicolors-picker {
position: absolute;
top: 70px;
left: 70px;
width: 12px;
height: 12px;
border: solid 1px black;
border-radius: 10px;
margin-top: -6px;
margin-left: -6px;
background: none;
}
.minicolors-grid .minicolors-picker > div {
position: absolute;
top: 0;
left: 0;
width: 8px;
height: 8px;
border-radius: 8px;
border: solid 2px white;
box-sizing: content-box;
}
.minicolors-picker {
position: absolute;
top: 0;
left: 0;
width: 18px;
height: 2px;
background: white;
border: solid 1px black;
margin-top: -2px;
box-sizing: content-box;
}
/* Swatches */
.minicolors-swatches,
.minicolors-swatches li {
margin: 5px 0 3px 5px; /* LTR */
padding: 0;
list-style: none;
overflow: hidden;
}
[dir=rtl] .minicolors-swatches,
[dir=rtl] .minicolors-swatches li {
margin: 5px 5px 3px 0;
}
.minicolors-swatches .minicolors-swatch {
position: relative;
float: left; /* LTR */
cursor: pointer;
margin:0 4px 0 0; /* LTR */
}
[dir=rtl] .minicolors-swatches .minicolors-swatch {
float: right;
margin:0 0 0 4px;
}
.minicolors-with-opacity .minicolors-swatches .minicolors-swatch {
margin-right: 7px; /* LTR */
}
[dir=rtl] .minicolors-with-opacity .minicolors-swatches .minicolors-swatch {
margin-right: 0;
margin-left: 7px;
}
.minicolors-swatch.selected {
border-color: #000;
}
/* Inline controls */
.minicolors-inline {
display: inline-block;
}
.minicolors-inline .minicolors-input {
display: none !important;
}
.minicolors-inline .minicolors-panel {
position: relative;
top: auto;
left: auto; /* LTR */
box-shadow: none;
z-index: auto;
display: inline-block;
}
[dir=rtl] .minicolors-inline .minicolors-panel {
right: auto;
}
/* Default theme */
.minicolors-theme-default .minicolors-swatch {
top: 5px;
left: 5px; /* LTR */
width: 18px;
height: 18px;
}
[dir=rtl] .minicolors-theme-default .minicolors-swatch {
right: 5px;
}
.minicolors-theme-default .minicolors-swatches .minicolors-swatch {
margin-bottom: 2px;
top: 0;
left: 0; /* LTR */
width: 18px;
height: 18px;
}
[dir=rtl] .minicolors-theme-default .minicolors-swatches .minicolors-swatch {
right: 0;
}
.minicolors-theme-default.minicolors-position-right .minicolors-swatch {
left: auto; /* LTR */
right: 5px; /* LTR */
}
[dir=rtl] .minicolors-theme-default.minicolors-position-left .minicolors-swatch {
right: auto;
left: 5px;
}
.minicolors-theme-default.minicolors {
width: auto;
display: inline-block;
}
.minicolors-theme-default .minicolors-input {
height: 20px;
width: auto;
display: inline-block;
padding-left: 26px; /* LTR */
}
[dir=rtl] .minicolors-theme-default .minicolors-input {
text-align: right;
unicode-bidi: plaintext;
padding-left: 1px;
padding-right: 26px;
}
.minicolors-theme-default.minicolors-position-right .minicolors-input {
padding-right: 26px; /* LTR */
padding-left: inherit; /* LTR */
}
[dir=rtl] .minicolors-theme-default.minicolors-position-left .minicolors-input {
padding-right: inherit;
padding-left: 26px;
}
/* Bootstrap theme */
.minicolors-theme-bootstrap .minicolors-swatch {
z-index: 2;
top: 3px;
left: 3px; /* LTR */
width: 28px;
height: 28px;
border-radius: 3px;
}
[dir=rtl] .minicolors-theme-bootstrap .minicolors-swatch {
right: 3px;
}
.minicolors-theme-bootstrap .minicolors-swatches .minicolors-swatch {
margin-bottom: 2px;
top: 0;
left: 0; /* LTR */
width: 20px;
height: 20px;
}
[dir=rtl] .minicolors-theme-bootstrap .minicolors-swatches .minicolors-swatch {
right: 0;
}
.minicolors-theme-bootstrap .minicolors-swatch-color {
border-radius: inherit;
}
.minicolors-theme-bootstrap.minicolors-position-right > .minicolors-swatch {
left: auto; /* LTR */
right: 3px; /* LTR */
}
[dir=rtl] .minicolors-theme-bootstrap.minicolors-position-left > .minicolors-swatch {
right: auto;
left: 3px;
}
.minicolors-theme-bootstrap .minicolors-input {
float: none;
padding-left: 44px; /* LTR */
}
[dir=rtl] .minicolors-theme-bootstrap .minicolors-input {
text-align: right;
unicode-bidi: plaintext;
padding-left: 12px;
padding-right: 44px;
}
.minicolors-theme-bootstrap.minicolors-position-right .minicolors-input {
padding-right: 44px; /* LTR */
padding-left: 12px; /* LTR */
}
[dir=rtl] .minicolors-theme-bootstrap.minicolors-position-left .minicolors-input {
padding-right: 12px;
padding-left: 44px;
}
.minicolors-theme-bootstrap .minicolors-input.input-lg + .minicolors-swatch {
top: 4px;
left: 4px; /* LTR */
width: 37px;
height: 37px;
border-radius: 5px;
}
[dir=rtl] .minicolors-theme-bootstrap .minicolors-input.input-lg + .minicolors-swatch {
right: 4px;
}
.minicolors-theme-bootstrap .minicolors-input.input-sm + .minicolors-swatch {
width: 24px;
height: 24px;
}
.minicolors-theme-bootstrap .minicolors-input.input-xs + .minicolors-swatch {
width: 18px;
height: 18px;
}
.input-group .minicolors-theme-bootstrap:not(:first-child) .minicolors-input {
border-top-left-radius: 0; /* LTR */
border-bottom-left-radius: 0; /* LTR */
}
[dir=rtl] .input-group .minicolors-theme-bootstrap .minicolors-input {
border-radius: 4px;
}
[dir=rtl] .input-group .minicolors-theme-bootstrap:not(:first-child) .minicolors-input {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
[dir=rtl] .input-group .minicolors-theme-bootstrap:not(:last-child) .minicolors-input {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
/* bootstrap input-group rtl override */
[dir=rtl] .input-group .form-control,
[dir=rtl] .input-group-addon,
[dir=rtl] .input-group-btn > .btn,
[dir=rtl] .input-group-btn > .btn-group > .btn,
[dir=rtl] .input-group-btn > .dropdown-toggle {
border: 1px solid #ccc;
border-radius: 4px;
}
[dir=rtl] .input-group .form-control:first-child,
[dir=rtl] .input-group-addon:first-child,
[dir=rtl] .input-group-btn:first-child > .btn,
[dir=rtl] .input-group-btn:first-child > .btn-group > .btn,
[dir=rtl] .input-group-btn:first-child > .dropdown-toggle,
[dir=rtl] .input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),
[dir=rtl] .input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-left: 0;
}
[dir=rtl] .input-group .form-control:last-child,
[dir=rtl] .input-group-addon:last-child,
[dir=rtl] .input-group-btn:last-child > .btn,
[dir=rtl] .input-group-btn:last-child > .btn-group > .btn,
[dir=rtl] .input-group-btn:last-child > .dropdown-toggle,
[dir=rtl] .input-group-btn:first-child > .btn:not(:first-child),
[dir=rtl] .input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
/* Semantic Ui theme */
.minicolors-theme-semanticui .minicolors-swatch {
top: 0;
left: 0; /* LTR */
padding: 18px;
}
[dir=rtl] .minicolors-theme-semanticui .minicolors-swatch {
right: 0;
}
.minicolors-theme-semanticui input {
text-indent: 30px;
}

View File

@ -1,10 +1,138 @@
require 'rubyXL'
class Admin::GalleriesController < OrbitAdminController
include Admin::GalleriesHelper
before_filter :setup_vars
before_filter :setup_vars
before_action :authenticate_user, :except => "imgs"
before_action :log_user_action
def save_crop
begin
images = AlbumImage.all.select{|value| params[:id].include? value.id.to_s}
id = images.first.album_id.to_s
x = params['x']
y = params['y']
w = params['w']
h = params['h']
cords = x.zip(y,w,h)
count = cords.length
images.each_with_index do |image,index|
cord = cords[index]
if image.album_crops.first.nil?
image.album_crops.create(crop_x: cord[0],crop_y: cord[1],crop_w: cord[2],crop_h: cord[3])
else
image.album_crops.first.update_attributes(crop_x: cord[0],crop_y: cord[1],crop_w: cord[2],crop_h: cord[3])
end
end
@@finish = false
@@start = false
Thread.new do
@@start = true
images.each_with_index do |image,index|
@@progress_percent = (index*100.0/count).floor.to_s+'%'
all_version = image.file.versions.map{|k,v| k}
begin
#org_fname = image.file.path
#org_extname = File.extname(org_fname)
#org_fname.slice! org_extname
#FileUtils.cp(org_fname + org_extname, org_fname + '_resized' + org_extname)
@@progress_filename = image[:file].to_s
all_version.each do |version|
if !(version.to_s == 'resized' && crop_but_no_backup(image))
image.file.recreate_versions! version
image.save!
end
end
rescue => e
@@progress_filename = e.inspect.to_s
puts e.inspect
end
end
@@finish = true
end
rescue => e
puts e.inspect
end
redirect_url = "/admin/galleries/crop_process"
render :json => {'href' => redirect_url}.to_json
end
def call_translate
text = params['text']
render :json => {'translate' => "#{t(text.to_s)}" }.to_json
end
def recreate_image
notalive = @@progress_percent.nil? rescue true
if notalive
if !params['album_id'].to_s.empty?
choice_ids = params['album_id'].split(',')
albums = Album.all.select { |value| (choice_ids.include? value.id.to_s)}
if !(params['use_default']=='true')
color = params['color_choice'].to_s.empty? ? 'transparent' : params['color_choice']
albums.each do |album|
if album.album_colors.first.nil?
album.album_colors.create('color' => color)
else
album.album_colors.first.update_attributes('color' => color, 'updated_at' => Time.now)
end
end
end
@@start = false
count = 0
albums.each{|album| count+=album.album_images.count }
@@finish = false
Thread.new do
@@start = true
i = 0
albums.each do |album|
album.album_images.each do |image|
error = nil
all_version = image.file.versions.map{|k,v| k}
begin
all_version.each do |version|
if !(version.to_s == 'resized' && crop_but_no_backup(image))
image.file.recreate_versions! version
image.save!
end
end
rescue => error
end
@@progress_percent = (i*100.0/count).floor.to_s+'%'
if !error.nil?
@@progress_filename = error.inspect.to_s.encode('UTF-8', invalid: :replace, undef: :replace, replace: '?')
sleep(1)
else
@@progress_filename = image[:file].to_s
end
i+=1
end
end
@@finish = true
end
else
@@start = true
@@progress_filename = ''
@@finish = true
@@progress_percent = '100%'
end
end
end
def finish_recreate
@@progress_percent = nil
@@progress_filename = nil
@@start = false
render :text => ''
end
def recreate_progress
if @@start
render :json => {'percent' => (@@progress_percent rescue '0%'), 'filename' => (@@progress_filename rescue ''), 'finish' => (@@finish rescue false) }.to_json
else
render :json => {'percent' => '0%', 'filename' => '', 'finish' => false }.to_json
end
end
def index
Album.each do |album|
if album.album_colors.first.nil?
album.album_colors.create('color' => '#000000')
end
end
@tags = @module_app.tags
categories = @module_app.categories.enabled
@filter_fields = filter_fields(categories, @tags)
@ -14,7 +142,15 @@ class Admin::GalleriesController < OrbitAdminController
albums = Album.where(:order.gt => -1).asc(:order).with_categories(filters("category")).with_tags(filters("tag"))
albums = search_data(albums,[:name])
@albums = @albums.concat(albums)
if AlbumColor.count!=0
if AlbumColor.all.desc('updated_at').first[:color] == 'transparent'
@color_save = ''
else
@color_save = AlbumColor.desc('updated_at').first[:color]
end
else
@color_save = '#000000'
end
if request.xhr?
render :partial => "album", :collection => @albums
end
@ -190,19 +326,53 @@ class Admin::GalleriesController < OrbitAdminController
end
def upload_image
@album = Album.find(params[:album_id])
@files = params['files']
a = Array.new
@files.each do |file|
@image = @album.album_images.new
@image.file = file
@image.tags = @album.tags rescue []
@image.save!
a << {"thumbnail_url"=>@image.file.thumb.url,"url"=>admin_image_path(@image)}
def upload_process
if @@upload_success == true
count = @@image_unprocessed.length
Thread.new do
begin
@@start = true
@@image_unprocessed.each_with_index do |image,i|
@@progress_filename = @@file[i].original_filename
image.file = @@file[i]
image.save!
@@progress_percent = ((i+1)*100.0/count).floor.to_s + '%'
end
rescue => e
puts e.inspect
end
@@file = []
@@image_unprocessed = []
@upload_success = false
@@finish = true
end
end
render :json=>{"files"=>a}.to_json
end
def start_upload_process
@@upload_success = true
render :json => {}.to_json
end
def init_upload
@@image_unprocessed = []
@@start = false
@@finish = false
@@file = []
@@progress_percent = '0%'
@@progress_filename = 'processing!!'
render :json => {}.to_json
end
def upload_image
if !(@@image_unprocessed.nil?)
album = Album.find(params[:album_id])
files = params['files']
files.each do |file|
image = album.album_images.new
@@file << file
image.tags = (album.tags rescue [])
@@image_unprocessed << image
end
end
render :json=>{"files"=>[{}]}.to_json
end
def last_image_id
@ -276,7 +446,13 @@ class Admin::GalleriesController < OrbitAdminController
end
private
def crop_but_no_backup image
fname = image.file.path
extension = File.extname(fname)
base_name = fname.chomp(extension)
base_name += ('_resized'+ extension)
File.file?(base_name)
end
def setup_vars
@module_app = ModuleApp.where(:key=>"gallery").first
end

View File

@ -1,5 +1,17 @@
class Admin::ImagesController < OrbitAdminController
before_filter :setup_vars
def batch_crop
images = params['image_ids'].split(',')
@img = []
images.each do |image|
@img << AlbumImage.find(image)
end
render 'batch_crop'
end
def edit
@image = AlbumImage.find(params[:id])
render 'edit_image'
end
def show
@image = AlbumImage.find(params[:id])
@albumid = @image.album_id
@ -35,6 +47,7 @@ class Admin::ImagesController < OrbitAdminController
images = params['images']
images.each do |image|
img = AlbumImage.find(image)
FileUtils.rm_rf(File.dirname(img.file.path))
img.delete
end
if params['delete_cover'] == "true"

View File

@ -67,6 +67,7 @@ class GalleriesController < ApplicationController
{
"link_to_show" => OrbitHelper.widget_more_url + "/" + a.album.to_param + "#" + a.id.to_s,
"alt_title" => alt_text,
"src" => a.file.url,
"thumb-src" => a.file.thumb.url,
"thumb-large-src" => a.file.thumb_large.url,
"image_description" => a.description,
@ -86,14 +87,15 @@ class GalleriesController < ApplicationController
images = album.album_images.asc(:order)
output = Array.new
images.each do |values|
alt_text = (values.description.nil? || values.description == "" ? "gallery image" : values.description)
output << { _id: values.id.to_s,
description: values.description,
title: values.title,
alt_title: alt_text,
file: values.file.as_json[:file],
gallery_album_id: values.album_id,
tags: values.tags}
alt_text = (values.description.nil? || values.description == "" ? "gallery image" : values.description)
output << { _id: values.id.to_s,
description: values.description,
title: values.title,
alt_title: alt_text,
url: values.file.url,
file: values.file.as_json[:file],
gallery_album_id: values.album_id,
tags: values.tags}
end
return output
end
@ -105,7 +107,6 @@ class GalleriesController < ApplicationController
images = album.album_images.asc(:order)
data = {
"album" => album,
# "images" => images,
"image" => image.id.to_s,
"images" => imgs(albumid)
}

View File

@ -17,7 +17,9 @@ class Album
# has_and_belongs_to_many :tags, :class_name => "GalleryTag"
has_many :album_images, :autosave => true, :dependent => :destroy
has_many :album_colors, :autosave => true, :dependent => :destroy
accepts_nested_attributes_for :album_images, :allow_destroy => true
accepts_nested_attributes_for :album_colors, :allow_destroy => true
def self.find_by_param(input)
self.find_by(uid: input)

View File

@ -0,0 +1,6 @@
class AlbumColor
include Mongoid::Document
include Mongoid::Timestamps
field :color, type: String
belongs_to :album
end

8
app/models/album_crop.rb Normal file
View File

@ -0,0 +1,8 @@
class AlbumCrop
include Mongoid::Document
field :crop_x, type: String
field :crop_y, type: String
field :crop_w, type: String
field :crop_h, type: String
belongs_to :album_image
end

View File

@ -14,5 +14,6 @@ class AlbumImage
# has_and_belongs_to_many :tags, :class_name => "GalleryTag"
belongs_to :album
has_many :album_crops, :autosave => true, :dependent => :destroy
accepts_nested_attributes_for :album_crops, :allow_destroy => true
end

View File

@ -2,14 +2,8 @@
module CarrierWave
module Uploader
module Versions
def recreate_version!(version)
already_cached = cached?
cache_stored_file! if !already_cached
send(version).store!
if !already_cached && @cache_id
tmp_dir = File.expand_path(File.join(cache_dir, cache_id), CarrierWave.root)
FileUtils.rm_rf(tmp_dir)
end
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
end
end
@ -21,7 +15,6 @@ class GalleryUploader < CarrierWave::Uploader::Base
# include CarrierWave::RMagick
# include CarrierWave::ImageScience
include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
# storage :file
# storage :s3
@ -31,7 +24,13 @@ class GalleryUploader < CarrierWave::Uploader::Base
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
def get_org_url
if have_crop?
model.file.resized.url
else
model.file.url
end
end
def fix_exif_rotation
manipulate! do |img|
img.tap(&:auto_orient)
@ -53,37 +52,45 @@ class GalleryUploader < CarrierWave::Uploader::Base
# version :thumb do
# process :scale => [50, 50]
# end
process :resizer
process :optimize
version :resized, :if => :have_crop? do #backup
def full_filename(for_file)
extension = File.extname(super(for_file))
base_name = super(for_file).split('resized_').join('').chomp(extension)
base_name + '_resized'+ extension
end
end
version :crop_from_org, :if => :have_crop? do
process :crop_it
def full_filename(for_file)
super(for_file).split('crop_from_org_').join('')
end
end
version :thumb do
process :fix_exif_rotation
process :resize_to_fill => [200, 200]
process :convert => 'png', :if => :transparent?
process :pad_process => [200,200]
end
version :thumb_large do
process :fix_exif_rotation
process :resize_to_fill => [600, 600]
process :convert => 'png', :if => :transparent?
process :pad_process => [600,600]
end
version :theater do
process :fix_exif_rotation
process :resize_to_limit => [1920, 1080]
process :limit_process => [1920, 1080]
end
version :mobile do
process :fix_exif_rotation
process :resize_to_limit => [1152, 768]
process :limit_process => [1152, 768]
end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
# def extension_white_list
# %w(jpg jpeg gif png)
# end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
# def extension_white_list
# %w(jpg jpeg gif png)
# end
# Override the filename of the uploaded files:
# def filename
# "something.jpg" if original_filename
# end
# Override the filename of the uploaded files:
# def filename
# "something.jpg" if original_filename
# end
# def manipulate!
# raise current_path.inspect
@ -94,6 +101,66 @@ class GalleryUploader < CarrierWave::Uploader::Base
# rescue ::MiniMagick::Error, ::MiniMagick::Invalid => e
# raise CarrierWave::ProcessingError.new("Failed to manipulate with MiniMagick, maybe it is not an image? Original Error: #{e}")
# end
def optimize (*arg)
manipulate! do |img|
return img unless img.mime_type.match /image\/jpeg/
img.strip
img.combine_options do |c|
c.quality "90"
c.depth "24"
c.interlace "plane"
end
img
end
end
private
def resizer
size_of_file = size.to_f / (2**20)
if size_of_file > 5
img = MiniMagick::Image.open(path)
img_width = img[:width]
img_height = img[:height]
multiple = [img_width/Math.sqrt(size_of_file/5)/1920,img_height/Math.sqrt(size_of_file/5)/1080].max
if (multiple - multiple.to_i)>0.5
multiple = multiple.to_i + 0.5
else
multiple = multiple.to_i
end
resize_to_limit(multiple*1920,multiple*1080)
else
manipulate! do |img|
img
end
end
end
def limit_process(w,h)
resize_to_limit(w,h)
end
def have_crop?(*arg)
!(model.album_crops.first.nil?)
end
def crop_it
crops = model.album_crops.first
x=(crops.crop_x).to_i.abs.to_s
y=(crops.crop_y).to_i.abs.to_s
w=crops.crop_w.to_i
h=crops.crop_h.to_i
crop_image("#{w}x#{h}+#{x}+#{y}")
end
def crop_image(geometry)
img = MiniMagick::Image.open(model.file.resized.path)
img.crop(geometry)
img.write(model.file.crop_from_org.path)
end
def transparent?(*arg)
now_id = model.album_id.to_s
now_album = Album.all.select { |value| (now_id==value.id.to_s)}[0]
now_album.album_colors.first['color']=='transparent'
end
def pad_process (w,h)
now_id = model.album_id.to_s
now_album = Album.all.select { |value| (now_id==value.id.to_s)}[0]
resize_and_pad(w, h, (now_album.album_colors.first['color']=='transparent' ? :transparent : now_album.album_colors.first['color']), 'Center')
end
end

View File

@ -1,4 +1,7 @@
<li class="rgalbum" data-image-id="<%= album.id %>">
<div class="check">
<input type="checkbox" class="checkbox" name='album_id' value='<%= album.id %>'>
</div>
<a href="<%= admin_gallery_path(album.id) %>">
<% if album.cover == "default" %>
<%= image_tag "gallery/default.jpg" %>

View File

@ -2,6 +2,7 @@
<%= stylesheet_link_tag "lib/main-forms" %>
<%= stylesheet_link_tag "lib/fileupload" %>
<%= stylesheet_link_tag "lib/main-list" %>
<%= stylesheet_link_tag "jquery.minicolors" %>
<% end %>
<% content_for :page_specific_javascript do %>
<%= javascript_include_tag "lib/bootstrap-fileupload" %>
@ -9,7 +10,55 @@
<%= javascript_include_tag "lib/datetimepicker/datetimepicker.js" %>
<%= javascript_include_tag "lib/modal-preview" %>
<%= javascript_include_tag "lib/file-type" %>
<%= javascript_include_tag "jquery.minicolors" %>
<% end %>
<style>
.main-forms fieldset .input-area .module-area {
padding: 20px;
overflow: visible;
}
input.minicolors-input{
height: 2.5em;
max-width: 90%;
}
</style>
<script type="text/javascript">
function set_transparent(trigger) {
if (trigger.checked){
$('.minicolors-input').attr('data-color',$('.minicolors-input').val())
$('.minicolors-input').minicolors('value','transparent')
$('.minicolors-input').prop('disabled',true)
}
else{
$('.minicolors-input').minicolors('value',$('.minicolors-input').attr('data-color'))
$('.minicolors-input').prop('disabled',false)
}
}
$(document).ready( function() {
$('.minicolors-input').minicolors({
defaultValue: $(this).data('defaultValue') || '',
format: 'hex',
letterCase: 'lowercase',
position: 'bottom left',
change: function(value, opacity) {
if( !value ) return;
if( opacity ) value += ', ' + opacity;
},
theme: 'bootstrap'
});
$('.minicolors-input').attr('autocomplete','off')
$('.minicolors').css('margin','0 10px')
$('.minicolors').css('height','34px')
$('*').submit(function () {
var value = $(this).find('input.minicolors-input').val();
if (value == ''){
$(this).find('input.minicolors-input').val('transparent');
$(this).find('input.minicolors-input').prop('disabled',false);
}
return true
})
});
</script>
<fieldset>
<!-- Input Area -->
<div class="input-area">
@ -23,6 +72,9 @@
<li>
<a href="#tag" data-toggle="tab"><%= t(:tags) %></a>
</li>
<li>
<a href="#frame_color" data-toggle="tab"><%= t('gallery.recreate_thumb') %></a>
</li>
</ul>
<!-- Module -->
@ -40,7 +92,7 @@
</div>
</div>
<!-- Tag Module -->
<!-- Tag Module -->
<div class="tab-pane fade" id="tag">
<!-- Tag -->
@ -48,52 +100,69 @@
<label class="control-label muted"><%= t(:tags) %></label>
<%= select_tags(f, @module_app) %>
</div>
</div>
<!-- Frame Color Module -->
<% if @album.album_colors.first.nil? %>
<% @album.album_colors.new('color' => '#000000') %>
<% end %>
<%= f.fields_for :album_colors do |album_color_form| %>
<div class="tab-pane fade" id="frame_color">
<!-- Frame Color -->
<div class="control-group" style='display: flex;'>
<label class="control-label muted"><%= t('gallery.recreate_thumb') %></label>
<%= album_color_form.text_field :color , :class => 'input-block-level minicolors-input' %>
<span style='font-size: 20px;display: flex;align-items: center;'>
<input type='checkbox' onchange='set_transparent(this)' style='width: 18px;height: 18px;margin: 0;'>
<%= t('gallery.transparent') %>
</span>
</div>
</div>
<% end %>
</div>
<div class="nav-name"><strong><%= t(:language) %></strong></div>
<ul class="nav nav-pills language-nav">
<% @site_in_use_locales.each_with_index do |locale, i| %>
<li <%= (i == 0 ? 'class=active' : '') %>>
<a href=".<%= locale %>" data-toggle="tab"><%= t(locale.to_s) %></a>
</li>
<% end %>
</ul>
<div class="tab-content language-area">
<!-- Language Tabs -->
</div>
<div class='input-area'>
<div class="nav-name"><strong><%= t(:language) %></strong></div>
<ul class="nav nav-pills language-nav">
<% @site_in_use_locales.each_with_index do |locale, i| %>
<li <%= (i == 0 ? 'class=active' : '') %>>
<a href=".<%= locale %>" data-toggle="tab"><%= t(locale.to_s) %></a>
</li>
<% end %>
</ul>
<div class="tab-content language-area">
<!-- Language Tabs -->
<% @site_in_use_locales.each_with_index do |locale, i| %>
<div class="tab-pane fade in <%= (i == 0 ? 'active' : '') %> <%= locale %>">
<div class="control-group input-title">
<%= f.fields_for :name_translations do |name| %>
<%= label_tag(locale, t("gallery.album_name"),:class=>"control-label muted") %>
<div class="controls">
<%= name.text_field locale, :class => "input-block-level", :placeholder=>"Title",:value => (@album.name_translations[locale] rescue nil) %>
</div>
<% end %>
</div>
<div class="control-group input-content">
<%= f.fields_for :description_translations do |desc| %>
<%= label_tag(locale, t("gallery.album_desc"), :class=>"control-label muted") %>
<div class="controls">
<div class="textarea">
<%= desc.text_area locale, :class => "ckeditor input-block-level", :value => (@album.description_translations[locale] rescue nil)%>
</div>
</div>
<% end %>
</div>
</div>
<% end %>
</div>
<% @site_in_use_locales.each_with_index do |locale, i| %>
<div class="tab-pane fade in <%= (i == 0 ? 'active' : '') %> <%= locale %>">
<div class="control-group input-title">
<%= f.fields_for :name_translations do |name| %>
<%= label_tag(locale, t("gallery.album_name"),:class=>"control-label muted") %>
<div class="controls">
<%= name.text_field locale, :class => "input-block-level", :placeholder=>"Title",:value => (@album.name_translations[locale] rescue nil) %>
</div>
<% end %>
</div>
<div class="control-group input-content">
<%= f.fields_for :description_translations do |desc| %>
<%= label_tag(locale, t("gallery.album_desc"), :class=>"control-label muted") %>
<div class="controls">
<div class="textarea">
<%= desc.text_area locale, :class => "ckeditor input-block-level", :value => (@album.description_translations[locale] rescue nil)%>
</div>
</div>
<% end %>
</div>
</div>
<% end %>
</div>
</div>
<!-- Form Actions -->
<div class="form-actions">
<%= f.submit t("gallery.save"), :class=> "btn btn-primary bt-form-save" %>
</div>
</div>
<!-- Form Actions -->
<div class="form-actions">
<%= f.submit t("gallery.save"), :class=> "btn btn-primary bt-form-save" %>
</div>
</fieldset>

View File

@ -3,6 +3,9 @@
<img src="<%= image.file.thumb %>">
</a>
<% if can_edit_or_delete?(@album) %>
<span class="photo_edit" style="position: absolute;top: 0;background: #fff;padding: 5px;">
<a style="height:auto;color: #000;width: auto;" href="/<%= I18n.locale.to_s%>/admin/images/<%=image.id.to_s %>/edit">
<i class="<%= (@album.cover.to_s == image.id.to_s)? "editimage" : "editimage-2" %>"></i>edit</a></span>
<ul class="photo-action clearfix">
<li class="photo_cover"><i class="<%= (@album.cover.to_s == image.id.to_s)? "icons-star" : "icons-star-2" %>"></i></li>
<li class="phtot_depiction"><a href="#view-photo-depiction" class="open" for="description"><i class="icon-comment-alt"></i></a></li>

View File

@ -0,0 +1,106 @@
<%= javascript_include_tag "jquery.minicolors.js" %>
<%= stylesheet_link_tag "jquery.minicolors.css" %>
<nobr style='display: block;display: flex;flex-wrap: wrap;width: 100%;'>
<form method="get" action="/admin/galleries/recreate_image?" name="thumb_recreate_form"
style='display: block;display: inline-flex;flex-wrap: wrap;align-items: center;width: 100%;'>
<span style="display:inline-flex;align-items:center;padding:0 1%;height:34px;font-size: 1.5em;">
<%= t('gallery.recreate_thumb')+':' %>
</span>
<input style='height:26px;max-width: 80%;' class='minicolors-input' type="text" name="color_choice" value="<%= @color_save.to_s %>" autocomplete="off">
<span style='font-size: 20px;'>
<input type='checkbox' onchange='set_transparent(this)' style='width: 18px;height: 18px;margin: 0;'>
<%= t('gallery.transparent') %>
</span>
<button type="button" onclick='submit_msg()' style='margin: 0 10px;height: 34px;'>
<%= t('gallery.recreate') %>
</button>
<input type="hidden" name="album_id" value="">
<span style='display: inline-flex;align-items: center;'>
<input type='checkbox' name='use_default' value='true' onchange='hide_input(this)' style='width: 18px;height: 18px;margin: 0;'>
<label style='font-size: 20px;margin: 0;'><%= t('gallery.use_set') %></label>
</span>
</form>
<span style='display: inline-flex;align-items: center;padding-bottom: 20px;padding-left: 10px;'>
<input type='radio' name='checkbox' onchange='set_checked(this)'>
<label style='font-size: 20px;margin: 0;'><%= t('gallery.checked') %></label>
<input type='radio' name='checkbox' onchange='set_unchecked(this)'>
<label style='font-size: 20px;margin: 0;'><%= t('gallery.unchecked') %></label>
</span>
</nobr>
<script type="text/javascript">
function hide_input(trigger) {
if (trigger.checked){
$('.minicolors').css('display','none')
}
else{
$('.minicolors').css('display','block')
}
}
function set_transparent(trigger) {
if (trigger.checked){
$('.minicolors-input').attr('data-color',$('.minicolors-input').val())
$('.minicolors-input').minicolors('value','')
$('.minicolors-input').prop('disabled',true)
}
else{
$('.minicolors-input').minicolors('value',$('.minicolors-input').attr('data-color'))
$('.minicolors-input').prop('disabled',false)
}
}
function set_checked(trigger) {
if (trigger.checked){
$(".rgbody input[name='album_id']").prop('checked',true)
}
}
function set_unchecked(trigger) {
if (trigger.checked){
$(".rgbody input[name='album_id']").prop('checked',false)
}
}
function submit_msg() {
var msg = "<%= t('gallery.sure?') %>";
if (confirm(msg)==true){
$("form[name='thumb_recreate_form']").submit();
return true;
}else{
return false;
}
}
$("form[name='thumb_recreate_form']").submit(function () {
var formdata = new Array;
var data = $(".rgbody input[name='album_id']")
var count=data.length;
var permit = true
for (i=0;i<count;i++){
if (data[i].checked){
formdata.push($(data[i]).val())
}
}
if (formdata.length===0){
permit = false
}
$("form[name='thumb_recreate_form']").find("input[name='album_id']").val(formdata.join(','))
if (permit){
return true;
}
else{
alert('<%= t('gallery.no_choose') %>')
return false;
}
})
$(document).ready( function() {
$('.minicolors-input').minicolors({
defaultValue: $(this).data('defaultValue') || '',
format: 'hex',
letterCase: 'lowercase',
position: 'bottom left',
change: function(value, opacity) {
if( !value ) return;
if( opacity ) value += ', ' + opacity;
},
theme: 'bootstrap'
});
$('.minicolors').css('margin','0 10px')
$('.minicolors').css('height','34px')
});
</script>

View File

@ -1,6 +1,5 @@
<% content_for :page_specific_css do %>
<%= stylesheet_link_tag "gallery" %>
<% end %>
<%= stylesheet_link_tag "gallery" %>
<%= stylesheet_link_tag "lib/tags-groups" %>
<% content_for :page_specific_javascript do %>
<%= javascript_include_tag "lib/jquery-ui-1.10.0.custom.min" %>
<%= javascript_include_tag "jquery.masonry.min.js" %>
@ -8,17 +7,18 @@
<%= javascript_include_tag "gallery" %>
<% end %>
<%= render_filter @filter_fields, "orbit_gallery" %>
<div class="order-edit-notification">Albums re-ordering enabled.</div>
<div class="rgbody">
<ul id="orbit_gallery" class="gallery clearfix" data-gallery-id="gallery">
<%= render :partial => "album", :collection => @albums %>
<div class="order-edit-notification">Albums re-ordering enabled.</div>
<%= render 'recreate_thumb' %>
<div class="rgbody" style='float: left;'>
<ul id="orbit_gallery" class="gallery clearfix" data-gallery-id="gallery"
style='display: inline-flex;flex-wrap: wrap;'>
<%= render :partial => "album", :collection => @albums %>
</ul>
</div>
<div class="bottomnav clearfix">
<div class="action pull-right">
<% if can_edit_or_delete?(nil) %>
<a href="#" class="btn btn-small btn-info order-btn-class" id="edit-order-btn">Edit Order</a>
<a href="#" class="btn btn-small btn-info order-btn-class" id="edit-order-btn"><%= t('gallery.edit_order') %></a>
<% end %>
</div>
</div>

View File

@ -0,0 +1,39 @@
<%= t('gallery.progressbar')+':' %>
<div style='width:100%;'>
<div class="progress">
<div class="progress-bar" style="width: 0%;text-align:center;background:#86f9fe;background: linear-gradient(90deg,#86f9fe,#2900f8);">0</div>
</div>
<div class="message" style='width:100%;text-align:center;'></div>
</div>
<SCRIPT LANGUAGE=javascript>
function get_data(){
var finish=false;
$.ajax({
url : "/admin/galleries/recreate_image/recreate_progress",
dataType : "json",
type : "post",
success:function(data){
$(".progress-bar").text(data.percent)
$(".message").text(data.filename)
finish = data.finish
if (finish){
$.get('/admin/galleries/recreate_image/finish_recreate')
clearInterval(id)
document.location.href = '/admin/galleries'
console.log('finish!')
}
$(".progress-bar").css('width',data.percent)
},
error:function(XMLHttpRequest, textStatus){
console.log(XMLHttpRequest); //XMLHttpRequest.responseText XMLHttpRequest.status XMLHttpRequest.readyState
console.log(textStatus);
$(".progress-bar").text("<%= t('gallery.error') %>");
console.log('error')
$.get('/admin/galleries/recreate_image/finish_recreate')
$(".progress-bar").css('width','100%')
clearInterval(id)
}
})
}
var id = setInterval(get_data,200)
</SCRIPT>

View File

@ -1,11 +1,9 @@
<% content_for :page_specific_css do %>
<%= stylesheet_link_tag "gallery" %>
<%= stylesheet_link_tag "lib/tags-groups" %>
<% end %>
<%= stylesheet_link_tag "gallery" %>
<%= stylesheet_link_tag "lib/tags-groups" %>
<!-- <div class="topnav clearfix">
<ul class="breadcrumb text-info pull-left">
<li><a href="/orbit_4.0.1/admin/dashboards/dashboards.shtml">Dashboard</a> <span class="divider">/</span></li>
<li><a href="<%#= panel_gallery_back_end_albums_path %>">Gallery</a> <span class="divider">/</span></li>
<li><a href="/orbit_4.0.1/admin/dashboards/dashboards.shtml"><%= t('gallery.dashboard') %></a> <span class="divider">/</span></li>
<li><a href="<%#= panel_gallery_back_end_albums_path %>"><%= t('gallery.gallery') %></a> <span class="divider">/</span></li>
<li class="active"><%#= @album.name %></li>
</ul>
</div> -->
@ -13,20 +11,22 @@
<div class="order-edit-notification">Images re-ordering enabled.</div>
<div class="bottomnav clearfix">
<div class="action pull-left">
<a href="<%= admin_galleries_path %>" class="btn btn-small"><i class="icons-back"></i> Back</a>
<a href="<%= admin_galleries_path %>" class="btn btn-small"><i class="icons-back"></i> <%= t('gallery.back') %></a>
<a href="javascript:select_all()" class='btn btn-small'> <%= t('gallery.checked') %></a>
</div>
<div class="action pull-right">
<a href="#" class="btn btn-inverse btn-small deselect hide">Deselect</a>
<a href="javascript:batch_crop()" class="btn btn-small hide crop"><%= t('gallery.batch_crop') %></a>
<a href="#" class="btn btn-inverse btn-small deselect hide"><%= t('gallery.deselect') %></a>
<% if can_edit_or_delete?(@album) %>
<a href="#dialog" data-toggle="modal" class="btn btn-warning btn-small deletephoto hide"><i class="icons-cross-3"></i> Delete Photo</a>
<a href="#view-photo-tags" class="btn btn-primary btn-small addtags open hide" for="batch"><i class="icons-tag"></i> Add Tags</a>
<a href="<%= import_admin_gallery_path(@album.id) %>" class="btn btn-small btn-info"><i class="icons-download"></i> Import</a>
<a href="#dialog" data-toggle="modal" class="btn btn-warning btn-small deletephoto hide"><i class="icons-cross-3"></i><%= t('gallery.delete_photo') %></a>
<a href="#view-photo-tags" class="btn btn-primary btn-small addtags open hide" for="batch"><i class="icons-tag"></i><%= t('gallery.add_tags') %></a>
<a href="<%= import_admin_gallery_path(@album.id) %>" class="btn btn-small btn-info"><i class="icons-download"></i><%= t('gallery.import') %></a>
<b class="divider"></b>
<a href="<%= edit_admin_gallery_path(@album.id) %>" class="btn btn-small btn-success"><i class="icon-edit"></i> Edit</a>
<a href="#" class="btn btn-small btn-info order-btn-class" id="edit-order-btn">Edit Order</a>
<a href="<%= edit_admin_gallery_path(@album.id) %>" class="btn btn-small btn-success"><i class="icon-edit"></i> <%= t('gallery.edit') %></a>
<a href="#" class="btn btn-small btn-info order-btn-class" id="edit-order-btn"><%= t('gallery.edit_order') %></a>
<b class="divider"></b>
<a href="#" class="add-imgs btn btn-small btn-primary"><i class="icons-plus"></i> Add Image</a>
<a href="#" class="add-imgs btn btn-small btn-primary"><i class="icons-plus"></i><%= t('gallery.add_image') %></a>
<% end %>
</div>
<form action="<%= admin_galleries_upload_image_path %>", id='fileupload'>
@ -39,7 +39,7 @@
<li>
<div class="fileinput-button add-photo">
<i class="icon-plus icon-white"></i>
<span>Add files...</span>
<span><%= t('gallery.add_files') %>...</span>
<input type="file" name="files[]" multiple>
</div>
<input type="hidden" value="<%= @album.id.to_s %>" name="album_id" id="fileupload_aid" />
@ -47,19 +47,19 @@
<li>
<button type="submit" class="start add-photo">
<i class="icon-upload icon-white"></i>
<span>Start upload</span>
<span><%= t('gallery.start_upload') %></span>
</button>
</li>
<li>
<button type="reset" class="cancel add-photo">
<i class="icon-ban-circle icon-white"></i>
<span>Cancel upload</span>
<span><%= t('gallery.cancel_upload') %></span>
</button>
</li>
<!-- <li>
<button type="button" class="delete">
<i class="icons-trash icon-white"></i>
<span>Delete</span>
<span><%= t('gallery.delete') %></span>
</button>
</li> -->
</ul>
@ -78,7 +78,7 @@
<!-- Drop Zone -->
<div id="dropzone" class="drop">
<div data-icons="&#xe0a3;"></div>
Drop files here
<%= t('gallery.drop_files_here') %>
</div>
<!-- The loading indicator is shown during file processing -->
<div class="fileupload-loading"></div>
@ -142,7 +142,7 @@
<% end %>
</ul>
<div class="form-actions">
<a href="javascript:$.pageslide.close()" class="btn btn-small">Cancel</a>
<a href="javascript:$.pageslide.close()" class="btn btn-small"><%= t('gallery.cancel') %></a>
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</fieldset>
@ -160,7 +160,7 @@
<textarea rows="10" name="album_image[description_translations][<%= locale %>]" for="<%= locale %>"></textarea>
<% end %>
<div class="form-actions">
<a href="javascript:$.pageslide.close()" class="btn btn-small">Cancel</a>
<a href="javascript:$.pageslide.close()" class="btn btn-small"><%= t('gallery.cancel') %></a>
<input type="submit" value="Save" class="btn btn-primary" />
<input type="hidden" value="" name="image_id" />
</div>
@ -242,7 +242,7 @@
</li>
<li class="name-size">
<p><a href="{%=file.url%}" title="{%=file.name%}" data-gallery="{%=file.thumbnail_url&&'gallery'%}" download="{%=file.name%}">{%=file.name%}</a></p>
<p ><span class="label label-success">Success</span> File uploaded successfully!</p>
<p ><span class="label label-success"><%= t('gallery.success') %></span><%= t('gallery.file_uploaded_successfully') %>!</p>
<p class="label label-info">{%=o.formatFileSize(file.size)%}</p>
</li>
{% } %}

View File

@ -12,12 +12,12 @@
<%= form_for @album, :url => panel_gallery_back_end_upload_image_path, :html => {:class => 'clear'} do |f| %>
<div class="fileupload-buttonbar">
<label class="fileinput-button">
<span>Add files...</span>
<span><%= t('gallery.add_files') %>...</span>
<input type="file" name="files[]" multiple>
</label>
<input type="hidden" value="<%= params[:album_id] %>" name="album_id" id="fileupload_aid" />
<button type="submit" class="start">Start upload</button>
<button type="reset" class="cancel">Cancel upload</button>
<button type="submit" class="start"><%= t('gallery.start_upload') %></button>
<button type="reset" class="cancel"><%= t('gallery.cancel_upload') %></button>
<!-- <button type="button" class="delete">Delete files</button>-->
</div>
<!-- </form> -->

View File

@ -0,0 +1,39 @@
<%= t('gallery.progressbar')+':' %>
<div style='width:100%;'>
<div class="progress">
<div class="progress-bar" style="width: 0%;text-align:center;background:#86f9fe;background: linear-gradient(90deg,#86f9fe,#2900f8);">0</div>
</div>
<div class="message" style='width:100%;text-align:center;'></div>
</div>
<SCRIPT LANGUAGE=javascript>
function get_data(){
var finish=false;
$.ajax({
url : "/admin/galleries/recreate_image/recreate_progress",
dataType : "json",
type : "post",
success:function(data){
$(".progress-bar").text(data.percent)
$(".message").text(data.filename)
finish = data.finish
if (finish){
$.get('/admin/galleries/recreate_image/finish_recreate')
clearInterval(id)
document.location.href = '/admin/galleries'
console.log('finish!')
}
$(".progress-bar").css('width',data.percent)
},
error:function(XMLHttpRequest, textStatus){
console.log(XMLHttpRequest); //XMLHttpRequest.responseText XMLHttpRequest.status XMLHttpRequest.readyState
console.log(textStatus);
$(".progress-bar").text("<%= t('gallery.error') %>");
console.log('error')
$.get('/admin/galleries/recreate_image/finish_recreate')
$(".progress-bar").css('width','100%')
clearInterval(id)
}
})
}
var id = setInterval(get_data,200)
</SCRIPT>

View File

@ -0,0 +1,102 @@
<style>
body{max-width: 100%;}
</style>
<script type="text/javascript" src="/assets/cropper.js"></script>
<script type="text/javascript" src="/assets/jquery-cropper.js"></script>
<link href="/assets/cropper.css" rel="stylesheet"></link>
<div style='padding-left: 10px;display:flex; flex-wrap: wrap;width:100%;align-items: center;'>
<div style='display:inline-flex;flex-direction:column;margin-right: 10px;'>
<span style='display:inline-flex;'>
<label style='padding: 5px;'><%= t('gallery.width') %>:</label><input type="text" name="width">
</span>
<span style='display:inline-flex;'>
<label style='padding: 5px;'><%= t('gallery.height') %>:</label><input type="text" name="height">
</span>
</div>
<button style='height: 50px;' onclick='change_config()'>修改裁減框長寬比</button>
</div>
<div style='display:flex; flex-wrap: wrap;width:100%'>
<% @img.each do |image| %>
<div class='<%= image.id %>' style='width:40%;max-width:40%;margin:10px 20px;'>
<img class='editimage' src="<%= image.file.get_org_url %>">
</div>
<% end %>
</div>
<button onclick='save_data()'><%= t('gallery.save') %></button>
<script>
var cropper_img = [],options=[]
function change_config(){
var count = cropper_img.length
var aspect_value = parseInt($("input[name='width']").val())/parseInt($("input[name='height']").val())
for (var i=0;i<count;i++){
if (isNaN(aspect_value)){
try{
delete options[i]['aspectRatio']
}
catch{
}
}else{
options[i].aspectRatio = aspect_value
}
$('.editimage').eq(i).cropper('destroy').cropper(options[i])
}
}
var x=[],y=[],w=[],h=[]
var id = []
<% @img.each do |image| %>
<% if image.album_crops.first.nil? %>
<% image.album_crops.new() %>
<% end %>
<% if !image.album_crops.first.crop_x.to_s.empty? %>
x.push(<%= image.album_crops.first.crop_x %>)
y.push(<%= image.album_crops.first.crop_y %>)
w.push(<%= image.album_crops.first.crop_w %>)
h.push(<%= image.album_crops.first.crop_h %>)
<% else %>
x.push('')
y.push('')
w.push('')
h.push('')
<% end %>
<% end %>
$('img.editimage').on('load',function() {
var temp = $('.editimage').parent()
temp.each(function(){id.push($(this).attr('class'))})
var image = $('.editimage')
var count = image.length
<% @img.each_with_index do |_,i| %>
options[<%= i %>] = {
data: {
x: x[<%= i %>],
y: y[<%= i %>],
width: w[<%= i %>],
height: h[<%= i %>]
},
crop: function (e) {
x[<%= i %>] = e.detail.x
y[<%= i %>] = e.detail.y
w[<%= i %>] = e.detail.width
h[<%= i %>] = e.detail.height
},
viewMode: 2,
zoomOnWheel: false,
autoCropArea: 1
};
cropper_img.push($('.editimage').eq(<%= i %>).cropper(options[<%= i %>]));
<% end %>
});
function save_data(){
$.ajax({
url : '/admin/galleries/save_crop',
dataType : "json",
type : "post",
data:{x:x,y:y,w:w,h:h,id:id},
success:function(data){
window.location.href = data.href;
},
error:function(){
alert('Your server has some problem, please try again later!')
}
})
}
</script>

View File

@ -0,0 +1,39 @@
<%= t('gallery.progressbar')+':' %>
<div style='width:100%;'>
<div class="progress">
<div class="progress-bar" style="width: 0%;text-align:center;background:#86f9fe;background: linear-gradient(90deg,#86f9fe,#2900f8);">0</div>
</div>
<div class="message" style='width:100%;text-align:center;'></div>
</div>
<SCRIPT LANGUAGE=javascript>
function get_data(){
var finish=false;
$.ajax({
url : "/admin/galleries/recreate_image/recreate_progress",
dataType : "json",
type : "post",
success:function(data){
$(".progress-bar").text(data.percent)
$(".message").text(data.filename)
finish = data.finish
if (finish){
$.get('/admin/galleries/recreate_image/finish_recreate')
clearInterval(id)
document.location.href = '/admin/galleries'
console.log('finish!')
}
$(".progress-bar").css('width',data.percent)
},
error:function(XMLHttpRequest, textStatus){
console.log(XMLHttpRequest); //XMLHttpRequest.responseText XMLHttpRequest.status XMLHttpRequest.readyState
console.log(textStatus);
$(".progress-bar").text("<%= t('gallery.error') %>");
console.log('error')
$.get('/admin/galleries/recreate_image/finish_recreate')
$(".progress-bar").css('width','100%')
clearInterval(id)
}
})
}
var id = setInterval(get_data,200)
</SCRIPT>

View File

@ -0,0 +1,59 @@
<style>
body{max-width: 100%;}
</style>
<script type="text/javascript" src="/assets/cropper.js"></script>
<link href="/assets/cropper.css" rel="stylesheet"></link>
<img class='editimage'src="<%= @image.file.get_org_url %>">
<div class='img-preview'></div>
<button onclick='save_data()'><%= t('gallery.save') %></button>
<script>
var x=[],y=[],w=[],h=[]
<% if @image.album_crops.first.nil? %>
<% @image.album_crops.new() %>
<% end %>
<% if !(@image.album_crops.first.crop_x.to_s.empty?) %>
x.push(<%= @image.album_crops.first.crop_x %>)
y.push(<%= @image.album_crops.first.crop_y %>)
w.push(<%= @image.album_crops.first.crop_w %>)
h.push(<%= @image.album_crops.first.crop_h %>)
<% end %>
$('img.editimage').on('load',function() {
var image = $('.editimage')
var options = {
data: {
x: x[0],
y: y[0],
width: w[0],
height: h[0]
},
crop: function (e) {
x[0] = e.detail.x
y[0] = e.detail.y
w[0] = e.detail.width
h[0] = e.detail.height
},
viewMode: 2,
zoomOnWheel: false,
autoCropArea: 1,
minContainerWidth: parseInt($('.editimage').width()),
minContainerHeight: parseInt($('.editimage').height())
};
var cropper = new Cropper(image[0],options);
});
function save_data(){
var temp = location.href.split('/').slice(-2)
var id = [temp[0]]
$.ajax({
url : '/admin/galleries/save_crop',
dataType : "json",
type : "post",
data:{x:x,y:y,w:w,h:h,id:id},
success:function(data){
window.location.href = data.href;
},
error:function(){
alert('Your server has some problem, please try again later!')
}
})
}
</script>

View File

@ -15,6 +15,9 @@
</div>
</div>
<div class="gallery-actions">
<div class="gallery-show-original gallery-actions-btn">
<a title="<%= t('gallery.show_original_image') %>"><i class="fa fa-image"></i></a>
</div>
<div class="gallery-toggle-desc gallery-actions-btn">
<i class="fa fa-comment"></i>
</div>

View File

@ -1,6 +1,37 @@
en:
gallery:
show_original_image: Show the original picture
width: Width
height: Height
batch_crop: Batch crop images
use_set: Use the previously configured color
add_files: Add files
start_upload: Start upload
cancel_upload: Cancel upload
drop_files_here: Drop files here
success: Success
file_uploaded_successfully: File uploaded successfully
close_panel: Close panel
no_choose: Please select at least one before apply
edit_order: Edit Order
save_order: Save Order
add_tags: Add tags
import: Import
delete_photo: Delete Photo
delete: Delete
deselect: Deselect
back: Back
edit: Edit
add_image: Add Image
progressbar: 'Progress bar'
error: 'Recreate thumb failed, please contact service agent or try again later'
'sure?': 'Are yoy sure to apply? it will recreate all the thumbs of you choose'
recreate_thumb: 'Frame color'
'recreate': 'Apply'
transparent: transparent
checked: select all
unchecked: unselect all
add_album: Add Album
add_images: Add Images
all: All

View File

@ -1,6 +1,39 @@
zh_tw:
gallery:
show_original_image: 顯示原始圖片
width:
height:
batch_crop: 批量裁減圖片
use_set: 使用先前已設定的顏色
add_files: 新增檔案
start_upload: 開始上傳
cancel_upload: 取消上傳
drop_files_here: 拖移檔案到此
success: 成功
file_uploaded_successfully: 檔案上傳成功
close_panel: 關閉面板
no_choose: 請至少選擇一項再按套用
edit_order: 改變排序
save_order: 儲存排序
add_tags: 新增標籤
import: 匯入
delete_photo: 刪除圖片
delete: 刪除
deselect: 反選
back: 返回
edit: 編輯
add_image: 新增圖片
cancel: 關閉
dashboard: 儀表板
progressbar: 進度條
error: '重新產生縮圖失敗,請聯絡客服或稍後再試'
'sure?': '您真的确定要套用嗎? 會重新產生整個相簿的縮圖喔!'
recreate_thumb: 相框底色
transparent: 透明
checked: 全選
unchecked: 全部反選
recreate: 套用
add_album: 新增相冊
add_images: 新增影像
album: 相冊
@ -25,15 +58,15 @@ zh_tw:
no_description: 沒有描述
photo_tag: 相片標籤
pic_not_found: 找不到圖片
img_link: Image Link
img_description: Image Description
img_link: 圖片連結
img_description: 圖片描述
save: 儲存
save_changes: 儲存變更
search_tags: 搜尋標籤
select_category: 選擇類別
set_cover: 設定為封面
widget:
widget1: Widget1
widget1: 插件1
widget_option:
horizontal: 水平
vertical: 垂直

View File

@ -6,7 +6,11 @@ Rails.application.routes.draw do
get "/xhr/galleries/theater/:id" => "galleries#theater"
namespace :admin do
get "galleries/get_photoData_json" => "galleries#get_photoData_json"
get "galleries/recreate_image" => "galleries#recreate_image"
get "galleries/crop_process" => "images#crop_process"
post "galleries/recreate_image/recreate_progress" => "galleries#recreate_progress"
get "galleries/recreate_image/finish_recreate" => "galleries#finish_recreate"
get "galleries/batch_crop" => "images#batch_crop"
get "galleries/new_images" => "galleries#new_images"
get "galleries/last_image_id" => "galleries#last_image_id"
post "galleries/set_cover" => "galleries#set_cover"
@ -14,7 +18,11 @@ Rails.application.routes.draw do
post "galleries/update_image" => "images#update_image"
post "galleries/image_tagging" => "images#image_tagging"
post "galleries/order" => "images#changeorder"
post "galleries/translate" => "galleries#call_translate"
post "galleries/save_crop" => "galleries#save_crop"
get "galleries/upload_process" => "galleries#upload_process"
post "galleries/start_upload_process" => "galleries#start_upload_process"
post "galleries/init_upload" => "galleries#init_upload"
resources :galleries do
get "imgs" => "galleries#imgs"
member do