Skip to content

Commit

Permalink
add editor upload-image functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
fr0tt committed Aug 12, 2023
1 parent ab8da2a commit 9bc405a
Show file tree
Hide file tree
Showing 10 changed files with 135 additions and 32 deletions.
37 changes: 37 additions & 0 deletions app/Http/Controllers/FileController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\Facades\Image;
use Symfony\Component\HttpFoundation\Response;

class FileController extends Controller
{

public function store(Request $request)
{

$this->validate($request, [
'file' => 'image|required',
]);

$path = $request->file('file')->store('attachments');

Image::make(Storage::path($path))
->resize(1600, null, function ($constraint) {
$constraint->aspectRatio();
$constraint->upsize();
})
->interlace()
->save();

return response()->json([
'data' => [
'path' => Storage::url($path)
]
], Response::HTTP_CREATED);
}

}
2 changes: 1 addition & 1 deletion public/css/app.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/js/app.js

Large diffs are not rendered by default.

11 changes: 2 additions & 9 deletions public/js/app.js.LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*!
* Vue-Lazyload.js v1.3.4
* (c) 2021 Awe <hilongjw@gmail.com>
* Vue-Lazyload.js v1.3.5
* (c) 2023 Awe <hilongjw@gmail.com>
* Released under the MIT License.
*/

Expand All @@ -10,13 +10,6 @@
* Released under the MIT License.
*/

/*!
* is-primitive <https://github.com/jonschlinkert/is-primitive>
*
* Copyright (c) 2014-2015, Jon Schlinkert.
* Licensed under the MIT License.
*/

