Skip to content

Commit

Permalink
v3.0.0
Browse files Browse the repository at this point in the history
- use a unique id for the zip progress tracking to avoid issues with multiple download of the same zip at the same time

- add auto invalidate cache option, note that to keep things as performance friendly while making sure the cache invalidation updates as regularly as possible, every time the user navigate into a folder the invalidation check will fire.

- add new enhancement to stop scrolling the main page when the manager scroll has reached the end “i focken hated that”

- updated resources
- update readme
  • Loading branch information
ctf0 committed Apr 23, 2018
1 parent 55b84d4 commit 80c4c89
Show file tree
Hide file tree
Showing 13 changed files with 121 additions and 66 deletions.
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@
- install dependencies

```bash
yarn add vue vue-ls vue-tippy@v1 vue2-filters vue-bounty vue-notif vue-clipboard2 vue-awesome@v2 vue-touch@next idb-keyval axios dropzone cropperjs keycode babel-preset-es2015-node6 babel-preset-stage-2
yarn add vue vue-ls vue-tippy@v1 vue2-filters vue-bounty vue-notif vue-clipboard2 vue-awesome@v2 vue-touch@next vue-scroll-stop idb-keyval axios dropzone cropperjs keycode babel-preset-es2015-node6 babel-preset-stage-2
# or
npm install vue vue-ls vue-tippy@v1 vue2-filters vue-bounty vue-notif vue-clipboard2 vue-awesome@v2 vue-touch@next idb-keyval axios dropzone cropperjs keycode babel-preset-es2015-node6 babel-preset-stage-2 --save
npm install vue vue-ls vue-tippy@v1 vue2-filters vue-bounty vue-notif vue-clipboard2 vue-awesome@v2 vue-touch@next vue-scroll-stop idb-keyval axios dropzone cropperjs keycode babel-preset-es2015-node6 babel-preset-stage-2 --save
```

