Merge pull request #591 from hrniels/subalbums

Some cleanup, fixes and a new feature for subalbums.
pull/603/head
Tobias Reich 8 years ago committed by GitHub
commit 55ae8a4be2

@ -28,6 +28,7 @@ final class Admin extends Access {
case 'Album::setPublic': self::setAlbumPublicAction(); break;
case 'Album::delete': self::deleteAlbumAction(); break;
case 'Album::merge': self::mergeAlbumsAction(); break;
case 'Album::move': self::moveAlbumsAction(); break;
// Photo functions
case 'Photo::get': self::getPhotoAction(); break;
@ -143,6 +144,14 @@ final class Admin extends Access {
}
private static function moveAlbumsAction() {
Validator::required(isset($_POST['albumIDs']), __METHOD__);
$album = new Album($_POST['albumIDs']);
Response::json($album->move());
}
// Photo functions
private static function getPhotoAction() {

@ -637,13 +637,6 @@ final class Album {
$albumID = array_splice($albumIDs, 0, 1);
$albumID = $albumID[0];
// Ensure that we don't merge an album into its own subalbum
foreach($albumIDs as $id) {
foreach($this->getSubAlbums($id) as $sid) {
if($sid == $albumID) return false;
}
}
// Move photos
$query = Database::prepare(Database::get(), "UPDATE ? SET album = ? WHERE album IN (?)", array(LYCHEE_TABLE_PHOTOS, $albumID, $this->albumIDs));
$result = Database::execute(Database::get(), $query, __METHOD__, __LINE__);
@ -672,6 +665,40 @@ final class Album {
}
/**
* @return boolean Returns true when successful.
*/
public function move() {
// Check dependencies
Validator::required(isset($this->albumIDs), __METHOD__);
// Call plugins
Plugins::get()->activate(__METHOD__, 0, func_get_args());
// Convert to array
$albumIDs = explode(',', $this->albumIDs);
// Get first albumID
$albumID = array_splice($albumIDs, 0, 1);
$albumID = $albumID[0];
// $albumIDs contains all IDs without the first albumID
// Convert to string
$filteredIDs = implode(',', $albumIDs);
// Move albums
$query = Database::prepare(Database::get(), "UPDATE ? SET parent = ? WHERE id IN (?)", array(LYCHEE_TABLE_ALBUMS, $albumID, $filteredIDs));
$result = Database::execute(Database::get(), $query, __METHOD__, __LINE__);
// Call plugins
Plugins::get()->activate(__METHOD__, 1, func_get_args());
if ($result===false) return false;
return true;
}
/**
* @return boolean Returns true when successful.
*/

@ -3,6 +3,26 @@
* @copyright 2015 by Tobias Reich
*/
const buildAlbumOptions = function(albums, select, parent = 0, layer = 0) {
var cmbxOptions = ''
for (i in albums) {
if (albums[i].parent==parent) {
let title = (layer>0 ? '  '.repeat(layer - 1) + '└ ' : '') + albums[i].title
let selected = select==albums[i].id ? ' selected="selected"' : ''
cmbxOptions += `<option${ selected } value='${ albums[i].id }'>${ title }</option>`
cmbxOptions += buildAlbumOptions(albums, select, albums[i].id, layer + 1)
}
}
return cmbxOptions
}
album = {
json: null,
@ -146,21 +166,6 @@ album.parse = function() {
}
function buildAlbumOptions(albums, select, parent = 0, layer = 0) {
var cmbxOptions = ''
for (i in albums) {
if (albums[i].parent == parent) {
let title = (layer > 0 ? "&nbsp;&nbsp;".repeat(layer - 1) + "└ " : "") + albums[i].title
cmbxOptions += `<option `;
if (select == albums[i].id)
cmbxOptions += `selected="selected" `
cmbxOptions += `value='` + albums[i].id + `'>` + title + `</option>`
cmbxOptions += buildAlbumOptions(albums, select, albums[i].id, layer + 1)
}
}
return cmbxOptions
}
album.add = function(albumID = 0) {
const action = function(data) {
@ -249,6 +254,21 @@ album.delete = function(albumIDs) {
albums.deleteByID(id)
})
} else if (visible.album()) {
// if we deleted the current album, go to its parent
if (albumIDs.length==1 && album.json.id==albumIDs[0]) {
let id = album.getParent()
album.refresh()
lychee.goto(id)
}
// otherwise, we deleted a subalbum
else {
album.reload()
}
} else {
albums.refresh()
@ -628,7 +648,7 @@ album.getArchive = function(albumID) {
}
album.merge = function(albumIDs, titles = []) {
const getMessage = function(albumIDs, titles, operation) {
let title = ''
let sTitle = ''
@ -653,14 +673,20 @@ album.merge = function(albumIDs, titles = []) {
// Fallback for second album without a title
if (sTitle==='') sTitle = 'Untitled'
msg = lychee.html`<p>Are you sure you want to merge the album '$${ sTitle }' into the album '$${ title }'?</p>`
msg = lychee.html`<p>Are you sure you want to ${ operation } the album '$${ sTitle }' into '$${ title }'?</p>`
} else {
msg = lychee.html`<p>Are you sure you want to merge all selected albums into the album '$${ title }'?</p>`
msg = lychee.html`<p>Are you sure you want to ${ operation } all selected albums into '$${ title }'?</p>`
}
return msg
}
album.merge = function(albumIDs, titles = []) {
const action = function() {
basicModal.close()
@ -671,19 +697,15 @@ album.merge = function(albumIDs, titles = []) {
api.post('Album::merge', params, function(data) {
if (data!==true) {
lychee.error(null, params, data)
} else {
albums.refresh()
lychee.goto()
}
if (data!==true) lychee.error(null, params, data)
else album.reload()
})
}
basicModal.show({
body: msg,
body: getMessage(albumIDs, titles, 'merge'),
buttons: {
action: {
title: 'Merge Albums',
@ -697,4 +719,59 @@ album.merge = function(albumIDs, titles = []) {
}
})
}
album.move = function(albumIDs, titles = []) {
const action = function() {
basicModal.close()
let params = {
albumIDs: albumIDs.join()
}
api.post('Album::move', params, function(data) {
if (data!==true) lychee.error(null, params, data)
else album.reload()
})
}
basicModal.show({
body: getMessage(albumIDs, titles, 'move'),
buttons: {
action: {
title: 'Move Albums',
fn: action,
class: 'red'
},
cancel: {
title: "Don't Move",
fn: basicModal.close
}
}
})
}
album.reload = function() {
let albumID = album.getID()
album.refresh()
albums.refresh()
if (visible.album()) lychee.goto(albumID)
else lychee.goto()
}
album.refresh = function() {
album.json = null
album.subjson = null
}

@ -15,11 +15,11 @@ build.iconic = function(icon, classes = '') {
}
build.divider = function(title) {
build.divider = function(title, id = '') {
let html = ''
html += lychee.html`<div class='divider'><h1>$${ title }</h1></div>`
html += lychee.html`<div class='divider' id='$${ id }'><h1>$${ title }</h1></div>`
return html

@ -51,6 +51,24 @@ const getAlbumFrom = function(albums, id) {
}
const getSubIDs = function(albums, albumID) {
let ids = [ albumID ]
for (a in albums) {
if (albums[a].parent==albumID) {
let sub = getSubIDs(albums, albums[a].id)
for (id in sub)
ids.push(sub[id])
}
}
return ids
}
const countSubAlbums = function(photoIDs) {
let count = 0
@ -117,12 +135,10 @@ contextMenu.album = function(albumID, e) {
if (album.isSmartID(albumID)) return false
// Show merge-item when there's more than one album
let showMerge = (albums.json && albums.json.albums && Object.keys(albums.json.albums).length>1)
let items = [
{ title: build.iconic('pencil') + 'Rename', fn: () => album.setTitle([ albumID ]) },
{ title: build.iconic('collapse-left') + 'Merge', visible: showMerge, fn: () => { basicContext.close(); contextMenu.mergeAlbum(albumID, e) } },
{ title: build.iconic('collapse-left') + 'Merge', fn: () => { basicContext.close(); contextMenu.mergeAlbum(albumID, e) } },
{ title: build.iconic('folder') + 'Move', fn: () => { basicContext.close(); contextMenu.moveAlbum([ albumID ], e) } },
{ title: build.iconic('trash') + 'Delete', fn: () => album.delete([ albumID ]) }
]
@ -140,13 +156,11 @@ contextMenu.albumMulti = function(albumIDs, e) {
// Show list of albums otherwise
let autoMerge = (albumIDs.length>1 ? true : false)
// Show merge-item when there's more than one album
let showMerge = (albums.json && albums.json.albums && Object.keys(albums.json.albums).length>1)
let items = [
{ title: build.iconic('pencil') + 'Rename All', fn: () => album.setTitle(albumIDs) },
{ title: build.iconic('collapse-left') + 'Merge All', visible: showMerge && autoMerge, fn: () => album.merge(albumIDs) },
{ title: build.iconic('collapse-left') + 'Merge', visible: showMerge && !autoMerge, fn: () => { basicContext.close(); contextMenu.mergeAlbum(albumIDs[0], e) } },
{ title: build.iconic('collapse-left') + 'Merge All', visible: autoMerge, fn: () => album.merge(albumIDs) },
{ title: build.iconic('collapse-left') + 'Merge', visible: !autoMerge, fn: () => { basicContext.close(); contextMenu.mergeAlbum(albumIDs[0], e) } },
{ title: build.iconic('folder') + 'Move All', fn: () => { basicContext.close(); contextMenu.moveAlbum(albumIDs, e) } },
{ title: build.iconic('trash') + 'Delete All', fn: () => album.delete(albumIDs) }
]
@ -193,7 +207,7 @@ contextMenu.mergeAlbum = function(albumID, e) {
// It's not possible to move them into us
let exclude = [ albumID ]
let a = getAlbumFrom(data.albums, selalbum.parent)
while (a != null) {
while (a!=null) {
exclude.push(a.id)
a = getAlbumFrom(data.albums, a.parent)
}
@ -210,6 +224,38 @@ contextMenu.mergeAlbum = function(albumID, e) {
}
contextMenu.moveAlbum = function(albumIDs, e) {
api.post('Albums::get', { parent: -1 }, function(data) {
let items = []
if (data.albums && data.num>1) {
let title = albums.getByID(albumIDs[0]).title
// Disable all childs
// It's not possible to move us into them
let exclude = []
for (i in albumIDs) {
let sub = getSubIDs(data.albums, String(albumIDs[i]))
for (s in sub)
exclude.push(sub[s])
}
items = buildAlbumList(data.albums, exclude, (a) => album.move([ a.id ].concat(albumIDs), [ a.title, title ]), 0, 1)
items.unshift({ title: 'Root', fn: () => album.move([ 0 ].concat(albumIDs), [ 'Root', title ]) })
}
if (items.length===0) return false
basicContext.show(items, e.originalEvent, contextMenu.close)
})
}
contextMenu.photo = function(photoID, e) {
// Notice for 'Move':

@ -141,8 +141,8 @@ header.setMode = function(mode) {
header.dom('.header__toolbar--album').addClass('header__toolbar--visible')
// Hide download button when album empty
if (album.json.content===false) $('#button_archive').hide()
else $('#button_archive').show()
if (album.json.content===false && album.subjson.num==0) $('#button_archive').hide()
else $('#button_archive').show()
// Hide download button when not logged in and album not downloadable
if (lychee.publicMode===true && album.json.downloadable==='0') $('#button_archive').hide()

@ -158,7 +158,7 @@ view.album = {
if (album.json.content && album.json.content!==false) {
photosData += build.divider('Photos')
photosData += build.divider('Photos', 'divider-photos')
// Build photos
$.each(album.json.content, function() {
@ -236,6 +236,7 @@ view.album = {
if (!visible.albums()) {
album.json.num--
view.album.num()
if (album.json.num == 0) $('#divider-photos').hide()
}
})

Loading…
Cancel
Save