/*!
* tiny-cookie - A tiny cookie manipulation plugin
* https://github.com/Alex1990/tiny-cookie
Expand Down
4 changes: 2 additions & 2 deletions public/mix-manifest.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"/js/app.js": "/js/app.js?id=93eee1c6f36a1eac2b6ae126a8161940",
"/css/app.css": "/css/app.css?id=5aed6d56797605cc406c47f244b6234a"
"/js/app.js": "/js/app.js?id=a081b725095ab293461ddd140bde7126",
"/css/app.css": "/css/app.css?id=c96f213a8fd919bdba321ca0a4bd8bd0"
}
2 changes: 1 addition & 1 deletion public/service-worker.js

Large diffs are not rendered by default.

69 changes: 65 additions & 4 deletions resources/js/components/EditorMenuBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@
<div v-if="editor" class="menubar inline-block bg-gray-200 px-4 py-1">
<button class="menubar-button styles" @click="showStyles = !showStyles">
{{ style }}
<svg-vue class="editor-icon inline-block ml-2" icon="material/arrow_drop_down" />
<svg-vue
class="editor-icon inline-block ml-2"
icon="material/arrow_drop_down" />
<transition name="fade">
<ol
v-if="showStyles"
class="absolute bg-white shadow-lg z-50 text-left w-full mt-1 left-0">
<li class="style font-normal" @click="styleClick('Normal', 0)">Normal</li>
<li class="style font-normal" @click="styleClick('Normal', 0)">
Normal
</li>
<li
class="style font-black"
:class="{ 'is-active': editor.isActive('heading', { level: 1 }) }"
Expand Down Expand Up @@ -115,19 +119,34 @@
<svg-vue class="editor-icon" icon="material/art_track" />
</button>

<button class="menubar-button relative cursor-pointer" title="Image">
<input
class="absolute left-0 right-0 top-0 bottom-0 text-0 opacity-0 cursor-pointer"
type="file"
@input="uploadImage" />
<svg-vue class="editor-icon" icon="material/image" />
</button>

<i class="delimiter" />

<button class="menubar-button" title="Undo" @click="editor.chain().focus().undo().run()">
<button
class="menubar-button"
title="Undo"
@click="editor.chain().focus().undo().run()">
<svg-vue class="editor-icon" icon="material/undo" />
</button>

<button class="menubar-button" title="Redo" @click="editor.chain().focus().redo().run()">
<button
class="menubar-button"
title="Redo"
@click="editor.chain().focus().redo().run()">
<svg-vue class="editor-icon" icon="material/redo" />
</button>
</div>
</template>

<script>
import axios from 'axios'
export default {
props: ['editor'],
data() {
Expand All @@ -145,6 +164,35 @@ export default {
this.editor.chain().focus().setParagraph().run()
}
},
uploadImage() {
const file = document.querySelector('input[type=file]').files[0]
if (typeof file === 'undefined') {
return
}
const formData = new FormData()
formData.append('file', file)
axios
.post('/api/files', formData, {
headers: {
Accept: 'application/json',
},
})
.then((response) => {
if (response.status !== 201) {
return
}
const path = response.data.data.path
this.editor.commands.setImage({ src: path })
})
.catch((error) => {
this.$store.dispatch('notification/setNotification', {
type: 'error',
title: 'Error ' + error.response.status,
description: 'Image could not be uploaded.',
})
})
},
},
}
</script>
Expand All @@ -153,35 +201,48 @@ export default {
padding-top: 0.375rem;
padding-bottom: 0.375rem;
}
.text-0 {
font-size: 0rem;
}
@media (max-width: 768px) {
.menubar {
overflow-x: scroll;
white-space: nowrap;
@apply py-1.5;
}
}
.delimiter {
@apply inline-block align-middle h-6 mx-2 border border-gray-400;
}
.menubar-button {
@apply px-1 py-1 align-middle text-gray-600 font-semibold;
.editor-icon {
@apply w-6 fill-current;
}
.style {
@apply px-3 py-1.5;
}
.style:hover {
@apply bg-gray-200;
}
}
.menubar-button:hover {
@apply bg-gray-100;
}
.menubar-button.is-active,
.menubar-button .is-active {
@apply text-gray-800 bg-white;
}
.menubar-button.styles {
@apply relative px-3;
}
Expand Down
26 changes: 17 additions & 9 deletions resources/sass/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
@tailwind components;
@tailwind utilities;

@import "theme";
@import 'theme';

html {
font-family: 'Inter', 'Noto Sans', '-apple-system', 'BlinkMacSystemFont', 'Segoe UI', 'Roboto', 'Helvetica Neue', 'Arial', 'Noto Sans', 'sans-serif';
font-family: 'Inter', 'Noto Sans', '-apple-system', 'BlinkMacSystemFont', 'Segoe UI',
'Roboto', 'Helvetica Neue', 'Arial', 'Noto Sans', 'sans-serif';
}

.-ml-0\.5 {
Expand Down Expand Up @@ -94,16 +95,19 @@ label.label {
@apply block text-gray-600 font-semibold text-sm uppercase mb-2;
}

.router-fade-enter-active, .router-fade-leave-active {
transition: opacity .2s ease;
.router-fade-enter-active,
.router-fade-leave-active {
transition: opacity 0.2s ease;
}

.router-fade-enter, .router-fade-leave-to {
.router-fade-enter,
.router-fade-leave-to {
opacity: 0;
}

.open-sans {
font-family: -apple-system, BlinkMacSystemFont, 'Open Sans', 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif;
font-family: -apple-system, BlinkMacSystemFont, 'Open Sans', 'Segoe UI', Roboto,
Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif;
}

.ProseMirror {
Expand Down Expand Up @@ -133,7 +137,8 @@ label.label {
@apply text-gray-100;
}
}
ul, ol {
ul,
ol {
padding: 0 1.25rem;
}
ul {
Expand All @@ -142,7 +147,7 @@ label.label {
ol {
list-style-type: decimal;
}
ul[data-type=taskList] {
ul[data-type='taskList'] {
list-style: none;
padding: 0;
li {
Expand All @@ -168,6 +173,9 @@ label.label {
@apply mt-4 mb-4;
border-top: 2px solid #e6e6e6;
}
img.ProseMirror-selectednode {
outline: 1.5px solid #000;
}
}

.vue-treeselect {
Expand Down Expand Up @@ -198,4 +206,4 @@ label.label {
@apply text-orange-500 bg-orange-200 font-medium;
}
}
}
}
1 change: 1 addition & 0 deletions resources/svg/material/image.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 8 additions & 5 deletions routes/api.php
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
<?php

use App\Http\Controllers\AuthController;
use App\Http\Controllers\CollectionController;
use App\Http\Controllers\ExportController;
use App\Http\Controllers\FileController;
use App\Http\Controllers\ImportController;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\AuthController;
use App\Http\Controllers\UserController;
use App\Http\Controllers\PostController;
use App\Http\Controllers\CollectionController;
use App\Http\Controllers\ShareController;
use App\Http\Controllers\TestingController;
use App\Http\Controllers\TagController;
use App\Http\Controllers\ShareController;
use App\Http\Controllers\UserController;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
Expand Down Expand Up @@ -63,6 +64,8 @@
Route::patch('shares/{id}', [ShareController::class, 'update']);
Route::delete('shares/{id}', [ShareController::class, 'destroy']);

Route::post('files', [FileController::class, 'store']);

Route::post('imports', [ImportController::class, 'store']);
Route::get('exports', [ExportController::class, 'index']);

Expand Down

0 comments on commit 9bc405a

Please sign in to comment.