- add this one liner to your main js file and run `npm run watch` to compile your `js/css` files.
Expand Down Expand Up @@ -221,6 +221,12 @@ return [
* load image preview when item is clicked
*/
'lazy_load_image_on_click' => false,

/*
* automatically invalidate cache after ?
* in "Minutes"
*/
'cacheExpiresAfter'=> 60,
];
```

Expand All @@ -230,4 +236,3 @@ return [

- visit `localhost:8000/media`
- [Wiki](https://github.com/ctf0/Laravel-Media-Manager/wiki)
- [Cacheing Strategy](https://github.com/ctf0/Laravel-Media-Manager/issues/29)
5 changes: 0 additions & 5 deletions logs/v2.6.0.txt

This file was deleted.

8 changes: 8 additions & 0 deletions logs/v3.0.0.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
- use a unique id for the zip progress tracking to avoid issues with multiple download of the same zip at the same time

- add auto invalidate cache option, note that to keep things as performance friendly while making sure the cache invalidation updates as regularly as possible, every time the user navigate into a folder the invalidation check will fire.

- add new enhancement to stop scrolling the main page when the manager scroll has reached the end “i focken hated that”

- updated resources
- update readme
29 changes: 17 additions & 12 deletions src/Controllers/MediaController.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class MediaController extends Controller
{
use OpsTrait;

protected $config;
protected $baseUrl;
protected $carbon;
protected $db;
Expand All @@ -28,21 +29,20 @@ class MediaController extends Controller

public function __construct(Carbon $carbon)
{
$config = config('mediaManager');

$this->carbon = $carbon;
$this->fileSystem = array_get($config, 'storage_disk');
$this->config = config('mediaManager');
$this->fileSystem = array_get($this->config, 'storage_disk');
$this->storageDisk = app('filesystem')->disk($this->fileSystem);
$this->baseUrl = $this->storageDisk->url('/');
$this->ignoreFiles = array_get($config, 'ignore_files');
$this->fileChars = array_get($config, 'allowed_fileNames_chars');
$this->folderChars = array_get($config, 'allowed_folderNames_chars');
$this->sanitizedText = array_get($config, 'sanitized_text');
$this->unallowedMimes = array_get($config, 'unallowed_mimes');
$this->LMF = array_get($config, 'last_modified_format');
$this->ignoreFiles = array_get($this->config, 'ignore_files');
$this->fileChars = array_get($this->config, 'allowed_fileNames_chars');
$this->folderChars = array_get($this->config, 'allowed_folderNames_chars');
$this->sanitizedText = array_get($this->config, 'sanitized_text');
$this->unallowedMimes = array_get($this->config, 'unallowed_mimes');
$this->LMF = array_get($this->config, 'last_modified_format');
$this->db = app('db')->connection('mediamanager')->table('locked');
$this->storageDiskInfo = config("filesystems.disks.{$this->fileSystem}");
$this->zipCacheStore = app('cache')->store('mediamanager');
$this->storageDiskInfo = config("filesystems.disks.{$this->fileSystem}");

$this->storageDisk->addPlugin(new ListWith());
}
Expand All @@ -54,7 +54,10 @@ public function __construct(Carbon $carbon)
*/
public function index()
{
return view('MediaManager::media');
return view('MediaManager::media')->with([
'randId' => uniqid(),
'cacheExp' => array_get($this->config, 'cacheExpiresAfter'),
]);
}

/**
Expand Down Expand Up @@ -600,6 +603,7 @@ public function folder_download(Request $request)
{
return $this->download(
$request->name,
$request->id,
$this->storageDisk->allFiles("{$request->folders}/$request->name"),
'folder'
);
Expand All @@ -616,6 +620,7 @@ public function files_download(Request $request)
{
return $this->download(
$request->name . '-files',
$request->id,
json_decode($request->list, true),
'files'
);
Expand All @@ -634,7 +639,7 @@ public function zip_progress(Request $request)

// params
$id = $request->header('last-event-id');
$name = $request->name;
$name = "{$request->name}-{$request->id}";

// get changes
$store = $this->zipCacheStore;
Expand Down
15 changes: 9 additions & 6 deletions src/Controllers/OpsTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -196,15 +196,18 @@ protected function storeFile($item, $upload_path, $file_name)
* @param mixed $name
* @param mixed $list
* @param mixed $type
* @param mixed $id
*/
protected function download($name, $list, $type)
protected function download($name, $id, $list, $type)
{
$cacheName = "$name-$id";

// track changes
$counter = 100 / count($list);
$store = $this->zipCacheStore;
$store->forever("$name.progress", 0);
$store->forever("$cacheName.progress", 0);

return response()->stream(function () use ($name, $list, $type, $counter, $store) {
return response()->stream(function () use ($name, $list, $type, $counter, $store, $cacheName) {
$zip = new ZipStream("$name.zip", [
'content_type' => 'application/octet-stream',
]);
Expand All @@ -219,14 +222,14 @@ protected function download($name, $list, $type)
}

if ($streamRead) {
$store->increment("$name.progress", round($counter, 2));
$store->increment("$cacheName.progress", round($counter, 2));
$zip->addFileFromStream($file_name, $streamRead);
} else {
$store->forever("$name.warn", $file_name);
$store->forever("$cacheName.warn", $file_name);
}
}

$store->forever("$name.done", true);
$store->forever("$cacheName.done", true);
$zip->finish();
});
}
Expand Down
2 changes: 1 addition & 1 deletion src/MediaRoutes.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public static function routes()
app('router')->post('change_vis', ['uses' => "$controller@change_vis", 'as' => 'change_vis']);
app('router')->post('lock_file', ['uses' => "$controller@lock_file", 'as' => 'lock_file']);

app('router')->get('zip_progress/{name?}', ['uses' => "$controller@zip_progress", 'as' => 'zip_progress']);
app('router')->get('zip_progress/{name?}/{id?}', ['uses' => "$controller@zip_progress", 'as' => 'zip_progress']);
app('router')->post('folder_download', ['uses' => "$controller@folder_download", 'as' => 'folder_download']);
app('router')->post('files_download', ['uses' => "$controller@files_download", 'as' => 'files_download']);
});
Expand Down
6 changes: 6 additions & 0 deletions src/config/mediaManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,10 @@
* load image preview when item is clicked
*/
'lazy_load_image_on_click' => false,

/*
* automatically invalidate cache after ?
* in "Minutes"
*/
'cacheExpiresAfter'=> 60,
];
22 changes: 8 additions & 14 deletions src/resources/assets/js/components/media.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ export default {
'zipProgressRoute',
'uploadPanelImgList',
'hideExt',
'hidePath'
'hidePath',
'cacheExp'
],
data() {
return {
Expand Down Expand Up @@ -99,8 +100,12 @@ export default {
},
created() {
document.addEventListener('keydown', this.shortCuts)
this.preSaved()
this.getFiles(this.folders, null, this.selectedFile)
this.invalidateCache().then(() => {
this.preSaved()
this.getFiles(this.folders, null, this.selectedFile)
})
},
mounted() {
this.fileUpload()
Expand All @@ -122,17 +127,6 @@ export default {
document.removeEventListener('keydown', this.shortCuts)
},
methods: {
preSaved() {
let ls = this.getLs()
if (ls) {
this.randomNames = ls.randomNames === undefined ? false : ls.randomNames
this.folders = ls.folders === undefined ? [] : ls.folders
this.toolBar = ls.toolBar === undefined ? true : ls.toolBar
this.selectedFile = ls.selectedFileName === undefined ? null : ls.selectedFileName
}
},
shortCuts(e) {
let key = keycode(e)
Expand Down
5 changes: 3 additions & 2 deletions src/resources/assets/js/manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ window.Dropzone = require('dropzone')
Vue.use(require('vue2-filters'))
Vue.use(require('vue-clipboard2'))
Vue.use(require('vue-ls'))
Vue.use(require('vue-scroll-stop'))

// vue-tippy
Vue.use(require('vue-tippy'), {
Expand Down Expand Up @@ -36,8 +37,8 @@ axios.defaults.headers.common = {
'X-Requested-With': 'XMLHttpRequest'
}
axios.interceptors.response.use(
(response) => {return response},
(error) => {return Promise.reject(error.response)}
(response) => response,
(error) => Promise.reject(error.response)
)

// vue-awesome
Expand Down
65 changes: 48 additions & 17 deletions src/resources/assets/js/modules/cache.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { Store, set, get, del, clear } from 'idb-keyval'
const idbKeyVal = new Store(
import addMinutes from 'date-fns/add_minutes'
import getTime from 'date-fns/get_time'

import { Store, get, set, del, clear, keys } from 'idb-keyval'
const cacheStore = new Store(
'ctf0-Media_Manager', // db
'laravel-media-manager' // store
)
Expand All @@ -11,26 +14,36 @@ export default {
return this.$ls.get('ctf0-Media_Manager', {})
},
updateLs(obj) {
let storage = this.getLs()

Object.assign(storage, obj)
let storage = Object.assign(this.getLs(), obj)
this.$ls.set('ctf0-Media_Manager', storage)
},
removeLs() {
this.folders = []
this.$ls.remove('ctf0-Media_Manager')
// location.reload()
},
preSaved() {
let ls = this.getLs()

if (ls) {
this.randomNames = ls.randomNames || false
this.folders = ls.folders || []
this.toolBar = ls.toolBar || true
this.selectedFile = ls.selectedFileName || null
}
},

// cache
cacheResponse(value) {
return set(this.cacheName, value, idbKeyVal).catch((err) => {
getCachedResponse(key = this.cacheName) {
return get(key, cacheStore)
},
cacheResponse(val) {
let date = getTime(addMinutes(new Date(), this.cacheExp))
val = Object.assign(val, {expire: date})

return set(this.cacheName, val, cacheStore).catch((err) => {
console.warn('cacheStore.setItem', err)
})
},
getCachedResponse() {
return get(this.cacheName, idbKeyVal)
},
removeCachedResponse(destination = null) {
let cacheName = this.cacheName
let extra
Expand All @@ -49,15 +62,18 @@ export default {
: [cacheName]

items.forEach((one) => {
return del(one, idbKeyVal).then(() => {
console.log(`${one} ${this.trans('clear_cache')}`)
}).catch((err) => {
console.warn('cacheStore.removeItem', err)
})
return this.deleteCache(one)
})
},
deleteCache(item) {
return del(item, cacheStore).then(() => {
console.log(`${item} ${this.trans('clear_cache')}`)
}).catch((err) => {
console.error('cacheStore.removeItem', err)
})
},
clearCache(showNotif = true) {
clear(idbKeyVal).then(() => {
clear(cacheStore).then(() => {
if (showNotif) {
this.showNotif(this.trans('clear_cache'))
}
Expand All @@ -68,6 +84,21 @@ export default {
}).catch((err) => {
console.error(err)
})
},
invalidateCache() {
let now = getTime(new Date())

return keys(cacheStore).then((keys) => {
keys.map((key) => {
this.getCachedResponse(key).then((item) => {
if (item.expire < now) {
return this.deleteCache(key)
}
})
})
}).catch((err) => {
console.error(err)
})
}
}
}
4 changes: 2 additions & 2 deletions src/resources/assets/js/modules/download.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default {
})
},

ZipDownload(type) {
ZipDownload(type, id) {
this.showProgress = true

// de-select download btn
Expand All @@ -39,7 +39,7 @@ export default {
: folders.length ? `${folders[folders.length - 1]}-files` : 'media_manager-files'

let es = new EventSource(
`${this.zipProgressRoute}/${name}`,
`${this.zipProgressRoute}/${name}/${id}`,
{withCredentials: true}
)

Expand Down
5 changes: 4 additions & 1 deletion src/resources/assets/js/modules/selected.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,10 @@ export default {
openFolder(file) {
if (!this.isBulkSelecting() && this.fileTypeIs(file, 'folder')) {
this.folders.push(file.name)
this.getFiles(this.folders)

this.invalidateCache().then(() => {
this.getFiles(this.folders)
})
}

this.resetInput('currentFilterName')
Expand Down
Loading

0 comments on commit 80c4c89

Please sign in to comment.