Merge pull request #1397 from owncloud/trash_fileactions
Enable fileactions while viewing trash
This commit is contained in:
commit
6d4b344f5d
|
@ -26,7 +26,7 @@ OCP\User::checkLoggedIn();
|
||||||
|
|
||||||
$filename = $_GET["file"];
|
$filename = $_GET["file"];
|
||||||
|
|
||||||
$view = new OC_FilesystemView('/'.\OCP\User::getUser().'/files_trashbin');
|
$view = new OC_FilesystemView('/'.\OCP\User::getUser().'/files_trashbin/files');
|
||||||
|
|
||||||
if(!$view->file_exists($filename)) {
|
if(!$view->file_exists($filename)) {
|
||||||
header("HTTP/1.0 404 Not Found");
|
header("HTTP/1.0 404 Not Found");
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
// Check if we are a user
|
// Check if we are a user
|
||||||
OCP\User::checkLoggedIn();
|
OCP\User::checkLoggedIn();
|
||||||
|
|
||||||
|
OCP\App::setActiveNavigationEntry('files_index');
|
||||||
|
|
||||||
OCP\Util::addScript('files_trashbin', 'trash');
|
OCP\Util::addScript('files_trashbin', 'trash');
|
||||||
OCP\Util::addScript('files_trashbin', 'disableDefaultActions');
|
OCP\Util::addScript('files_trashbin', 'disableDefaultActions');
|
||||||
OCP\Util::addScript('files', 'fileactions');
|
OCP\Util::addScript('files', 'fileactions');
|
||||||
|
@ -41,7 +43,7 @@ if ($dir) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$dirlisting = false;
|
$dirlisting = false;
|
||||||
$query = \OC_DB::prepare('SELECT id,location,timestamp,type,mime FROM *PREFIX*files_trash WHERE user=?');
|
$query = \OC_DB::prepare('SELECT `id`,`location`,`timestamp`,`type`,`mime` FROM `*PREFIX*files_trash` WHERE user = ?');
|
||||||
$result = $query->execute(array($user))->fetchAll();
|
$result = $query->execute(array($user))->fetchAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,6 +68,18 @@ foreach ($result as $r) {
|
||||||
$files[] = $i;
|
$files[] = $i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function fileCmp($a, $b) {
|
||||||
|
if ($a['type'] == 'dir' and $b['type'] != 'dir') {
|
||||||
|
return -1;
|
||||||
|
} elseif ($a['type'] != 'dir' and $b['type'] == 'dir') {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return strnatcasecmp($a['name'], $b['name']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
usort($files, "fileCmp");
|
||||||
|
|
||||||
// Make breadcrumb
|
// Make breadcrumb
|
||||||
$pathtohere = '';
|
$pathtohere = '';
|
||||||
$breadcrumb = array();
|
$breadcrumb = array();
|
||||||
|
@ -93,9 +107,9 @@ $list->assign('disableSharing', true);
|
||||||
$list->assign('dirlisting', $dirlisting);
|
$list->assign('dirlisting', $dirlisting);
|
||||||
$list->assign('disableDownloadActions', true);
|
$list->assign('disableDownloadActions', true);
|
||||||
$tmpl->assign('breadcrumb', $breadcrumbNav->fetchPage(), false);
|
$tmpl->assign('breadcrumb', $breadcrumbNav->fetchPage(), false);
|
||||||
|
$tmpl->assign('dirlisting', $dirlisting);
|
||||||
$tmpl->assign('fileList', $list->fetchPage(), false);
|
$tmpl->assign('fileList', $list->fetchPage(), false);
|
||||||
$tmpl->assign('files', $files);
|
$tmpl->assign('files', $files);
|
||||||
$tmpl->assign('dirlisting', $dirlisting);
|
$tmpl->assign('dir', \OC\Files\Filesystem::normalizePath($view->getAbsolutePath()));
|
||||||
$tmpl->assign('dir', OC_Filesystem::normalizePath($view->getAbsolutePath()));
|
|
||||||
|
|
||||||
$tmpl->printPage();
|
$tmpl->printPage();
|
||||||
|
|
|
@ -141,6 +141,29 @@ $(document).ready(function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#fileList').on('click', 'td.filename a', function(event) {
|
||||||
|
var mime = $(this).parent().parent().data('mime');
|
||||||
|
if (mime !== 'httpd/unix-directory') {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
var filename = $(this).parent().parent().attr('data-file');
|
||||||
|
var tr = $('tr').filterAttr('data-file',filename);
|
||||||
|
var renaming = tr.data('renaming');
|
||||||
|
if(!renaming && !FileList.isLoading(filename)){
|
||||||
|
if(mime.substr(0, 5) === 'text/'){ //no texteditor for now
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var type = $(this).parent().parent().data('type');
|
||||||
|
var permissions = $(this).parent().parent().data('permissions');
|
||||||
|
var action = FileActions.getDefault(mime, type, permissions);
|
||||||
|
if(action){
|
||||||
|
event.preventDefault();
|
||||||
|
action(filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
FileActions.actions.dir = {};
|
||||||
});
|
});
|
||||||
|
|
||||||
function processSelection(){
|
function processSelection(){
|
||||||
|
@ -206,4 +229,8 @@ function getSelectedFiles(property){
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function fileDownloadPath(dir, file) {
|
||||||
|
return OC.filePath('files_trashbin', '', 'download.php') + '?file='+encodeURIComponent(file);
|
||||||
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ class Trashbin {
|
||||||
|
|
||||||
$trashbinSize = self::getTrashbinSize($user);
|
$trashbinSize = self::getTrashbinSize($user);
|
||||||
if ( $trashbinSize === false || $trashbinSize < 0 ) {
|
if ( $trashbinSize === false || $trashbinSize < 0 ) {
|
||||||
$trashbinSize = self::calculateSize(new \OC_FilesystemView('/'. $user.'/files_trashbin'));
|
$trashbinSize = self::calculateSize(new \OC\Files\View('/'. $user.'/files_trashbin'));
|
||||||
}
|
}
|
||||||
$trashbinSize += self::copy_recursive($file_path, 'files_trashbin/files/'.$deleted.'.d'.$timestamp, $view);
|
$trashbinSize += self::copy_recursive($file_path, 'files_trashbin/files/'.$deleted.'.d'.$timestamp, $view);
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ class Trashbin {
|
||||||
// Take care of file versions
|
// Take care of file versions
|
||||||
if ( \OCP\App::isEnabled('files_versions') ) {
|
if ( \OCP\App::isEnabled('files_versions') ) {
|
||||||
if ( $view->is_dir('files_versions'.$file_path) ) {
|
if ( $view->is_dir('files_versions'.$file_path) ) {
|
||||||
$trashbinSize += self::calculateSize(new \OC_FilesystemView('/'. $user.'/files_versions/'.$file_path));
|
$trashbinSize += self::calculateSize(new \OC\Files\View('/'. $user.'/files_versions/'.$file_path));
|
||||||
$view->rename('files_versions'.$file_path, 'files_trashbin/versions'. $deleted.'.d'.$timestamp);
|
$view->rename('files_versions'.$file_path, 'files_trashbin/versions'. $deleted.'.d'.$timestamp);
|
||||||
} else if ( $versions = \OCA\Files_Versions\Storage::getVersions($user, $file_path) ) {
|
} else if ( $versions = \OCA\Files_Versions\Storage::getVersions($user, $file_path) ) {
|
||||||
foreach ($versions as $v) {
|
foreach ($versions as $v) {
|
||||||
|
@ -86,10 +86,10 @@ class Trashbin {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Take care of encryption keys
|
// Take care of encryption keys
|
||||||
$keyfile = \OC_Filesystem::normalizePath('files_encryption/keyfiles/'.$file_path);
|
$keyfile = \OC\Files\Filesystem::normalizePath('files_encryption/keyfiles/'.$file_path);
|
||||||
if ( \OCP\App::isEnabled('files_encryption') && $view->file_exists($keyfile.'.key') ) {
|
if ( \OCP\App::isEnabled('files_encryption') && $view->file_exists($keyfile.'.key') ) {
|
||||||
if ( $view->is_dir('files'.$file_path) ) {
|
if ( $view->is_dir('files'.$file_path) ) {
|
||||||
$trashbinSize += self::calculateSize(new \OC_FilesystemView('/'.$user.'/'.$keyfile));
|
$trashbinSize += self::calculateSize(new \OC\Files\View('/'.$user.'/'.$keyfile));
|
||||||
$view->rename($keyfile, 'files_trashbin/keyfiles/'. $deleted.'.d'.$timestamp);
|
$view->rename($keyfile, 'files_trashbin/keyfiles/'. $deleted.'.d'.$timestamp);
|
||||||
} else {
|
} else {
|
||||||
$trashbinSize += $view->filesize($keyfile.'.key');
|
$trashbinSize += $view->filesize($keyfile.'.key');
|
||||||
|
@ -102,7 +102,7 @@ class Trashbin {
|
||||||
|
|
||||||
// get available disk space for user
|
// get available disk space for user
|
||||||
$quota = \OC_Preferences::getValue($user, 'files', 'quota');
|
$quota = \OC_Preferences::getValue($user, 'files', 'quota');
|
||||||
if ( $quota === null ) {
|
if ( $quota === null || $quota === 'default') {
|
||||||
$quota = \OC_Appconfig::getValue('files', 'default_quota');
|
$quota = \OC_Appconfig::getValue('files', 'default_quota');
|
||||||
}
|
}
|
||||||
if ( $quota === null ) {
|
if ( $quota === null ) {
|
||||||
|
@ -134,11 +134,11 @@ class Trashbin {
|
||||||
*/
|
*/
|
||||||
public static function restore($file, $filename, $timestamp) {
|
public static function restore($file, $filename, $timestamp) {
|
||||||
$user = \OCP\User::getUser();
|
$user = \OCP\User::getUser();
|
||||||
$view = new \OC_FilesystemView('/'.$user);
|
$view = new \OC\Files\View('/'.$user);
|
||||||
|
|
||||||
$trashbinSize = self::getTrashbinSize($user);
|
$trashbinSize = self::getTrashbinSize($user);
|
||||||
if ( $trashbinSize === false || $trashbinSize < 0 ) {
|
if ( $trashbinSize === false || $trashbinSize < 0 ) {
|
||||||
$trashbinSize = self::calculateSize(new \OC_FilesystemView('/'. $user.'/files_trashbin'));
|
$trashbinSize = self::calculateSize(new \OC\Files\View('/'. $user.'/files_trashbin'));
|
||||||
}
|
}
|
||||||
if ( $timestamp ) {
|
if ( $timestamp ) {
|
||||||
$query = \OC_DB::prepare('SELECT location,type FROM *PREFIX*files_trash'
|
$query = \OC_DB::prepare('SELECT location,type FROM *PREFIX*files_trash'
|
||||||
|
@ -165,8 +165,8 @@ class Trashbin {
|
||||||
$location = '';
|
$location = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$source = \OC_Filesystem::normalizePath('files_trashbin/files/'.$file);
|
$source = \OC\Files\Filesystem::normalizePath('files_trashbin/files/'.$file);
|
||||||
$target = \OC_Filesystem::normalizePath('files/'.$location.'/'.$filename);
|
$target = \OC\Files\Filesystem::normalizePath('files/'.$location.'/'.$filename);
|
||||||
|
|
||||||
// we need a extension in case a file/dir with the same name already exists
|
// we need a extension in case a file/dir with the same name already exists
|
||||||
$ext = self::getUniqueExtension($location, $filename, $view);
|
$ext = self::getUniqueExtension($location, $filename, $view);
|
||||||
|
@ -174,7 +174,7 @@ class Trashbin {
|
||||||
if( $view->rename($source, $target.$ext) ) {
|
if( $view->rename($source, $target.$ext) ) {
|
||||||
$view->touch($target.$ext, $mtime);
|
$view->touch($target.$ext, $mtime);
|
||||||
if ($view->is_dir($target.$ext)) {
|
if ($view->is_dir($target.$ext)) {
|
||||||
$trashbinSize -= self::calculateSize(new \OC_FilesystemView('/'.$user.'/'.$target.$ext));
|
$trashbinSize -= self::calculateSize(new \OC\Files\View('/'.$user.'/'.$target.$ext));
|
||||||
} else {
|
} else {
|
||||||
$trashbinSize -= $view->filesize($target.$ext);
|
$trashbinSize -= $view->filesize($target.$ext);
|
||||||
}
|
}
|
||||||
|
@ -186,8 +186,8 @@ class Trashbin {
|
||||||
$versionedFile = $file;
|
$versionedFile = $file;
|
||||||
}
|
}
|
||||||
if ( $result[0]['type'] === 'dir' ) {
|
if ( $result[0]['type'] === 'dir' ) {
|
||||||
$trashbinSize -= self::calculateSize(new \OC_FilesystemView('/'.$user.'/'.'files_trashbin/versions/'. $file));
|
$trashbinSize -= self::calculateSize(new \OC\Files\View('/'.$user.'/'.'files_trashbin/versions/'. $file));
|
||||||
$view->rename(\OC_Filesystem::normalizePath('files_trashbin/versions/'. $file), \OC_Filesystem::normalizePath('files_versions/'.$location.'/'.$filename.$ext));
|
$view->rename(\OC\Files\Filesystem::normalizePath('files_trashbin/versions/'. $file), \OC\Files\Filesystem::normalizePath('files_versions/'.$location.'/'.$filename.$ext));
|
||||||
} else if ( $versions = self::getVersionsFromTrash($versionedFile, $timestamp) ) {
|
} else if ( $versions = self::getVersionsFromTrash($versionedFile, $timestamp) ) {
|
||||||
foreach ($versions as $v) {
|
foreach ($versions as $v) {
|
||||||
if ($timestamp ) {
|
if ($timestamp ) {
|
||||||
|
@ -204,16 +204,16 @@ class Trashbin {
|
||||||
// Take care of encryption keys TODO! Get '.key' in file between file name and delete date (also for permanent delete!)
|
// Take care of encryption keys TODO! Get '.key' in file between file name and delete date (also for permanent delete!)
|
||||||
$parts = pathinfo($file);
|
$parts = pathinfo($file);
|
||||||
if ( $result[0]['type'] === 'dir' ) {
|
if ( $result[0]['type'] === 'dir' ) {
|
||||||
$keyfile = \OC_Filesystem::normalizePath('files_trashbin/keyfiles/'.$parts['dirname'].'/'.$filename);
|
$keyfile = \OC\Files\Filesystem::normalizePath('files_trashbin/keyfiles/'.$parts['dirname'].'/'.$filename);
|
||||||
} else {
|
} else {
|
||||||
$keyfile = \OC_Filesystem::normalizePath('files_trashbin/keyfiles/'.$parts['dirname'].'/'.$filename.'.key');
|
$keyfile = \OC\Files\Filesystem::normalizePath('files_trashbin/keyfiles/'.$parts['dirname'].'/'.$filename.'.key');
|
||||||
}
|
}
|
||||||
if ($timestamp) {
|
if ($timestamp) {
|
||||||
$keyfile .= '.d'.$timestamp;
|
$keyfile .= '.d'.$timestamp;
|
||||||
}
|
}
|
||||||
if ( \OCP\App::isEnabled('files_encryption') && $view->file_exists($keyfile) ) {
|
if ( \OCP\App::isEnabled('files_encryption') && $view->file_exists($keyfile) ) {
|
||||||
if ( $result[0]['type'] === 'dir' ) {
|
if ( $result[0]['type'] === 'dir' ) {
|
||||||
$trashbinSize -= self::calculateSize(new \OC_FilesystemView('/'.$user.'/'.$keyfile));
|
$trashbinSize -= self::calculateSize(new \OC\Files\View('/'.$user.'/'.$keyfile));
|
||||||
$view->rename($keyfile, 'files_encryption/keyfiles/'. $location.'/'.$filename);
|
$view->rename($keyfile, 'files_encryption/keyfiles/'. $location.'/'.$filename);
|
||||||
} else {
|
} else {
|
||||||
$trashbinSize -= $view->filesize($keyfile);
|
$trashbinSize -= $view->filesize($keyfile);
|
||||||
|
@ -244,12 +244,12 @@ class Trashbin {
|
||||||
*/
|
*/
|
||||||
public static function delete($filename, $timestamp=null) {
|
public static function delete($filename, $timestamp=null) {
|
||||||
$user = \OCP\User::getUser();
|
$user = \OCP\User::getUser();
|
||||||
$view = new \OC_FilesystemView('/'.$user);
|
$view = new \OC\Files\View('/'.$user);
|
||||||
$size = 0;
|
$size = 0;
|
||||||
|
|
||||||
$trashbinSize = self::getTrashbinSize($user);
|
$trashbinSize = self::getTrashbinSize($user);
|
||||||
if ( $trashbinSize === false || $trashbinSize < 0 ) {
|
if ( $trashbinSize === false || $trashbinSize < 0 ) {
|
||||||
$trashbinSize = self::calculateSize(new \OC_FilesystemView('/'. $user.'/files_trashbin'));
|
$trashbinSize = self::calculateSize(new \OC\Files\View('/'. $user.'/files_trashbin'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $timestamp ) {
|
if ( $timestamp ) {
|
||||||
|
@ -262,7 +262,7 @@ class Trashbin {
|
||||||
|
|
||||||
if ( \OCP\App::isEnabled('files_versions') ) {
|
if ( \OCP\App::isEnabled('files_versions') ) {
|
||||||
if ($view->is_dir('files_trashbin/versions/'.$file)) {
|
if ($view->is_dir('files_trashbin/versions/'.$file)) {
|
||||||
$size += self::calculateSize(new \OC_Filesystemview('/'.$user.'/files_trashbin/versions/'.$file));
|
$size += self::calculateSize(new \OC\Files\view('/'.$user.'/files_trashbin/versions/'.$file));
|
||||||
$view->unlink('files_trashbin/versions/'.$file);
|
$view->unlink('files_trashbin/versions/'.$file);
|
||||||
} else if ( $versions = self::getVersionsFromTrash($filename, $timestamp) ) {
|
} else if ( $versions = self::getVersionsFromTrash($filename, $timestamp) ) {
|
||||||
foreach ($versions as $v) {
|
foreach ($versions as $v) {
|
||||||
|
@ -280,16 +280,16 @@ class Trashbin {
|
||||||
// Take care of encryption keys
|
// Take care of encryption keys
|
||||||
$parts = pathinfo($file);
|
$parts = pathinfo($file);
|
||||||
if ( $view->is_dir('/files_trashbin/files/'.$file) ) {
|
if ( $view->is_dir('/files_trashbin/files/'.$file) ) {
|
||||||
$keyfile = \OC_Filesystem::normalizePath('files_trashbin/keyfiles/'.$filename);
|
$keyfile = \OC\Files\Filesystem::normalizePath('files_trashbin/keyfiles/'.$filename);
|
||||||
} else {
|
} else {
|
||||||
$keyfile = \OC_Filesystem::normalizePath('files_trashbin/keyfiles/'.$filename.'.key');
|
$keyfile = \OC\Files\Filesystem::normalizePath('files_trashbin/keyfiles/'.$filename.'.key');
|
||||||
}
|
}
|
||||||
if ($timestamp) {
|
if ($timestamp) {
|
||||||
$keyfile .= '.d'.$timestamp;
|
$keyfile .= '.d'.$timestamp;
|
||||||
}
|
}
|
||||||
if ( \OCP\App::isEnabled('files_encryption') && $view->file_exists($keyfile) ) {
|
if ( \OCP\App::isEnabled('files_encryption') && $view->file_exists($keyfile) ) {
|
||||||
if ( $view->is_dir($keyfile) ) {
|
if ( $view->is_dir($keyfile) ) {
|
||||||
$size += self::calculateSize(new \OC_FilesystemView('/'.$user.'/'.$keyfile));
|
$size += self::calculateSize(new \OC\Files\View('/'.$user.'/'.$keyfile));
|
||||||
} else {
|
} else {
|
||||||
$size += $view->filesize($keyfile);
|
$size += $view->filesize($keyfile);
|
||||||
}
|
}
|
||||||
|
@ -297,7 +297,7 @@ class Trashbin {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($view->is_dir('/files_trashbin/files/'.$file)) {
|
if ($view->is_dir('/files_trashbin/files/'.$file)) {
|
||||||
$size += self::calculateSize(new \OC_Filesystemview('/'.$user.'/files_trashbin/files/'.$file));
|
$size += self::calculateSize(new \OC\Files\View('/'.$user.'/files_trashbin/files/'.$file));
|
||||||
} else {
|
} else {
|
||||||
$size += $view->filesize('/files_trashbin/files/'.$file);
|
$size += $view->filesize('/files_trashbin/files/'.$file);
|
||||||
}
|
}
|
||||||
|
@ -316,7 +316,7 @@ class Trashbin {
|
||||||
*/
|
*/
|
||||||
public static function file_exists($filename, $timestamp=null) {
|
public static function file_exists($filename, $timestamp=null) {
|
||||||
$user = \OCP\User::getUser();
|
$user = \OCP\User::getUser();
|
||||||
$view = new \OC_FilesystemView('/'.$user);
|
$view = new \OC\Files\View('/'.$user);
|
||||||
|
|
||||||
if ($timestamp) {
|
if ($timestamp) {
|
||||||
$filename = $filename.'.d'.$timestamp;
|
$filename = $filename.'.d'.$timestamp;
|
||||||
|
@ -324,7 +324,7 @@ class Trashbin {
|
||||||
$filename = $filename;
|
$filename = $filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
$target = \OC_Filesystem::normalizePath('files_trashbin/files/'.$filename);
|
$target = \OC\Files\Filesystem::normalizePath('files_trashbin/files/'.$filename);
|
||||||
return $view->file_exists($target);
|
return $view->file_exists($target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,7 +335,7 @@ class Trashbin {
|
||||||
private static function expire($availableSpace) {
|
private static function expire($availableSpace) {
|
||||||
|
|
||||||
$user = \OCP\User::getUser();
|
$user = \OCP\User::getUser();
|
||||||
$view = new \OC_FilesystemView('/'.$user);
|
$view = new \OC\Files\View('/'.$user);
|
||||||
$size = 0;
|
$size = 0;
|
||||||
|
|
||||||
$query = \OC_DB::prepare('SELECT location,type,id,timestamp FROM *PREFIX*files_trash WHERE user=?');
|
$query = \OC_DB::prepare('SELECT location,type,id,timestamp FROM *PREFIX*files_trash WHERE user=?');
|
||||||
|
@ -410,7 +410,7 @@ class Trashbin {
|
||||||
* @param $timestamp timestamp when the file was deleted
|
* @param $timestamp timestamp when the file was deleted
|
||||||
*/
|
*/
|
||||||
private static function getVersionsFromTrash($filename, $timestamp) {
|
private static function getVersionsFromTrash($filename, $timestamp) {
|
||||||
$view = new \OC_FilesystemView('/'.\OCP\User::getUser().'/files_trashbin/versions');
|
$view = new \OC\Files\View('/'.\OCP\User::getUser().'/files_trashbin/versions');
|
||||||
$versionsName = \OCP\Config::getSystemValue('datadirectory').$view->getAbsolutePath($filename);
|
$versionsName = \OCP\Config::getSystemValue('datadirectory').$view->getAbsolutePath($filename);
|
||||||
$versions = array();
|
$versions = array();
|
||||||
if ($timestamp ) {
|
if ($timestamp ) {
|
||||||
|
|
Loading…
Reference in New Issue