diff --git a/Gruntfile.js b/Gruntfile.js
index 9369716..a9ec167 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -95,6 +95,12 @@ module.exports = function (grunt) {
src: ['styles/**/*', 'highlight.pack.min.js'],
dest: 'static/highlightjs'
},
+ {
+ expand: true,
+ cwd: 'node_modules/dropzone/dist/min',
+ src: ['dropzone.min.css', 'dropzone.min.js'],
+ dest: 'static/dropzone'
+ },
{expand: true, cwd: 'node_modules/jquery/dist', src: ['jquery.min.js'], dest: 'static/jquery'}
],
},
diff --git a/app/Controllers/DashboardController.php b/app/Controllers/DashboardController.php
index 0976a5f..2ed0f3e 100644
--- a/app/Controllers/DashboardController.php
+++ b/app/Controllers/DashboardController.php
@@ -59,7 +59,7 @@ class DashboardController extends Controller
return view()->render(
$response,
- ($this->session->get('admin', false) && $this->session->get('gallery_view', true)) ? 'dashboard/admin.twig' : 'dashboard/home.twig',
+ ($this->session->get('admin', false) && $this->session->get('gallery_view', true)) ? 'dashboard/list.twig' : 'dashboard/grid.twig',
[
'medias' => $query->getMedia(),
'next' => $page < floor($query->getPages()),
diff --git a/app/Controllers/UploadController.php b/app/Controllers/UploadController.php
index 38dd0c7..bb46e8c 100644
--- a/app/Controllers/UploadController.php
+++ b/app/Controllers/UploadController.php
@@ -16,6 +16,28 @@ use Slim\Exception\HttpUnauthorizedException;
class UploadController extends Controller
{
+ /**
+ * @param Request $request
+ * @param Response $response
+ * @return Response
+ * @throws \Twig\Error\LoaderError
+ * @throws \Twig\Error\RuntimeError
+ * @throws \Twig\Error\SyntaxError
+ */
+ public function webUpload(Request $request, Response $response): Response
+ {
+ $user = $this->database->query('SELECT * FROM `users` WHERE `id` = ? LIMIT 1', $this->session->get('user_id'))->fetch();
+
+ if ($user->token === null || $user->token === '') {
+ $this->session->alert(lang('no_upload_token'), 'danger');
+ return redirect($response, $request->getHeaderLine('Referer'));
+ }
+
+ return view()->render($response, 'upload/web.twig', [
+ 'user' => $user,
+ ]);
+ }
+
/**
* @param Request $request
* @param Response $response
@@ -24,7 +46,6 @@ class UploadController extends Controller
*/
public function upload(Request $request, Response $response): Response
{
-
$json = [
'message' => null,
'version' => PLATFORM_VERSION,
@@ -40,7 +61,16 @@ class UploadController extends Controller
return json($response, $json, 400);
}
- if (isset($request->getUploadedFiles()['upload']) && $request->getUploadedFiles()['upload']->getError() === UPLOAD_ERR_INI_SIZE) {
+ $file = array_values($request->getUploadedFiles());
+ /** @var \Psr\Http\Message\UploadedFileInterface|null $file */
+ $file = isset($file[0]) ? $file[0] : null;
+
+ if ($file === null) {
+ $json['message'] = 'Request without file attached.';
+ return json($response, $json, 400);
+ }
+
+ if ($file->getError() === UPLOAD_ERR_INI_SIZE) {
$json['message'] = 'File too large (upload_max_filesize too low?).';
return json($response, $json, 400);
}
@@ -66,9 +96,6 @@ class UploadController extends Controller
$code = humanRandomString();
} while ($this->database->query('SELECT COUNT(*) AS `count` FROM `uploads` WHERE `code` = ?', $code)->fetch()->count > 0);
- /** @var \Psr\Http\Message\UploadedFileInterface $file */
- $file = $request->getUploadedFiles()['upload'];
-
$fileInfo = pathinfo($file->getClientFilename());
$storagePath = "$user->user_code/$code.$fileInfo[extension]";
@@ -169,12 +196,12 @@ class UploadController extends Controller
if (!$user) {
$this->session->alert(lang('token_not_found'), 'danger');
- return redirect($response, $request->getHeaderLine('HTTP_REFERER'));
+ return redirect($response, $request->getHeaderLine('Referer'));
}
if (!$user->active) {
$this->session->alert(lang('account_disabled'), 'danger');
- return redirect($response, $request->getHeaderLine('HTTP_REFERER'));
+ return redirect($response, $request->getHeaderLine('Referer'));
}
if ($this->session->get('admin', false) || $user->id === $media->user_id) {
@@ -232,7 +259,7 @@ class UploadController extends Controller
throw new HttpNotFoundException($request);
}
- if($ext !== null && pathinfo($media->filename, PATHINFO_EXTENSION) !== $ext){
+ if ($ext !== null && pathinfo($media->filename, PATHINFO_EXTENSION) !== $ext) {
throw new HttpBadRequestException($request);
}
diff --git a/app/Controllers/UserController.php b/app/Controllers/UserController.php
index dba503d..8a77ffd 100644
--- a/app/Controllers/UserController.php
+++ b/app/Controllers/UserController.php
@@ -358,8 +358,8 @@ class UserController extends Controller
}
if ($user->token === null || $user->token === '') {
- $this->session->alert('You don\'t have a personal upload token. (Click the update token button and try again)', 'danger');
- return redirect($response, $request->getHeaderLine('HTTP_REFERER'));
+ $this->session->alert(lang('no_upload_token'), 'danger');
+ return redirect($response, $request->getHeaderLine('Referer'));
}
$json = [
@@ -404,8 +404,8 @@ class UserController extends Controller
}
if ($user->token === null || $user->token === '') {
- $this->session->alert('You don\'t have a personal upload token. (Click the update token button and try again)', 'danger');
- return redirect($response, $request->getHeaderLine('HTTP_REFERER'));
+ $this->session->alert(lang('no_upload_token'), 'danger');
+ return redirect($response, $request->getHeaderLine('Referer'));
}
return view()->render($response->withHeader('Content-Disposition', 'attachment;filename="xbackbone_uploader_'.$user->username.'.sh"'),
diff --git a/app/routes.php b/app/routes.php
index 6b63d9a..b084391 100644
--- a/app/routes.php
+++ b/app/routes.php
@@ -15,6 +15,7 @@ use Slim\Routing\RouteCollectorProxy;
global $app;
$app->group('', function (RouteCollectorProxy $group) {
$group->get('/home[/page/{page}]', [DashboardController::class, 'home'])->setName('home');
+ $group->get('/upload', [UploadController::class, 'webUpload'])->setName('upload.web');
$group->group('', function (RouteCollectorProxy $group) {
$group->get('/home/switchView', [DashboardController::class, 'switchView'])->setName('switchView');
diff --git a/composer.lock b/composer.lock
index 3d3bf30..539b4d0 100644
--- a/composer.lock
+++ b/composer.lock
@@ -1,7 +1,7 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
- "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "a5d4341b89b81518c0e488cd3bc47127",
@@ -1862,15 +1862,15 @@
"authors": [
{
"name": "Freek Van der Herten",
+ "role": "Developer",
"email": "freek@spatie.be",
- "homepage": "https://spatie.be",
- "role": "Developer"
+ "homepage": "https://spatie.be"
},
{
"name": "Alex Vanderbist",
+ "role": "Developer",
"email": "alex.vanderbist@gmail.com",
- "homepage": "https://spatie.be",
- "role": "Developer"
+ "homepage": "https://spatie.be"
}
],
"description": "A minimal implementation of Dropbox API v2",
diff --git a/install/index.php b/install/index.php
index f5c745e..d72cdcb 100644
--- a/install/index.php
+++ b/install/index.php
@@ -257,7 +257,7 @@ $app->post('/', function (Request $request, Response $response, Filesystem $stor
cleanDirectory(__DIR__.'/../resources/cache');
cleanDirectory(__DIR__.'/../resources/sessions');
- removeDirectory(__DIR__.'/../install');
+ //removeDirectory(__DIR__.'/../install');
// if is upgrading and existing installation, put it out maintenance
if ($installed) {
diff --git a/package-lock.json b/package-lock.json
index 8128818..f92e725 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3,9 +3,9 @@
"lockfileVersion": 1,
"dependencies": {
"@fortawesome/fontawesome-free": {
- "version": "5.10.2",
- "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.10.2.tgz",
- "integrity": "sha512-9pw+Nsnunl9unstGEHQ+u41wBEQue6XPBsILXtJF/4fNN1L3avJcMF/gGF86rIjeTAgfLjTY9ndm68/X4f4idQ=="
+ "version": "5.11.2",
+ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.11.2.tgz",
+ "integrity": "sha512-XiUPoS79r1G7PcpnNtq85TJ7inJWe0v+b5oZJZKb0pGHNIV6+UiNeQWiFGmuQ0aj7GEhnD/v9iqxIsjuRKtEnQ=="
},
"abbrev": {
"version": "1.1.1",
@@ -359,6 +359,11 @@
"domelementtype": "1"
}
},
+ "dropzone": {
+ "version": "5.5.1",
+ "resolved": "https://registry.npmjs.org/dropzone/-/dropzone-5.5.1.tgz",
+ "integrity": "sha512-3VduRWLxx9hbVr42QieQN25mx/I61/mRdUSuxAmDGdDqZIN8qtP7tcKMa3KfpJjuGjOJGYYUzzeq6eGDnkzesA=="
+ },
"duplexer": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
@@ -744,9 +749,9 @@
}
},
"lodash": {
- "version": "4.17.11",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
- "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
+ "version": "4.17.15",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+ "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
"dev": true
}
}
@@ -863,9 +868,9 @@
"dev": true
},
"highlightjs": {
- "version": "9.12.0",
- "resolved": "https://registry.npmjs.org/highlightjs/-/highlightjs-9.12.0.tgz",
- "integrity": "sha512-eAhWMtDZaOZIQdxIP4UEB1vNp/CVXQPdMSihTSuaExhFIRC0BVpXbtP3mTP1hDoGOyh7nbB3cuC3sOPhG5wGDA=="
+ "version": "9.16.2",
+ "resolved": "https://registry.npmjs.org/highlightjs/-/highlightjs-9.16.2.tgz",
+ "integrity": "sha512-FK1vmMj8BbEipEy8DLIvp71t5UsC7n2D6En/UfM/91PCwmOpj6f2iu0Y0coRC62KSRHHC+dquM2xMULV/X7NFg=="
},
"hooker": {
"version": "0.2.3",
@@ -1043,9 +1048,9 @@
}
},
"lodash": {
- "version": "4.17.11",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
- "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
+ "version": "4.17.15",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+ "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
"dev": true
},
"loud-rejection": {
@@ -1347,9 +1352,9 @@
}
},
"popper.js": {
- "version": "1.15.0",
- "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.15.0.tgz",
- "integrity": "sha512-w010cY1oCUmI+9KwwlWki+r5jxKfTFDVoadl7MSrIujHU5MJ5OR6HTDj6Xo8aoR/QsA56x8jKjA59qGH4ELtrA=="
+ "version": "1.16.0",
+ "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.0.tgz",
+ "integrity": "sha512-+G+EkOPoE5S/zChTpmBSSDYmhXJ5PsW8eMhH8cP/CQHMFPBG/kC9Y5IIw6qNYgdJ+/COf0ddY2li28iHaZRSjw=="
},
"pretty-bytes": {
"version": "3.0.1",
@@ -1616,9 +1621,9 @@
}
},
"tooltip.js": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/tooltip.js/-/tooltip.js-1.3.2.tgz",
- "integrity": "sha512-DeDr9JxYx/lSvQ53ZCRFLxXrmrSyU3fLz6k+ITUTw69AIYtpWij/NmOJQscJ7BwY5lcEwWJWSfqqQWVvTMYZiw==",
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/tooltip.js/-/tooltip.js-1.3.3.tgz",
+ "integrity": "sha512-XWWuy/dBdF/F/YpRE955yqBZ4VdLfiTAUdOqoU+wJm6phJlMpEzl/iYHZ+qJswbeT9VG822bNfsETF9wzmoy5A==",
"requires": {
"popper.js": "^1.0.2"
}
diff --git a/package.json b/package.json
index 4acab13..1025a71 100644
--- a/package.json
+++ b/package.json
@@ -1,13 +1,14 @@
{
"dependencies": {
- "@fortawesome/fontawesome-free": "^5.10.2",
+ "@fortawesome/fontawesome-free": "^5.11.2",
"bootstrap": "^4.3.1",
"clipboard": "^2.0.4",
- "highlightjs": "^9.12.0",
+ "dropzone": "^5.5.1",
+ "highlightjs": "^9.16.2",
"jquery": "^3.4.1",
"plyr": "^3.5.6",
- "popper.js": "^1.15.0",
- "tooltip.js": "^1.3.2"
+ "popper.js": "^1.16.0",
+ "tooltip.js": "^1.3.3"
},
"devDependencies": {
"grunt": "^1.0.4",
diff --git a/resources/lang/en.lang.php b/resources/lang/en.lang.php
index a4cc596..e736e14 100644
--- a/resources/lang/en.lang.php
+++ b/resources/lang/en.lang.php
@@ -28,6 +28,7 @@ return [
'date' => 'Date',
'raw' => 'Show raw',
'download' => 'Download',
+ 'upload' => 'Upload',
'delete' => 'Delete',
'publish' => 'Publish',
'hide' => 'Hide',
@@ -99,4 +100,5 @@ return [
'default_lang_behavior' => 'XBackBone will try to match the browser language by default (the fallback is English).',
'lang_set' => 'System language enforced to "%s"',
'prerelease_channel' => 'Prerelease Channel',
+ 'no_upload_token' => 'You don\'t have a personal upload token. (Generate one and try again)',
];
diff --git a/resources/lang/it.lang.php b/resources/lang/it.lang.php
index 738e36a..a2aaf0f 100644
--- a/resources/lang/it.lang.php
+++ b/resources/lang/it.lang.php
@@ -27,6 +27,7 @@ return [
'date' => 'Data',
'raw' => 'Vedi raw',
'download' => 'Scarica',
+ 'upload' => 'Carica',
'delete' => 'Elimina',
'publish' => 'Pubblica',
'hide' => 'Nascondi',
@@ -99,4 +100,5 @@ return [
'default_lang_behavior' => 'Per impostazione predefinita, XBackbone cercherà di abbinare la lingua del browser (il fallback è l\'Inglese).',
'lang_set' => 'Lingua di sistema applicata a "%s"',
'prerelease_channel' => 'Canale prerelease',
+ 'no_upload_token' => 'Non hai un token personale per l\'upload associato. (Generane uno e riprova)',
];
diff --git a/resources/templates/base.twig b/resources/templates/base.twig
index 0804873..79f5215 100644
--- a/resources/templates/base.twig
+++ b/resources/templates/base.twig
@@ -17,6 +17,7 @@
+
{% block head %}{% endblock %}
@@ -35,6 +36,7 @@
+