Fix ESLint rules once and for all
This commit is contained in:
parent
2412a60bd4
commit
fb2c27086f
11
.prettierrc
11
.prettierrc
|
@ -1,11 +0,0 @@
|
||||||
{
|
|
||||||
"trailingComma": "none",
|
|
||||||
"tabWidth": 4,
|
|
||||||
"semi": true,
|
|
||||||
"singleQuote": true,
|
|
||||||
"endOfLine": "lf",
|
|
||||||
"bracketSpacing": true,
|
|
||||||
"useTabs": true,
|
|
||||||
"printWidth": 120,
|
|
||||||
"jsxBracketSameLine": false
|
|
||||||
}
|
|
|
@ -1,11 +1,9 @@
|
||||||
{
|
{
|
||||||
"discord.enabled": true,
|
|
||||||
"editor.detectIndentation": false,
|
"editor.detectIndentation": false,
|
||||||
"editor.insertSpaces": false,
|
"editor.insertSpaces": false,
|
||||||
"files.insertFinalNewline": true,
|
"files.insertFinalNewline": true,
|
||||||
"editor.formatOnPaste": true,
|
"editor.formatOnPaste": true,
|
||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
"vetur.validation.template": false,
|
|
||||||
"[javascript]": {
|
"[javascript]": {
|
||||||
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
|
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
|
||||||
},
|
},
|
||||||
|
@ -15,11 +13,6 @@
|
||||||
"prettier.disableLanguages": ["vue"],
|
"prettier.disableLanguages": ["vue"],
|
||||||
"vetur.format.enable": true,
|
"vetur.format.enable": true,
|
||||||
"files.eol": "\n",
|
"files.eol": "\n",
|
||||||
"vetur.format.defaultFormatter.html": "js-beautify-html",
|
|
||||||
"vetur.format.defaultFormatter.js": "prettier",
|
|
||||||
"vetur.format.defaultFormatter.scss": "prettier",
|
|
||||||
"vetur.format.defaultFormatter.stylus": "stylus-supremacy",
|
|
||||||
"vetur.format.defaultFormatter.ts": "vscode-typescript",
|
|
||||||
"eslint.alwaysShowStatus": true,
|
"eslint.alwaysShowStatus": true,
|
||||||
"eslint.format.enable": true,
|
"eslint.format.enable": true,
|
||||||
"editor.codeActionsOnSave": {
|
"editor.codeActionsOnSave": {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
82
package.json
82
package.json
|
@ -44,8 +44,6 @@
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"dotenv": "^6.2.0",
|
"dotenv": "^6.2.0",
|
||||||
"dumper.js": "^1.3.1",
|
"dumper.js": "^1.3.1",
|
||||||
"eslint-config-prettier": "^6.11.0",
|
|
||||||
"eslint-plugin-prettier": "^3.1.4",
|
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"express-rate-limit": "^3.4.0",
|
"express-rate-limit": "^3.4.0",
|
||||||
"ffmpeg-generate-video-preview": "^1.0.3",
|
"ffmpeg-generate-video-preview": "^1.0.3",
|
||||||
|
@ -89,98 +87,24 @@
|
||||||
"babel-eslint": "^10.0.1",
|
"babel-eslint": "^10.0.1",
|
||||||
"cross-env": "^5.2.0",
|
"cross-env": "^5.2.0",
|
||||||
"eslint": "^5.13.0",
|
"eslint": "^5.13.0",
|
||||||
"eslint-config-airbnb-base": "^14.2.0",
|
"eslint-config-aqua": "^7.3.0",
|
||||||
"eslint-config-aqua": "^4.4.1",
|
|
||||||
"eslint-import-resolver-nuxt": "^1.0.1",
|
"eslint-import-resolver-nuxt": "^1.0.1",
|
||||||
"eslint-plugin-vue": "^5.2.1",
|
"eslint-plugin-vue": "^5.2.1",
|
||||||
"node-sass": "^4.11.0",
|
"node-sass": "^4.11.0",
|
||||||
"nodemon": "^1.19.3",
|
"nodemon": "^1.19.3",
|
||||||
"postcss-css-variables": "^0.11.0",
|
"postcss-css-variables": "^0.11.0",
|
||||||
"postcss-nested": "^3.0.0",
|
"postcss-nested": "^3.0.0",
|
||||||
"prettier": "adamjlev/prettier",
|
|
||||||
"sass-loader": "^7.1.0"
|
"sass-loader": "^7.1.0"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"extends": [
|
"extends": [
|
||||||
"airbnb-base",
|
"aqua/node",
|
||||||
"plugin:eslint-plugin-vue/recommended"
|
"aqua/vue"
|
||||||
],
|
],
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"parser": "babel-eslint",
|
"parser": "babel-eslint",
|
||||||
"sourceType": "module"
|
"sourceType": "module"
|
||||||
},
|
},
|
||||||
"rules": {
|
|
||||||
"max-len": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"code": 120,
|
|
||||||
"ignoreUrls": true,
|
|
||||||
"ignoreStrings": true,
|
|
||||||
"ignoreTemplateLiterals": true,
|
|
||||||
"ignoreRegExpLiterals": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"class-methods-use-this": "off",
|
|
||||||
"no-param-reassign": "off",
|
|
||||||
"no-plusplus": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"allowForLoopAfterthoughts": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"no-underscore-dangle": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"allow": [
|
|
||||||
"_id"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"import/extensions": [
|
|
||||||
"error",
|
|
||||||
"always",
|
|
||||||
{
|
|
||||||
"js": "never",
|
|
||||||
"ts": "never"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"vue/attribute-hyphenation": 0,
|
|
||||||
"vue/html-closing-bracket-newline": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"singleline": "never",
|
|
||||||
"multiline": "never"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"vue/max-attributes-per-line": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"singleline": 5,
|
|
||||||
"multiline": {
|
|
||||||
"max": 1,
|
|
||||||
"allowFirstLine": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"quote-props": 0,
|
|
||||||
"indent": [
|
|
||||||
"error",
|
|
||||||
"tab"
|
|
||||||
],
|
|
||||||
"no-tabs": "off",
|
|
||||||
"vue/html-indent": [
|
|
||||||
"error",
|
|
||||||
"tab"
|
|
||||||
],
|
|
||||||
"import/no-extraneous-dependencies": "off",
|
|
||||||
"no-restricted-syntax": "off",
|
|
||||||
"no-continue": "off",
|
|
||||||
"no-await-in-loop": "off",
|
|
||||||
"comma-dangle": [
|
|
||||||
"error",
|
|
||||||
"never"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"settings": {
|
"settings": {
|
||||||
"import/resolver": {
|
"import/resolver": {
|
||||||
"nuxt": {
|
"nuxt": {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
exports.up = async (knex) => {
|
exports.up = async knex => {
|
||||||
await knex.schema.createTable('users', (table) => {
|
await knex.schema.createTable('users', table => {
|
||||||
table.increments();
|
table.increments();
|
||||||
table.string('username').unique();
|
table.string('username').unique();
|
||||||
table.text('password');
|
table.text('password');
|
||||||
|
@ -12,7 +12,7 @@ exports.up = async (knex) => {
|
||||||
table.timestamp('editedAt');
|
table.timestamp('editedAt');
|
||||||
});
|
});
|
||||||
|
|
||||||
await knex.schema.createTable('albums', (table) => {
|
await knex.schema.createTable('albums', table => {
|
||||||
table.increments();
|
table.increments();
|
||||||
table.integer('userId');
|
table.integer('userId');
|
||||||
table.string('name');
|
table.string('name');
|
||||||
|
@ -24,7 +24,7 @@ exports.up = async (knex) => {
|
||||||
table.unique(['userId', 'name']);
|
table.unique(['userId', 'name']);
|
||||||
});
|
});
|
||||||
|
|
||||||
await knex.schema.createTable('files', (table) => {
|
await knex.schema.createTable('files', table => {
|
||||||
table.increments();
|
table.increments();
|
||||||
table.integer('userId');
|
table.integer('userId');
|
||||||
table.string('name');
|
table.string('name');
|
||||||
|
@ -38,7 +38,7 @@ exports.up = async (knex) => {
|
||||||
table.timestamp('editedAt');
|
table.timestamp('editedAt');
|
||||||
});
|
});
|
||||||
|
|
||||||
await knex.schema.createTable('links', (table) => {
|
await knex.schema.createTable('links', table => {
|
||||||
table.increments();
|
table.increments();
|
||||||
table.integer('userId');
|
table.integer('userId');
|
||||||
table.integer('albumId');
|
table.integer('albumId');
|
||||||
|
@ -53,7 +53,7 @@ exports.up = async (knex) => {
|
||||||
table.unique(['userId', 'albumId', 'identifier']);
|
table.unique(['userId', 'albumId', 'identifier']);
|
||||||
});
|
});
|
||||||
|
|
||||||
await knex.schema.createTable('albumsFiles', (table) => {
|
await knex.schema.createTable('albumsFiles', table => {
|
||||||
table.increments();
|
table.increments();
|
||||||
table.integer('albumId');
|
table.integer('albumId');
|
||||||
table.integer('fileId');
|
table.integer('fileId');
|
||||||
|
@ -61,13 +61,13 @@ exports.up = async (knex) => {
|
||||||
table.unique(['albumId', 'fileId']);
|
table.unique(['albumId', 'fileId']);
|
||||||
});
|
});
|
||||||
|
|
||||||
await knex.schema.createTable('albumsLinks', (table) => {
|
await knex.schema.createTable('albumsLinks', table => {
|
||||||
table.increments();
|
table.increments();
|
||||||
table.integer('albumId');
|
table.integer('albumId');
|
||||||
table.integer('linkId').unique();
|
table.integer('linkId').unique();
|
||||||
});
|
});
|
||||||
|
|
||||||
await knex.schema.createTable('tags', (table) => {
|
await knex.schema.createTable('tags', table => {
|
||||||
table.increments();
|
table.increments();
|
||||||
table.string('uuid');
|
table.string('uuid');
|
||||||
table.integer('userId');
|
table.integer('userId');
|
||||||
|
@ -78,7 +78,7 @@ exports.up = async (knex) => {
|
||||||
table.unique(['userId', 'name']);
|
table.unique(['userId', 'name']);
|
||||||
});
|
});
|
||||||
|
|
||||||
await knex.schema.createTable('fileTags', (table) => {
|
await knex.schema.createTable('fileTags', table => {
|
||||||
table.increments();
|
table.increments();
|
||||||
table.integer('fileId');
|
table.integer('fileId');
|
||||||
table.integer('tagId');
|
table.integer('tagId');
|
||||||
|
@ -86,13 +86,13 @@ exports.up = async (knex) => {
|
||||||
table.unique(['fileId', 'tagId']);
|
table.unique(['fileId', 'tagId']);
|
||||||
});
|
});
|
||||||
|
|
||||||
await knex.schema.createTable('bans', (table) => {
|
await knex.schema.createTable('bans', table => {
|
||||||
table.increments();
|
table.increments();
|
||||||
table.string('ip');
|
table.string('ip');
|
||||||
table.timestamp('createdAt');
|
table.timestamp('createdAt');
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
exports.down = async (knex) => {
|
exports.down = async knex => {
|
||||||
await knex.schema.dropTableIfExists('users');
|
await knex.schema.dropTableIfExists('users');
|
||||||
await knex.schema.dropTableIfExists('albums');
|
await knex.schema.dropTableIfExists('albums');
|
||||||
await knex.schema.dropTableIfExists('files');
|
await knex.schema.dropTableIfExists('files');
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
const bcrypt = require('bcrypt');
|
const bcrypt = require('bcrypt');
|
||||||
const moment = require('moment');
|
const moment = require('moment');
|
||||||
|
|
||||||
exports.seed = async (db) => {
|
exports.seed = async db => {
|
||||||
const now = moment.utc().toDate();
|
const now = moment.utc().toDate();
|
||||||
const user = await db.table('users').where({ username: process.env.ADMIN_ACCOUNT }).first();
|
const user = await db.table('users').where({ username: process.env.ADMIN_ACCOUNT }).first();
|
||||||
if (user) return;
|
if (user) return;
|
||||||
|
|
|
@ -27,7 +27,7 @@ const generateThumbnailForImage = async (filename, output) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const generateThumbnailForVideo = (filename) => {
|
const generateThumbnailForVideo = filename => {
|
||||||
try {
|
try {
|
||||||
ffmpeg(nodePath.join(__dirname, '../../uploads', filename))
|
ffmpeg(nodePath.join(__dirname, '../../uploads', filename))
|
||||||
.thumbnail({
|
.thumbnail({
|
||||||
|
@ -36,7 +36,7 @@ const generateThumbnailForVideo = (filename) => {
|
||||||
folder: nodePath.join(__dirname, '../../uploads/thumbs/square'),
|
folder: nodePath.join(__dirname, '../../uploads/thumbs/square'),
|
||||||
size: '64x64'
|
size: '64x64'
|
||||||
})
|
})
|
||||||
.on('error', (error) => console.error(error.message));
|
.on('error', error => console.error(error.message));
|
||||||
ffmpeg(nodePath.join(__dirname, '../../uploads', filename))
|
ffmpeg(nodePath.join(__dirname, '../../uploads', filename))
|
||||||
.thumbnail({
|
.thumbnail({
|
||||||
timestamps: [0],
|
timestamps: [0],
|
||||||
|
@ -44,7 +44,7 @@ const generateThumbnailForVideo = (filename) => {
|
||||||
folder: nodePath.join(__dirname, '../../uploads/thumbs'),
|
folder: nodePath.join(__dirname, '../../uploads/thumbs'),
|
||||||
size: '150x?'
|
size: '150x?'
|
||||||
})
|
})
|
||||||
.on('error', (error) => console.error(error.message));
|
.on('error', error => console.error(error.message));
|
||||||
console.log('finished', filename);
|
console.log('finished', filename);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log('error', filename);
|
console.log('error', filename);
|
||||||
|
@ -64,15 +64,15 @@ const newDb = require('knex')({
|
||||||
connection: {
|
connection: {
|
||||||
filename: nodePath.join(__dirname, '../../', 'database.sqlite')
|
filename: nodePath.join(__dirname, '../../', 'database.sqlite')
|
||||||
},
|
},
|
||||||
postProcessResponse: (result) => {
|
postProcessResponse: result => {
|
||||||
const booleanFields = [
|
const booleanFields = [
|
||||||
'enabled',
|
'enabled',
|
||||||
'enableDownload',
|
'enableDownload',
|
||||||
'isAdmin'
|
'isAdmin'
|
||||||
];
|
];
|
||||||
|
|
||||||
const processResponse = (row) => {
|
const processResponse = row => {
|
||||||
Object.keys(row).forEach((key) => {
|
Object.keys(row).forEach(key => {
|
||||||
if (booleanFields.includes(key)) {
|
if (booleanFields.includes(key)) {
|
||||||
if (row[key] === 0) row[key] = false;
|
if (row[key] === 0) row[key] = false;
|
||||||
else if (row[key] === 1) row[key] = true;
|
else if (row[key] === 1) row[key] = true;
|
||||||
|
@ -81,7 +81,7 @@ const newDb = require('knex')({
|
||||||
return row;
|
return row;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (Array.isArray(result)) return result.map((row) => processResponse(row));
|
if (Array.isArray(result)) return result.map(row => processResponse(row));
|
||||||
if (typeof result === 'object') return processResponse(result);
|
if (typeof result === 'object') return processResponse(result);
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
|
@ -64,11 +64,11 @@ class albumGET extends Route {
|
||||||
/*
|
/*
|
||||||
Get the actual files
|
Get the actual files
|
||||||
*/
|
*/
|
||||||
const fileIds = fileList.map((el) => el.fileId);
|
const fileIds = fileList.map(el => el.fileId);
|
||||||
const files = await db.table('files')
|
const files = await db.table('files')
|
||||||
.whereIn('id', fileIds)
|
.whereIn('id', fileIds)
|
||||||
.select('name');
|
.select('name');
|
||||||
const filesToZip = files.map((el) => el.name);
|
const filesToZip = files.map(el => el.name);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Util.createZip(filesToZip, album);
|
Util.createZip(filesToZip, album);
|
||||||
|
|
|
@ -18,7 +18,7 @@ class filesGET extends Route {
|
||||||
.select('albumId');
|
.select('albumId');
|
||||||
|
|
||||||
if (albumFiles.length) {
|
if (albumFiles.length) {
|
||||||
albumFiles = albumFiles.map((a) => a.albumId);
|
albumFiles = albumFiles.map(a => a.albumId);
|
||||||
albums = await db.table('albums')
|
albums = await db.table('albums')
|
||||||
.whereIn('id', albumFiles)
|
.whereIn('id', albumFiles)
|
||||||
.select('id', 'name');
|
.select('id', 'name');
|
||||||
|
|
|
@ -56,7 +56,7 @@ class uploadPOST extends Route {
|
||||||
if (!album) return res.status(401).json({ message: 'Album doesn\'t exist or it doesn\'t belong to the user' });
|
if (!album) return res.status(401).json({ message: 'Album doesn\'t exist or it doesn\'t belong to the user' });
|
||||||
}
|
}
|
||||||
|
|
||||||
return upload(req, res, async (err) => {
|
return upload(req, res, async err => {
|
||||||
if (err) console.error(err.message);
|
if (err) console.error(err.message);
|
||||||
|
|
||||||
let uploadedFile = {};
|
let uploadedFile = {};
|
||||||
|
@ -142,7 +142,7 @@ class uploadPOST extends Route {
|
||||||
|
|
||||||
async checkIfFileExists(db, user, hash) {
|
async checkIfFileExists(db, user, hash) {
|
||||||
const exists = await db.table('files')
|
const exists = await db.table('files')
|
||||||
.where(function () { // eslint-disable-line func-names
|
.where(function() { // eslint-disable-line func-names
|
||||||
if (user) this.where('userId', user.id);
|
if (user) this.where('userId', user.id);
|
||||||
else this.whereNull('userId');
|
else this.whereNull('userId');
|
||||||
})
|
})
|
||||||
|
|
|
@ -9,7 +9,7 @@ const db = require('knex')({
|
||||||
database: process.env.DB_DATABASE,
|
database: process.env.DB_DATABASE,
|
||||||
filename: nodePath.join(__dirname, '../../../database.sqlite')
|
filename: nodePath.join(__dirname, '../../../database.sqlite')
|
||||||
},
|
},
|
||||||
postProcessResponse: (result) => {
|
postProcessResponse: result => {
|
||||||
/*
|
/*
|
||||||
Fun fact: Depending on the database used by the user and given that I don't want
|
Fun fact: Depending on the database used by the user and given that I don't want
|
||||||
to force a specific database for everyone because of the nature of this project,
|
to force a specific database for everyone because of the nature of this project,
|
||||||
|
@ -18,8 +18,8 @@ const db = require('knex')({
|
||||||
*/
|
*/
|
||||||
const booleanFields = ['enabled', 'enableDownload', 'isAdmin'];
|
const booleanFields = ['enabled', 'enableDownload', 'isAdmin'];
|
||||||
|
|
||||||
const processResponse = (row) => {
|
const processResponse = row => {
|
||||||
Object.keys(row).forEach((key) => {
|
Object.keys(row).forEach(key => {
|
||||||
if (booleanFields.includes(key)) {
|
if (booleanFields.includes(key)) {
|
||||||
if (row[key] === 0) row[key] = false;
|
if (row[key] === 0) row[key] = false;
|
||||||
else if (row[key] === 1) row[key] = true;
|
else if (row[key] === 1) row[key] = true;
|
||||||
|
@ -28,7 +28,7 @@ const db = require('knex')({
|
||||||
return row;
|
return row;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (Array.isArray(result)) return result.map((row) => processResponse(row));
|
if (Array.isArray(result)) return result.map(row => processResponse(row));
|
||||||
if (typeof result === 'object') return processResponse(result);
|
if (typeof result === 'object') return processResponse(result);
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
|
@ -42,16 +42,16 @@ class Server {
|
||||||
if (ext) { ext = `.${ext.toLowerCase()}`; }
|
if (ext) { ext = `.${ext.toLowerCase()}`; }
|
||||||
|
|
||||||
if (
|
if (
|
||||||
ThumbUtil.imageExtensions.indexOf(ext) > -1
|
ThumbUtil.imageExtensions.indexOf(ext) > -1 ||
|
||||||
|| ThumbUtil.videoExtensions.indexOf(ext) > -1
|
ThumbUtil.videoExtensions.indexOf(ext) > -1 ||
|
||||||
|| req.path.indexOf('_nuxt') > -1
|
req.path.indexOf('_nuxt') > -1 ||
|
||||||
|| req.path.indexOf('favicon.ico') > -1
|
req.path.indexOf('favicon.ico') > -1
|
||||||
) {
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
'stream': {
|
stream: {
|
||||||
write(str) { log.debug(str); }
|
write(str) { log.debug(str); }
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
@ -64,7 +64,7 @@ class Server {
|
||||||
}
|
}
|
||||||
|
|
||||||
registerAllTheRoutes() {
|
registerAllTheRoutes() {
|
||||||
jetpack.find(this.routesFolder, { matching: '*.js' }).forEach((routeFile) => {
|
jetpack.find(this.routesFolder, { matching: '*.js' }).forEach(routeFile => {
|
||||||
// eslint-disable-next-line import/no-dynamic-require, global-require
|
// eslint-disable-next-line import/no-dynamic-require, global-require
|
||||||
const RouteClass = require(path.join('../../../', routeFile));
|
const RouteClass = require(path.join('../../../', routeFile));
|
||||||
let routes = [RouteClass];
|
let routes = [RouteClass];
|
||||||
|
|
|
@ -2,16 +2,16 @@ const chrono = require('chrono-node');
|
||||||
|
|
||||||
class QueryHelper {
|
class QueryHelper {
|
||||||
static parsers = {
|
static parsers = {
|
||||||
before: (val) => QueryHelper.parseChronoList(val),
|
before: val => QueryHelper.parseChronoList(val),
|
||||||
after: (val) => QueryHelper.parseChronoList(val),
|
after: val => QueryHelper.parseChronoList(val),
|
||||||
tag: (val) => QueryHelper.sanitizeTags(val)
|
tag: val => QueryHelper.sanitizeTags(val)
|
||||||
};
|
};
|
||||||
|
|
||||||
static requirementHandlers = {
|
static requirementHandlers = {
|
||||||
album: (knex) => knex
|
album: knex => knex
|
||||||
.join('albumsFiles', 'files.id', '=', 'albumsFiles.fileId')
|
.join('albumsFiles', 'files.id', '=', 'albumsFiles.fileId')
|
||||||
.join('albums', 'albumsFiles.albumId', '=', 'album.id'),
|
.join('albums', 'albumsFiles.albumId', '=', 'album.id'),
|
||||||
tag: (knex) => knex
|
tag: knex => knex
|
||||||
.join('fileTags', 'files.id', '=', 'fileTags.fileId')
|
.join('fileTags', 'files.id', '=', 'fileTags.fileId')
|
||||||
.join('tags', 'fileTags.tagId', '=', 'tags.id')
|
.join('tags', 'fileTags.tagId', '=', 'tags.id')
|
||||||
}
|
}
|
||||||
|
@ -93,11 +93,11 @@ class QueryHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
static parseChronoList(list) {
|
static parseChronoList(list) {
|
||||||
return list.map((e) => chrono.parse(e));
|
return list.map(e => chrono.parse(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
static sanitizeTags(list) {
|
static sanitizeTags(list) {
|
||||||
return list.map((e) => e.replace(/\s/g, '_'));
|
return list.map(e => e.replace(/\s/g, '_'));
|
||||||
}
|
}
|
||||||
|
|
||||||
static generateInclusionForTags(db, knex, list) {
|
static generateInclusionForTags(db, knex, list) {
|
||||||
|
|
|
@ -53,7 +53,7 @@ class ThumbUtil {
|
||||||
folder: ThumbUtil.squareThumbPath,
|
folder: ThumbUtil.squareThumbPath,
|
||||||
size: '64x64'
|
size: '64x64'
|
||||||
})
|
})
|
||||||
.on('error', (error) => log.error(error.message));
|
.on('error', error => log.error(error.message));
|
||||||
|
|
||||||
ffmpeg(filePath)
|
ffmpeg(filePath)
|
||||||
.thumbnail({
|
.thumbnail({
|
||||||
|
@ -62,7 +62,7 @@ class ThumbUtil {
|
||||||
folder: ThumbUtil.thumbPath,
|
folder: ThumbUtil.thumbPath,
|
||||||
size: '150x?'
|
size: '150x?'
|
||||||
})
|
})
|
||||||
.on('error', (error) => log.error(error.message));
|
.on('error', error => log.error(error.message));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await previewUtil({
|
await previewUtil({
|
||||||
|
|
|
@ -25,7 +25,7 @@ const getStartTime = (vDuration, fDuration, ignoreBeforePercent, ignoreAfterPerc
|
||||||
return getRandomInt(ignoreBeforePercent * safeVDuration, ignoreAfterPercent * safeVDuration);
|
return getRandomInt(ignoreBeforePercent * safeVDuration, ignoreAfterPercent * safeVDuration);
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = async (opts) => {
|
module.exports = async opts => {
|
||||||
const {
|
const {
|
||||||
log = noop,
|
log = noop,
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ module.exports = async (opts) => {
|
||||||
.outputOptions([`-t ${fragmentDurationSecond}`])
|
.outputOptions([`-t ${fragmentDurationSecond}`])
|
||||||
.noAudio()
|
.noAudio()
|
||||||
.output(output)
|
.output(output)
|
||||||
.on('start', (cmd) => log && log({ cmd }))
|
.on('start', cmd => log && log({ cmd }))
|
||||||
.on('end', resolve)
|
.on('end', resolve)
|
||||||
.on('error', reject)
|
.on('error', reject)
|
||||||
.run();
|
.run();
|
||||||
|
|
|
@ -4,7 +4,7 @@ const probe = require('ffmpeg-probe');
|
||||||
|
|
||||||
const noop = () => {};
|
const noop = () => {};
|
||||||
|
|
||||||
module.exports = async (opts) => {
|
module.exports = async opts => {
|
||||||
const {
|
const {
|
||||||
log = noop,
|
log = noop,
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ module.exports = async (opts) => {
|
||||||
const info = await probe(input);
|
const info = await probe(input);
|
||||||
// const numFramesTotal = parseInt(info.streams[0].nb_frames, 10);
|
// const numFramesTotal = parseInt(info.streams[0].nb_frames, 10);
|
||||||
const { avg_frame_rate: avgFrameRate, duration } = info.streams[0];
|
const { avg_frame_rate: avgFrameRate, duration } = info.streams[0];
|
||||||
const [frames, time] = avgFrameRate.split('/').map((e) => parseInt(e, 10));
|
const [frames, time] = avgFrameRate.split('/').map(e => parseInt(e, 10));
|
||||||
|
|
||||||
const numFramesTotal = (frames / time) * duration;
|
const numFramesTotal = (frames / time) * duration;
|
||||||
|
|
||||||
|
@ -63,9 +63,9 @@ module.exports = async (opts) => {
|
||||||
.noAudio()
|
.noAudio()
|
||||||
.outputFormat('webm')
|
.outputFormat('webm')
|
||||||
.output(output)
|
.output(output)
|
||||||
.on('start', (cmd) => log && log({ cmd }))
|
.on('start', cmd => log && log({ cmd }))
|
||||||
.on('end', () => resolve())
|
.on('end', () => resolve())
|
||||||
.on('error', (err) => reject(err))
|
.on('error', err => reject(err))
|
||||||
.run();
|
.run();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -119,12 +119,12 @@ import { mapState, mapActions } from 'vuex';
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
albumId: {
|
albumId: {
|
||||||
type: Number,
|
'type': Number,
|
||||||
default: 0
|
'default': 0
|
||||||
},
|
},
|
||||||
details: {
|
details: {
|
||||||
type: Object,
|
'type': Object,
|
||||||
default: () => ({})
|
'default': () => ({})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
@ -175,7 +175,7 @@ export default {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.alert({ text: e.message, error: true });
|
this.alert({ text: e.message, error: true });
|
||||||
} finally {
|
} finally {
|
||||||
this.isDeletingLinks = this.isDeletingLinks.filter((e) => e !== identifier);
|
this.isDeletingLinks = this.isDeletingLinks.filter(e => e !== identifier);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async createLink(albumId) {
|
async createLink(albumId) {
|
||||||
|
@ -207,7 +207,7 @@ export default {
|
||||||
maxlength: 10
|
maxlength: 10
|
||||||
},
|
},
|
||||||
trapFocus: true,
|
trapFocus: true,
|
||||||
onConfirm: (value) => this.$handler.executeAction('albums/createCustomLink', { albumId, value })
|
onConfirm: value => this.$handler.executeAction('albums/createCustomLink', { albumId, value })
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
isDeleting(identifier) {
|
isDeleting(identifier) {
|
||||||
|
|
|
@ -53,7 +53,7 @@
|
||||||
<AlbumDetails
|
<AlbumDetails
|
||||||
v-if="isExpanded"
|
v-if="isExpanded"
|
||||||
:details="getDetails(album.id)"
|
:details="getDetails(album.id)"
|
||||||
:albumId="album.id" />
|
:album-id="album.id" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -67,8 +67,8 @@ export default {
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
album: {
|
album: {
|
||||||
type: Object,
|
'type': Object,
|
||||||
default: () => ({})
|
'default': () => ({})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
|
@ -54,6 +54,8 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<a href="https://github.com/weebdev/lolisafe">GitHub</a>
|
<a href="https://github.com/weebdev/lolisafe">GitHub</a>
|
||||||
|
<a href="https://patreon.com/pitu">Patreon</a>
|
||||||
|
<a href="https://discord.gg/5g6vgwn">Discord</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<a
|
<a
|
||||||
|
@ -79,9 +81,9 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({ loggedIn: 'auth/isLoggedIn' }),
|
...mapGetters({ loggedIn: 'auth/isLoggedIn' }),
|
||||||
...mapState({
|
...mapState({
|
||||||
version: (state) => state.config.version,
|
version: state => state.config.version,
|
||||||
serviceName: (state) => state.config.serviceName,
|
serviceName: state => state.config.serviceName,
|
||||||
token: (state) => state.auth.token
|
token: state => state.auth.token
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
@ -23,10 +23,10 @@
|
||||||
|
|
||||||
<template v-if="!images.showList">
|
<template v-if="!images.showList">
|
||||||
<Waterfall
|
<Waterfall
|
||||||
:gutterWidth="10"
|
:gutter-width="10"
|
||||||
:gutterHeight="4"
|
:gutter-height="4"
|
||||||
:options="{fitWidth: true}"
|
:options="{fitWidth: true}"
|
||||||
:itemWidth="width"
|
:item-width="width"
|
||||||
:items="gridFiles">
|
:items="gridFiles">
|
||||||
<template v-slot="{item}">
|
<template v-slot="{item}">
|
||||||
<template v-if="isPublic">
|
<template v-if="isPublic">
|
||||||
|
@ -165,32 +165,32 @@ export default {
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
files: {
|
files: {
|
||||||
type: Array,
|
'type': Array,
|
||||||
default: () => []
|
'default': () => []
|
||||||
},
|
},
|
||||||
total: {
|
total: {
|
||||||
type: Number,
|
'type': Number,
|
||||||
default: 0
|
'default': 0
|
||||||
},
|
},
|
||||||
fixed: {
|
fixed: {
|
||||||
type: Boolean,
|
'type': Boolean,
|
||||||
default: false
|
'default': false
|
||||||
},
|
},
|
||||||
isPublic: {
|
isPublic: {
|
||||||
type: Boolean,
|
'type': Boolean,
|
||||||
default: false
|
'default': false
|
||||||
},
|
},
|
||||||
width: {
|
width: {
|
||||||
type: Number,
|
'type': Number,
|
||||||
default: 150
|
'default': 150
|
||||||
},
|
},
|
||||||
enableSearch: {
|
enableSearch: {
|
||||||
type: Boolean,
|
'type': Boolean,
|
||||||
default: true
|
'default': true
|
||||||
},
|
},
|
||||||
enableToolbar: {
|
enableToolbar: {
|
||||||
type: Boolean,
|
'type': Boolean,
|
||||||
default: true
|
'default': true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
@ -212,16 +212,16 @@ export default {
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
...mapState({
|
||||||
user: (state) => state.auth.user,
|
user: state => state.auth.user,
|
||||||
albums: (state) => state.albums.tinyDetails,
|
albums: state => state.albums.tinyDetails,
|
||||||
images: (state) => state.images
|
images: state => state.images
|
||||||
}),
|
}),
|
||||||
blank() {
|
blank() {
|
||||||
// eslint-disable-next-line global-require, import/no-unresolved
|
// eslint-disable-next-line global-require, import/no-unresolved
|
||||||
return require('@/assets/images/blank.png');
|
return require('@/assets/images/blank.png');
|
||||||
},
|
},
|
||||||
gridFiles() {
|
gridFiles() {
|
||||||
return (this.files || []).filter((v) => !v.hideFromList);
|
return (this.files || []).filter(v => !v.hideFromList);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -259,8 +259,8 @@ export default {
|
||||||
},
|
},
|
||||||
isAlbumSelected(id) {
|
isAlbumSelected(id) {
|
||||||
if (!this.showingModalForFile) return false;
|
if (!this.showingModalForFile) return false;
|
||||||
const found = this.showingModalForFile.albums.find((el) => el.id === id);
|
const found = this.showingModalForFile.albums.find(el => el.id === id);
|
||||||
return !!(found && found.id);
|
return Boolean(found && found.id);
|
||||||
},
|
},
|
||||||
async openAlbumModal(file) {
|
async openAlbumModal(file) {
|
||||||
const { id } = file;
|
const { id } = file;
|
||||||
|
|
|
@ -24,24 +24,24 @@ export default {
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
options: {
|
options: {
|
||||||
type: Object,
|
'type': Object,
|
||||||
default: () => {}
|
'default': () => {}
|
||||||
},
|
},
|
||||||
items: {
|
items: {
|
||||||
type: Array,
|
'type': Array,
|
||||||
default: () => []
|
'default': () => []
|
||||||
},
|
},
|
||||||
itemWidth: {
|
itemWidth: {
|
||||||
type: Number,
|
'type': Number,
|
||||||
default: 150
|
'default': 150
|
||||||
},
|
},
|
||||||
gutterWidth: {
|
gutterWidth: {
|
||||||
type: Number,
|
'type': Number,
|
||||||
default: 10
|
'default': 10
|
||||||
},
|
},
|
||||||
gutterHeight: {
|
gutterHeight: {
|
||||||
type: Number,
|
'type': Number,
|
||||||
default: 4
|
'default': 4
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -84,20 +84,20 @@ export default {
|
||||||
this.masonry.layout();
|
this.masonry.layout();
|
||||||
},
|
},
|
||||||
diffDomChildren() {
|
diffDomChildren() {
|
||||||
const oldChildren = this.domChildren.filter((element) => !!element.parentNode);
|
const oldChildren = this.domChildren.filter(element => Boolean(element.parentNode));
|
||||||
const newChildren = this.getNewDomChildren();
|
const newChildren = this.getNewDomChildren();
|
||||||
const removed = oldChildren.filter((oldChild) => !newChildren.includes(oldChild));
|
const removed = oldChildren.filter(oldChild => !newChildren.includes(oldChild));
|
||||||
const domDiff = newChildren.filter((newChild) => !oldChildren.includes(newChild));
|
const domDiff = newChildren.filter(newChild => !oldChildren.includes(newChild));
|
||||||
const prepended = domDiff.filter((newChild, index) => newChildren[index] === newChild);
|
const prepended = domDiff.filter((newChild, index) => newChildren[index] === newChild);
|
||||||
const appended = domDiff.filter((el) => !prepended.includes(el));
|
const appended = domDiff.filter(el => !prepended.includes(el));
|
||||||
let moved = [];
|
let moved = [];
|
||||||
if (removed.length === 0) {
|
if (removed.length === 0) {
|
||||||
moved = oldChildren.filter((child, index) => index !== newChildren.indexOf(child));
|
moved = oldChildren.filter((child, index) => index !== newChildren.indexOf(child));
|
||||||
}
|
}
|
||||||
this.domChildren = newChildren;
|
this.domChildren = newChildren;
|
||||||
return {
|
return {
|
||||||
old: oldChildren,
|
'old': oldChildren,
|
||||||
new: newChildren,
|
'new': newChildren,
|
||||||
removed,
|
removed,
|
||||||
appended,
|
appended,
|
||||||
prepended,
|
prepended,
|
||||||
|
@ -120,15 +120,10 @@ export default {
|
||||||
getNewDomChildren() {
|
getNewDomChildren() {
|
||||||
const node = this.$refs.waterfall;
|
const node = this.$refs.waterfall;
|
||||||
const children = this.options && this.options.itemSelector
|
const children = this.options && this.options.itemSelector
|
||||||
? node.querySelectorAll(this.options.itemSelector) : node.children;
|
? node.querySelectorAll(this.options.itemSelector)
|
||||||
|
: node.children;
|
||||||
return Array.prototype.slice.call(children);
|
return Array.prototype.slice.call(children);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.wfi {
|
|
||||||
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -24,22 +24,20 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapState } from 'vuex';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Albuminfo',
|
name: 'Albuminfo',
|
||||||
props: {
|
props: {
|
||||||
imageId: {
|
imageId: {
|
||||||
type: Number,
|
'type': Number,
|
||||||
default: 0
|
'default': 0
|
||||||
},
|
},
|
||||||
imageAlbums: {
|
imageAlbums: {
|
||||||
type: Array,
|
'type': Array,
|
||||||
default: () => []
|
'default': () => []
|
||||||
},
|
},
|
||||||
albums: {
|
albums: {
|
||||||
type: Array,
|
'type': Array,
|
||||||
default: () => []
|
'default': () => []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
@ -52,7 +50,7 @@ export default {
|
||||||
this.orderedAlbums = this.getOrderedAlbums();
|
this.orderedAlbums = this.getOrderedAlbums();
|
||||||
// we're sorting here instead of computed because we want sort on creation
|
// we're sorting here instead of computed because we want sort on creation
|
||||||
// then the array's values should be frozen
|
// then the array's values should be frozen
|
||||||
this.selectedOptions = this.imageAlbums.map((e) => e.id);
|
this.selectedOptions = this.imageAlbums.map(e => e.id);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getOrderedAlbums() {
|
getOrderedAlbums() {
|
||||||
|
@ -70,8 +68,8 @@ export default {
|
||||||
},
|
},
|
||||||
isAlbumSelected(id) {
|
isAlbumSelected(id) {
|
||||||
if (!this.showingModalForFile) return false;
|
if (!this.showingModalForFile) return false;
|
||||||
const found = this.showingModalForFile.albums.find((el) => el.id === id);
|
const found = this.showingModalForFile.albums.find(el => el.id === id);
|
||||||
return !!(found && found.id);
|
return Boolean(found && found.id);
|
||||||
},
|
},
|
||||||
async handleClick(id) {
|
async handleClick(id) {
|
||||||
// here the album should be already removed from the selected list
|
// here the album should be already removed from the selected list
|
||||||
|
|
|
@ -97,12 +97,12 @@
|
||||||
<div class="divider is-lolisafe has-text-light">
|
<div class="divider is-lolisafe has-text-light">
|
||||||
Tags
|
Tags
|
||||||
</div>
|
</div>
|
||||||
<Taginfo :imageId="file.id" :imageTags="tags" />
|
<Taginfo :image-id="file.id" :image-tags="tags" />
|
||||||
|
|
||||||
<div class="divider is-lolisafe has-text-light">
|
<div class="divider is-lolisafe has-text-light">
|
||||||
Albums
|
Albums
|
||||||
</div>
|
</div>
|
||||||
<Albuminfo :imageId="file.id" :imageAlbums="albums" :albums="tinyDetails" />
|
<Albuminfo :image-id="file.id" :image-albums="albums" :albums="tinyDetails" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -122,21 +122,21 @@ export default {
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
file: {
|
file: {
|
||||||
type: Object,
|
'type': Object,
|
||||||
default: () => ({})
|
'default': () => ({})
|
||||||
},
|
},
|
||||||
albums: {
|
albums: {
|
||||||
type: Array,
|
'type': Array,
|
||||||
default: () => ([])
|
'default': () => ([])
|
||||||
},
|
},
|
||||||
tags: {
|
tags: {
|
||||||
type: Array,
|
'type': Array,
|
||||||
default: () => ([])
|
'default': () => ([])
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: mapState({
|
computed: mapState({
|
||||||
images: (state) => state.images,
|
images: state => state.images,
|
||||||
tinyDetails: (state) => state.albums.tinyDetails
|
tinyDetails: state => state.albums.tinyDetails
|
||||||
}),
|
}),
|
||||||
methods: {
|
methods: {
|
||||||
formatBytes(bytes, decimals = 2) {
|
formatBytes(bytes, decimals = 2) {
|
||||||
|
@ -148,6 +148,7 @@ export default {
|
||||||
|
|
||||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-mixed-operators
|
||||||
return `${parseFloat((bytes / k ** i).toFixed(dm))} ${sizes[i]}`;
|
return `${parseFloat((bytes / k ** i).toFixed(dm))} ${sizes[i]}`;
|
||||||
},
|
},
|
||||||
isVideo(type) {
|
isVideo(type) {
|
||||||
|
|
|
@ -22,12 +22,12 @@ export default {
|
||||||
name: 'Taginfo',
|
name: 'Taginfo',
|
||||||
props: {
|
props: {
|
||||||
imageId: {
|
imageId: {
|
||||||
type: Number,
|
'type': Number,
|
||||||
default: 0
|
'default': 0
|
||||||
},
|
},
|
||||||
imageTags: {
|
imageTags: {
|
||||||
type: Array,
|
'type': Array,
|
||||||
default: () => []
|
'default': () => []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
@ -37,14 +37,14 @@ export default {
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
...mapState({
|
||||||
tags: (state) => state.tags.tagsList
|
tags: state => state.tags.tagsList
|
||||||
}),
|
}),
|
||||||
selectedTags() { return this.imageTags.map((e) => e.name); },
|
selectedTags() { return this.imageTags.map(e => e.name); },
|
||||||
lowercaseTags() { return this.imageTags.map((e) => e.name.toLowerCase()); }
|
lowercaseTags() { return this.imageTags.map(e => e.name.toLowerCase()); }
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getFilteredTags(str) {
|
getFilteredTags(str) {
|
||||||
this.filteredTags = this.tags.map((e) => e.name).filter((e) => {
|
this.filteredTags = this.tags.map(e => e.name).filter(e => {
|
||||||
// check if the search string matches any of the tags
|
// check if the search string matches any of the tags
|
||||||
const sanitezedTag = e.toString().toLowerCase();
|
const sanitezedTag = e.toString().toLowerCase();
|
||||||
const matches = sanitezedTag.indexOf(str.toLowerCase()) >= 0;
|
const matches = sanitezedTag.indexOf(str.toLowerCase()) >= 0;
|
||||||
|
|
|
@ -8,16 +8,16 @@
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
size: {
|
size: {
|
||||||
type: String,
|
'type': String,
|
||||||
default: '60px'
|
'default': '60px'
|
||||||
},
|
},
|
||||||
background: {
|
background: {
|
||||||
type: String,
|
'type': String,
|
||||||
default: '#9C27B0'
|
'default': '#9C27B0'
|
||||||
},
|
},
|
||||||
duration: {
|
duration: {
|
||||||
type: String,
|
'type': String,
|
||||||
default: '1.8s'
|
'default': '1.8s'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
size: {
|
size: {
|
||||||
type: String,
|
'type': String,
|
||||||
default: '40px'
|
'default': '40px'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
size: {
|
size: {
|
||||||
type: String,
|
'type': String,
|
||||||
default: '60px'
|
'default': '60px'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
size: {
|
size: {
|
||||||
type: String,
|
'type': String,
|
||||||
default: '40px'
|
'default': '40px'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
|
@ -72,8 +72,8 @@ import { mapState, mapGetters } from 'vuex';
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
isWhite: {
|
isWhite: {
|
||||||
type: Boolean,
|
'type': Boolean,
|
||||||
default: false
|
'default': false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|
|
@ -89,12 +89,12 @@ export default {
|
||||||
props: {
|
props: {
|
||||||
value: [Number, String],
|
value: [Number, String],
|
||||||
data: {
|
data: {
|
||||||
type: Array,
|
'type': Array,
|
||||||
default: () => []
|
'default': () => []
|
||||||
},
|
},
|
||||||
field: {
|
field: {
|
||||||
type: String,
|
'type': String,
|
||||||
default: 'value'
|
'default': 'value'
|
||||||
},
|
},
|
||||||
keepFirst: Boolean,
|
keepFirst: Boolean,
|
||||||
clearOnSelect: Boolean,
|
clearOnSelect: Boolean,
|
||||||
|
@ -105,8 +105,8 @@ export default {
|
||||||
clearable: Boolean,
|
clearable: Boolean,
|
||||||
maxHeight: [String, Number],
|
maxHeight: [String, Number],
|
||||||
dropdownPosition: {
|
dropdownPosition: {
|
||||||
type: String,
|
'type': String,
|
||||||
default: 'auto'
|
'default': 'auto'
|
||||||
},
|
},
|
||||||
iconRight: String,
|
iconRight: String,
|
||||||
iconRightClickable: Boolean,
|
iconRightClickable: Boolean,
|
||||||
|
@ -159,25 +159,25 @@ export default {
|
||||||
* Check if exists default slot
|
* Check if exists default slot
|
||||||
*/
|
*/
|
||||||
hasDefaultSlot() {
|
hasDefaultSlot() {
|
||||||
return !!this.$scopedSlots.default;
|
return Boolean(this.$scopedSlots.default);
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Check if exists "empty" slot
|
* Check if exists "empty" slot
|
||||||
*/
|
*/
|
||||||
hasEmptySlot() {
|
hasEmptySlot() {
|
||||||
return !!this.$slots.empty;
|
return Boolean(this.$slots.empty);
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Check if exists "header" slot
|
* Check if exists "header" slot
|
||||||
*/
|
*/
|
||||||
hasHeaderSlot() {
|
hasHeaderSlot() {
|
||||||
return !!this.$slots.header;
|
return Boolean(this.$slots.header);
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Check if exists "footer" slot
|
* Check if exists "footer" slot
|
||||||
*/
|
*/
|
||||||
hasFooterSlot() {
|
hasFooterSlot() {
|
||||||
return !!this.$slots.footer;
|
return Boolean(this.$slots.footer);
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Apply dropdownPosition property
|
* Apply dropdownPosition property
|
||||||
|
@ -202,7 +202,8 @@ export default {
|
||||||
// eslint-disable-next-line no-nested-ternary
|
// eslint-disable-next-line no-nested-ternary
|
||||||
maxHeight: this.maxHeight === undefined
|
maxHeight: this.maxHeight === undefined
|
||||||
// eslint-disable-next-line no-restricted-globals
|
// eslint-disable-next-line no-restricted-globals
|
||||||
? null : (isNaN(this.maxHeight) ? this.maxHeight : `${this.maxHeight}px`)
|
? null
|
||||||
|
: (isNaN(this.maxHeight) ? this.maxHeight : `${this.maxHeight}px`)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -239,7 +240,7 @@ export default {
|
||||||
}
|
}
|
||||||
// Close dropdown if input is clear or else open it
|
// Close dropdown if input is clear or else open it
|
||||||
if (this.hasFocus && (!this.openOnFocus || value)) {
|
if (this.hasFocus && (!this.openOnFocus || value)) {
|
||||||
this.isActive = !!value;
|
this.isActive = Boolean(value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
|
@ -378,8 +379,8 @@ export default {
|
||||||
* reached it's end.
|
* reached it's end.
|
||||||
*/
|
*/
|
||||||
checkIfReachedTheEndOfScroll(list) {
|
checkIfReachedTheEndOfScroll(list) {
|
||||||
if (list.clientHeight !== list.scrollHeight
|
if (list.clientHeight !== list.scrollHeight &&
|
||||||
&& list.scrollTop + list.clientHeight >= list.scrollHeight) {
|
list.scrollTop + list.clientHeight >= list.scrollHeight) {
|
||||||
this.$emit('infinite-scroll');
|
this.$emit('infinite-scroll');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -396,9 +397,9 @@ export default {
|
||||||
if (this.$refs.dropdown === undefined) return;
|
if (this.$refs.dropdown === undefined) return;
|
||||||
const rect = this.$refs.dropdown.getBoundingClientRect();
|
const rect = this.$refs.dropdown.getBoundingClientRect();
|
||||||
this.isListInViewportVertically = (
|
this.isListInViewportVertically = (
|
||||||
rect.top >= 0
|
rect.top >= 0 &&
|
||||||
&& rect.bottom <= (window.innerHeight
|
rect.bottom <= (window.innerHeight ||
|
||||||
|| document.documentElement.clientHeight)
|
document.documentElement.clientHeight)
|
||||||
);
|
);
|
||||||
if (this.appendToBody) {
|
if (this.appendToBody) {
|
||||||
this.updateAppendToBody();
|
this.updateAppendToBody();
|
||||||
|
@ -425,9 +426,9 @@ export default {
|
||||||
list.scrollTop = element.offsetTop;
|
list.scrollTop = element.offsetTop;
|
||||||
} else if (element.offsetTop >= visMax) {
|
} else if (element.offsetTop >= visMax) {
|
||||||
list.scrollTop = (
|
list.scrollTop = (
|
||||||
element.offsetTop
|
element.offsetTop -
|
||||||
- list.clientHeight
|
list.clientHeight +
|
||||||
+ element.clientHeight
|
element.clientHeight
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -487,7 +488,7 @@ export default {
|
||||||
if (dropdownMenu && trigger) {
|
if (dropdownMenu && trigger) {
|
||||||
// update wrapper dropdown
|
// update wrapper dropdown
|
||||||
const root = this.$data._bodyEl;
|
const root = this.$data._bodyEl;
|
||||||
root.classList.forEach((item) => root.classList.remove(item));
|
root.classList.forEach(item => root.classList.remove(item));
|
||||||
root.classList.add('autocomplete');
|
root.classList.add('autocomplete');
|
||||||
root.classList.add('control');
|
root.classList.add('control');
|
||||||
if (this.expandend) {
|
if (this.expandend) {
|
||||||
|
@ -496,10 +497,10 @@ export default {
|
||||||
const rect = trigger.getBoundingClientRect();
|
const rect = trigger.getBoundingClientRect();
|
||||||
let top = rect.top + window.scrollY;
|
let top = rect.top + window.scrollY;
|
||||||
const left = rect.left + window.scrollX;
|
const left = rect.left + window.scrollX;
|
||||||
if (!this.isOpenedTop) {
|
if (this.isOpenedTop) {
|
||||||
top += trigger.clientHeight;
|
|
||||||
} else {
|
|
||||||
top -= dropdownMenu.clientHeight;
|
top -= dropdownMenu.clientHeight;
|
||||||
|
} else {
|
||||||
|
top += trigger.clientHeight;
|
||||||
}
|
}
|
||||||
this.style = {
|
this.style = {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
ref="autocomplete"
|
ref="autocomplete"
|
||||||
v-model="query"
|
v-model="query"
|
||||||
:data="filteredHints"
|
:data="filteredHints"
|
||||||
:customSelector="handleSelect"
|
:custom-selector="handleSelect"
|
||||||
field="name"
|
field="name"
|
||||||
class="lolisafe-input search"
|
class="lolisafe-input search"
|
||||||
placeholder="Search"
|
placeholder="Search"
|
||||||
|
@ -40,8 +40,8 @@ export default {
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
hiddenHints: {
|
hiddenHints: {
|
||||||
type: Array,
|
'type': Array,
|
||||||
default: () => []
|
'default': () => []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
@ -49,34 +49,34 @@ export default {
|
||||||
query: '',
|
query: '',
|
||||||
hints: [
|
hints: [
|
||||||
{
|
{
|
||||||
'name': 'tag',
|
name: 'tag',
|
||||||
'valueFormat': 'name',
|
valueFormat: 'name',
|
||||||
'hint': ''
|
hint: ''
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'album',
|
name: 'album',
|
||||||
'valueFormat': 'name',
|
valueFormat: 'name',
|
||||||
'hint': ''
|
hint: ''
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'before',
|
name: 'before',
|
||||||
'valueFormat': 'specific date',
|
valueFormat: 'specific date',
|
||||||
'hint': ''
|
hint: ''
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'during',
|
name: 'during',
|
||||||
'valueFormat': 'specific date',
|
valueFormat: 'specific date',
|
||||||
'hint': ''
|
hint: ''
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'after',
|
name: 'after',
|
||||||
'valueFormat': 'specific date',
|
valueFormat: 'specific date',
|
||||||
'hint': ''
|
hint: ''
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'file',
|
name: 'file',
|
||||||
'valueFormat': 'generated name',
|
valueFormat: 'generated name',
|
||||||
'hint': ''
|
hint: ''
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
filteredHints: []
|
filteredHints: []
|
||||||
|
@ -98,13 +98,22 @@ export default {
|
||||||
// get the last word or group of words
|
// get the last word or group of words
|
||||||
let lastWord = (qry.match(/("[^"]*")|[^\s]+/g) || ['']).pop().toLowerCase();
|
let lastWord = (qry.match(/("[^"]*")|[^\s]+/g) || ['']).pop().toLowerCase();
|
||||||
// if there's an open/unbalanced quote, don't autosuggest
|
// if there's an open/unbalanced quote, don't autosuggest
|
||||||
if (/^[^"]*("[^"]*"[^"]*)*(")[^"]*$/.test(qry)) { this.filteredHints = []; return; }
|
if (/^[^"]*("[^"]*"[^"]*)*(")[^"]*$/.test(qry)) {
|
||||||
|
this.filteredHints = [];
|
||||||
|
return;
|
||||||
|
}
|
||||||
// don't autosuggest if we have an open query but no text yet
|
// don't autosuggest if we have an open query but no text yet
|
||||||
if (/:\s+$/gi.test(qry)) { this.filteredHints = []; return; }
|
if (/:\s+$/gi.test(qry)) {
|
||||||
|
this.filteredHints = [];
|
||||||
|
return;
|
||||||
|
}
|
||||||
// if the above query didn't match (all quotes are balanced
|
// if the above query didn't match (all quotes are balanced
|
||||||
// and the previous tag has value
|
// and the previous tag has value
|
||||||
// check if we're about to start a new tag
|
// check if we're about to start a new tag
|
||||||
if (/\s+$/gi.test(qry)) { this.filteredHints = this.hints; return; }
|
if (/\s+$/gi.test(qry)) {
|
||||||
|
this.filteredHints = this.hints;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// ignore starting `-` from lastword, because - is used to
|
// ignore starting `-` from lastword, because - is used to
|
||||||
// exclude something, so -alb should autosuggest album
|
// exclude something, so -alb should autosuggest album
|
||||||
|
@ -112,7 +121,7 @@ export default {
|
||||||
|
|
||||||
// if we got here, then we handled all special cases
|
// if we got here, then we handled all special cases
|
||||||
// now take last word, and check if we can autosuggest a tag
|
// now take last word, and check if we can autosuggest a tag
|
||||||
this.filteredHints = this.hints.filter((hint) => hint.name
|
this.filteredHints = this.hints.filter(hint => hint.name
|
||||||
.toString()
|
.toString()
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
.indexOf(lastWord) === 0);
|
.indexOf(lastWord) === 0);
|
||||||
|
|
|
@ -48,7 +48,7 @@ import { mapState } from 'vuex';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
computed: mapState({
|
computed: mapState({
|
||||||
user: (state) => state.auth.user
|
user: state => state.auth.user
|
||||||
}),
|
}),
|
||||||
methods: {
|
methods: {
|
||||||
isRouteActive(id) {
|
isRouteActive(id) {
|
||||||
|
|
|
@ -93,8 +93,8 @@ export default {
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
...mapState({
|
||||||
config: (state) => state.config,
|
config: state => state.config,
|
||||||
albums: (state) => state.albums.tinyDetails
|
albums: state => state.albums.tinyDetails
|
||||||
}),
|
}),
|
||||||
...mapGetters({ loggedIn: 'auth/isLoggedIn', token: 'auth/getToken' })
|
...mapGetters({ loggedIn: 'auth/isLoggedIn', token: 'auth/getToken' })
|
||||||
},
|
},
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
v-bar
|
v-bar
|
||||||
class="scroll-area">
|
class="scroll-area">
|
||||||
<div class="default-body">
|
<div class="default-body">
|
||||||
<Navbar :isWhite="true" />
|
<Navbar :is-white="true" />
|
||||||
<nuxt-child
|
<nuxt-child
|
||||||
id="app"
|
id="app"
|
||||||
class="nuxt-app is-height-max-content" />
|
class="nuxt-app is-height-max-content" />
|
||||||
|
@ -23,7 +23,7 @@ export default {
|
||||||
},
|
},
|
||||||
computed: mapState(['config', 'alert']),
|
computed: mapState(['config', 'alert']),
|
||||||
created() {
|
created() {
|
||||||
this.$store.watch((state) => state.alert.message, () => {
|
this.$store.watch(state => state.alert.message, () => {
|
||||||
const { message, type, snackbar } = this.alert;
|
const { message, type, snackbar } = this.alert;
|
||||||
|
|
||||||
if (!message) return;
|
if (!message) return;
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<section class="hero is-fullheight">
|
<section class="hero is-fullheight">
|
||||||
<Navbar :isWhite="true" />
|
<Navbar :is-white="true" />
|
||||||
<div class="hero-body">
|
<div class="hero-body">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h2>404エラ</h2>
|
<h2>404エラ</h2>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
export default function ({ store, redirect }) {
|
export default function({ store, redirect }) {
|
||||||
// If the user is not authenticated
|
// If the user is not authenticated
|
||||||
if (!store.state.auth.user) return redirect('/login');
|
if (!store.state.auth.user) return redirect('/login');
|
||||||
if (!store.state.auth.user.isAdmin) return redirect('/dashboard');
|
if (!store.state.auth.user.isAdmin) return redirect('/dashboard');
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
export default function ({ store, redirect }) {
|
export default function({ store, redirect }) {
|
||||||
// If the user is not authenticated
|
// If the user is not authenticated
|
||||||
if (!store.state.auth.loggedIn) {
|
if (!store.state.auth.loggedIn) {
|
||||||
return redirect('/login');
|
return redirect('/login');
|
||||||
|
|
|
@ -36,10 +36,10 @@
|
||||||
<Grid
|
<Grid
|
||||||
v-if="files && files.length"
|
v-if="files && files.length"
|
||||||
:files="files"
|
:files="files"
|
||||||
:isPublic="true"
|
:is-public="true"
|
||||||
:width="200"
|
:width="200"
|
||||||
:enableSearch="false"
|
:enable-search="false"
|
||||||
:enableToolbar="false" />
|
:enable-toolbar="false" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
|
|
|
@ -115,9 +115,9 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({ 'apiKey': 'auth/getApiKey' }),
|
...mapGetters({ apiKey: 'auth/getApiKey' }),
|
||||||
...mapState({
|
...mapState({
|
||||||
user: (state) => state.auth.user
|
user: state => state.auth.user
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
metaInfo() {
|
metaInfo() {
|
||||||
|
|
|
@ -168,6 +168,7 @@ export default {
|
||||||
|
|
||||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-mixed-operators
|
||||||
return `${parseFloat((bytes / k ** i).toFixed(dm))} ${sizes[i]}`;
|
return `${parseFloat((bytes / k ** i).toFixed(dm))} ${sizes[i]}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,7 +145,7 @@ export default {
|
||||||
return { title: 'Settings' };
|
return { title: 'Settings' };
|
||||||
},
|
},
|
||||||
computed: mapState({
|
computed: mapState({
|
||||||
settings: (state) => state.admin.settings
|
settings: state => state.admin.settings
|
||||||
}),
|
}),
|
||||||
methods: {
|
methods: {
|
||||||
promptRestartService() {
|
promptRestartService() {
|
||||||
|
|
|
@ -92,7 +92,7 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: mapState({
|
computed: mapState({
|
||||||
user: (state) => state.admin.user
|
user: state => state.admin.user
|
||||||
}),
|
}),
|
||||||
methods: {
|
methods: {
|
||||||
promptDisableUser() {
|
promptDisableUser() {
|
||||||
|
|
|
@ -102,8 +102,8 @@ export default {
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
computed: mapState({
|
computed: mapState({
|
||||||
users: (state) => state.admin.users,
|
users: state => state.admin.users,
|
||||||
config: (state) => state.config
|
config: state => state.config
|
||||||
}),
|
}),
|
||||||
metaInfo() {
|
metaInfo() {
|
||||||
return { title: 'Uploads' };
|
return { title: 'Uploads' };
|
||||||
|
|
|
@ -74,7 +74,7 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions({
|
...mapActions({
|
||||||
'alert': 'alert/set'
|
alert: 'alert/set'
|
||||||
}),
|
}),
|
||||||
async createAlbum() {
|
async createAlbum() {
|
||||||
if (!this.newAlbumName || this.newAlbumName === '') return;
|
if (!this.newAlbumName || this.newAlbumName === '') return;
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
<Grid
|
<Grid
|
||||||
v-if="totalFiles && !isLoading"
|
v-if="totalFiles && !isLoading"
|
||||||
:files="images.files"
|
:files="images.files"
|
||||||
:enableSearch="false"
|
:enable-search="false"
|
||||||
class="grid">
|
class="grid">
|
||||||
<template v-slot:pagination>
|
<template v-slot:pagination>
|
||||||
<b-pagination
|
<b-pagination
|
||||||
|
@ -112,6 +112,7 @@ export default {
|
||||||
this.search = query;
|
this.search = query;
|
||||||
|
|
||||||
const sanitizedQ = this.sanitizeQuery(query);
|
const sanitizedQ = this.sanitizeQuery(query);
|
||||||
|
// eslint-disable-next-line no-negated-condition
|
||||||
if (!sanitizedQ.length) {
|
if (!sanitizedQ.length) {
|
||||||
this.current = 1;
|
this.current = 1;
|
||||||
await this.fetch(this.current);
|
await this.fetch(this.current);
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
export default function ({ $axios, store }) {
|
export default function({ $axios, store }) {
|
||||||
$axios.setHeader('accept', 'application/vnd.lolisafe.json');
|
$axios.setHeader('accept', 'application/vnd.lolisafe.json');
|
||||||
|
|
||||||
$axios.onRequest((config) => {
|
$axios.onRequest(config => {
|
||||||
if (store.state.auth.token) {
|
if (store.state.auth.token) {
|
||||||
config.headers.common.Authorization = `bearer ${store.state.auth.token}`;
|
config.headers.common.Authorization = `bearer ${store.state.auth.token}`;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$axios.onError((error) => {
|
$axios.onError(error => {
|
||||||
if (process.env.NODE_ENV !== 'production') console.error('[AXIOS Error]', error);
|
if (process.env.NODE_ENV !== 'production') console.error('[AXIOS Error]', error);
|
||||||
if (process.browser) {
|
if (process.browser) {
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
|
|
@ -6,11 +6,11 @@ const search = new FlexSearch('speed');
|
||||||
// https://github.com/nextapps-de/flexsearch
|
// https://github.com/nextapps-de/flexsearch
|
||||||
|
|
||||||
Vue.prototype.$search = {
|
Vue.prototype.$search = {
|
||||||
items: async (items) => {
|
'items': async items => {
|
||||||
await search.clear();
|
await search.clear();
|
||||||
await search.add(items);
|
await search.add(items);
|
||||||
},
|
},
|
||||||
do: async (term, field) => {
|
'do': async (term, field) => {
|
||||||
const results = await search.search(term, { field });
|
const results = await search.search(term, { field });
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
export default async (ctx) => {
|
export default async ctx => {
|
||||||
await ctx.store.dispatch('nuxtClientInit', ctx);
|
await ctx.store.dispatch('nuxtClientInit', ctx);
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,8 +9,8 @@ export const state = () => ({
|
||||||
});
|
});
|
||||||
|
|
||||||
export const getters = {
|
export const getters = {
|
||||||
isExpanded: (state) => (id) => state.expandedAlbums.indexOf(id) > -1,
|
isExpanded: state => id => state.expandedAlbums.indexOf(id) > -1,
|
||||||
getDetails: (state) => (id) => state.albumDetails[id] || {}
|
getDetails: state => id => state.albumDetails[id] || {}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const actions = {
|
export const actions = {
|
||||||
|
|
|
@ -11,9 +11,9 @@ const getDefaultState = () => ({
|
||||||
export const state = getDefaultState;
|
export const state = getDefaultState;
|
||||||
|
|
||||||
export const getters = {
|
export const getters = {
|
||||||
isLoggedIn: (state) => state.loggedIn,
|
isLoggedIn: state => state.loggedIn,
|
||||||
getApiKey: (state) => state.user?.apiKey,
|
getApiKey: state => state.user?.apiKey,
|
||||||
getToken: (state) => state.token
|
getToken: state => state.token
|
||||||
};
|
};
|
||||||
|
|
||||||
export const actions = {
|
export const actions = {
|
||||||
|
|
Loading…
Reference in New Issue