mirror of
https://github.com/Luzifer/share.git
synced 2024-12-20 10:31:16 +00:00
Add markdown support, update deps, improve build
Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
parent
bc37e8cbdc
commit
3d30096026
10 changed files with 22936 additions and 9388 deletions
22
Makefile
22
Makefile
|
@ -1,16 +1,30 @@
|
||||||
default:
|
default:
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
docker run --rm -ti -v $(CURDIR):$(CURDIR) -w $(CURDIR) luzifer/eslint src/*.js
|
docker run --rm -ti \
|
||||||
|
-v "$(CURDIR):/src" \
|
||||||
|
-w "/src/src" \
|
||||||
|
node:12-alpine \
|
||||||
|
npx eslint --ext .js,.vue --fix .
|
||||||
|
|
||||||
pack: webpack
|
pack: webpack
|
||||||
go-bindata -modtime 1 frontend/...
|
go-bindata \
|
||||||
|
-modtime 1 \
|
||||||
|
frontend/...
|
||||||
|
|
||||||
webpack: src/node_modules
|
webpack: src/node_modules
|
||||||
cd src && npm run build
|
docker run --rm -i \
|
||||||
|
-v "$(CURDIR):/src" \
|
||||||
|
-w "/src/src" \
|
||||||
|
node:12-alpine \
|
||||||
|
npm run build
|
||||||
|
|
||||||
src/node_modules:
|
src/node_modules:
|
||||||
cd src && npm install
|
docker run --rm -i \
|
||||||
|
-v "$(CURDIR):/src" \
|
||||||
|
-w "/src/src" \
|
||||||
|
node:12-alpine \
|
||||||
|
npm ci
|
||||||
|
|
||||||
auto-hook-pre-commit: pack
|
auto-hook-pre-commit: pack
|
||||||
git diff --exit-code bindata.go
|
git diff --exit-code bindata.go
|
||||||
|
|
30728
bindata.go
30728
bindata.go
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
|
@ -6,7 +6,7 @@
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/combine/npm/bootstrap@4.3.1/dist/css/bootstrap.min.css,npm/bootstrap-vue@2.0.0-rc.19/dist/bootstrap-vue.min.css,npm/bootswatch@4.3.1/dist/darkly/bootstrap.min.css,npm/highlight.js@9.15.6/styles/androidstudio.min.css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/combine/npm/highlight.js@9.15.6/styles/androidstudio.min.css">
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.2/css/all.css"
|
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.2/css/all.css"
|
||||||
integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay" crossorigin="anonymous">
|
integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay" crossorigin="anonymous">
|
||||||
|
@ -15,8 +15,6 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/combine/npm/vue@2.6.10,npm/bootstrap-vue@2.0.0-rc.19/dist/bootstrap-vue.min.js,npm/axios@0.18.0/dist/axios.min.js"></script>
|
|
||||||
<script src="app.js"></script>
|
<script src="app.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
2
src/.eslintignore
Normal file
2
src/.eslintignore
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
webpack.config.js
|
||||||
|
.eslintrc.js
|
|
@ -1,32 +1,31 @@
|
||||||
// https://eslint.org/docs/user-guide/configuring
|
// https://eslint.org/docs/user-guide/configuring
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
'root': true,
|
root: true,
|
||||||
'parserOptions': {
|
parserOptions: {
|
||||||
parser: 'babel-eslint',
|
parser: 'babel-eslint',
|
||||||
sourceType: 'module',
|
|
||||||
},
|
},
|
||||||
'env': {
|
env: {
|
||||||
node: true,
|
browser: true,
|
||||||
},
|
},
|
||||||
'extends': [
|
extends: [
|
||||||
/*
|
/*
|
||||||
* https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention
|
* https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention
|
||||||
* consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules.
|
* consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules.
|
||||||
*/
|
*/
|
||||||
'plugin:vue/essential',
|
'plugin:vue/strongly-recommended',
|
||||||
// https://github.com/standard/standard/blob/master/docs/RULES-en.md
|
// https://github.com/standard/standard/blob/master/docs/RULES-en.md
|
||||||
'eslint:recommended',
|
'eslint:recommended',
|
||||||
],
|
],
|
||||||
// required to lint *.vue files
|
// required to lint *.vue files
|
||||||
'plugins': ['vue'],
|
plugins: ['vue'],
|
||||||
'globals': {
|
globals: {
|
||||||
locale: true,
|
axios: true,
|
||||||
process: true,
|
process: true,
|
||||||
version: true,
|
Vue: true,
|
||||||
},
|
},
|
||||||
// add your custom rules here
|
// add your custom rules here
|
||||||
'rules': {
|
rules: {
|
||||||
'array-bracket-newline': ['error', { multiline: true }],
|
'array-bracket-newline': ['error', { multiline: true }],
|
||||||
'array-bracket-spacing': ['error'],
|
'array-bracket-spacing': ['error'],
|
||||||
'arrow-body-style': ['error', 'as-needed'],
|
'arrow-body-style': ['error', 'as-needed'],
|
||||||
|
@ -41,7 +40,7 @@ module.exports = {
|
||||||
'dot-location': ['error', 'property'],
|
'dot-location': ['error', 'property'],
|
||||||
'dot-notation': ['error'],
|
'dot-notation': ['error'],
|
||||||
'eol-last': ['error', 'always'],
|
'eol-last': ['error', 'always'],
|
||||||
'eqeqeq': ['error', 'always', { 'null': 'ignore' }],
|
'eqeqeq': ['error', 'always', { null: 'ignore' }],
|
||||||
'func-call-spacing': ['error', 'never'],
|
'func-call-spacing': ['error', 'never'],
|
||||||
'function-paren-newline': ['error', 'multiline'],
|
'function-paren-newline': ['error', 'multiline'],
|
||||||
'generator-star-spacing': ['off'], // allow async-await
|
'generator-star-spacing': ['off'], // allow async-await
|
||||||
|
@ -55,6 +54,7 @@ module.exports = {
|
||||||
'newline-per-chained-call': ['error'],
|
'newline-per-chained-call': ['error'],
|
||||||
'no-console': ['off'],
|
'no-console': ['off'],
|
||||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', // allow debugger during development
|
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', // allow debugger during development
|
||||||
|
'no-duplicate-imports': ['error'],
|
||||||
'no-else-return': ['error'],
|
'no-else-return': ['error'],
|
||||||
'no-extra-parens': ['error'],
|
'no-extra-parens': ['error'],
|
||||||
'no-implicit-coercion': ['error'],
|
'no-implicit-coercion': ['error'],
|
||||||
|
@ -64,6 +64,7 @@ module.exports = {
|
||||||
'no-trailing-spaces': ['error'],
|
'no-trailing-spaces': ['error'],
|
||||||
'no-unneeded-ternary': ['error'],
|
'no-unneeded-ternary': ['error'],
|
||||||
'no-useless-return': ['error'],
|
'no-useless-return': ['error'],
|
||||||
|
'no-var': ['error'],
|
||||||
'no-whitespace-before-property': ['error'],
|
'no-whitespace-before-property': ['error'],
|
||||||
'object-curly-newline': ['error', { consistent: true }],
|
'object-curly-newline': ['error', { consistent: true }],
|
||||||
'object-curly-spacing': ['error', 'always'],
|
'object-curly-spacing': ['error', 'always'],
|
||||||
|
@ -72,16 +73,21 @@ module.exports = {
|
||||||
'prefer-arrow-callback': ['error'],
|
'prefer-arrow-callback': ['error'],
|
||||||
'prefer-const': ['error'],
|
'prefer-const': ['error'],
|
||||||
'prefer-object-spread': ['error'],
|
'prefer-object-spread': ['error'],
|
||||||
|
'prefer-rest-params': ['error'],
|
||||||
'prefer-template': ['error'],
|
'prefer-template': ['error'],
|
||||||
'quote-props': ['error', 'consistent-as-needed', { keywords: true }],
|
'quote-props': ['error', 'consistent-as-needed', { keywords: false }],
|
||||||
'quotes': ['error', 'single', { allowTemplateLiterals: true }],
|
'quotes': ['error', 'single', { allowTemplateLiterals: true }],
|
||||||
'semi': ['error', 'never'],
|
'semi': ['error', 'never'],
|
||||||
|
'sort-imports': ['error', { ignoreCase: true, ignoreDeclarationSort: false, ignoreMemberSort: false }],
|
||||||
|
'sort-keys': ['error', 'asc', { caseSensitive: true, natural: false }],
|
||||||
'space-before-blocks': ['error', 'always'],
|
'space-before-blocks': ['error', 'always'],
|
||||||
'spaced-comment': ['warn', 'always'],
|
'spaced-comment': ['warn', 'always'],
|
||||||
|
'space-before-function-paren': ['error', 'never'],
|
||||||
'space-infix-ops': ['error'],
|
'space-infix-ops': ['error'],
|
||||||
'space-in-parens': ['error', 'never'],
|
'space-in-parens': ['error', 'never'],
|
||||||
'space-unary-ops': ['error', { words: true, nonwords: false }],
|
'space-unary-ops': ['error', { words: true, nonwords: false }],
|
||||||
'switch-colon-spacing': ['error'],
|
'switch-colon-spacing': ['error'],
|
||||||
|
'template-curly-spacing': ['error', 'never'],
|
||||||
'unicode-bom': ['error', 'never'],
|
'unicode-bom': ['error', 'never'],
|
||||||
'wrap-iife': ['error'],
|
'wrap-iife': ['error'],
|
||||||
'yoda': ['error'],
|
'yoda': ['error'],
|
||||||
|
|
92
src/app.vue
92
src/app.vue
|
@ -1,26 +1,32 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
|
<b-navbar
|
||||||
<b-navbar variant="primary" type="dark">
|
variant="primary"
|
||||||
<b-navbar-brand href="#"><i class="fas fa-share-alt-square"></i> Share</b-navbar-brand>
|
type="dark"
|
||||||
|
>
|
||||||
|
<b-navbar-brand href="#">
|
||||||
|
<i class="fas fa-share-alt-square" /> Share
|
||||||
|
</b-navbar-brand>
|
||||||
</b-navbar>
|
</b-navbar>
|
||||||
|
|
||||||
<b-container class="mt-4">
|
<b-container class="mt-4">
|
||||||
<b-row>
|
<b-row>
|
||||||
<b-col>
|
<b-col>
|
||||||
|
|
||||||
<b-card v-if="loading">
|
<b-card v-if="loading">
|
||||||
<b-card-text class="text-center">
|
<b-card-text class="text-center">
|
||||||
<h2><i class="fas fa-spinner fa-pulse"></i></h2>
|
<h2><i class="fas fa-spinner fa-pulse" /></h2>
|
||||||
{{ strings.loading }}
|
{{ strings.loading }}
|
||||||
</b-card-text>
|
</b-card-text>
|
||||||
</b-card>
|
</b-card>
|
||||||
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
|
<b-card
|
||||||
<b-card v-if="error" bg-variant="danger" text-variant="white">
|
v-if="error"
|
||||||
|
bg-variant="danger"
|
||||||
|
text-variant="white"
|
||||||
|
>
|
||||||
<b-card-text class="text-center">
|
<b-card-text class="text-center">
|
||||||
<h2><i class="fas fa-exclamation-circle"></i></h2>
|
<h2><i class="fas fa-exclamation-circle" /></h2>
|
||||||
{{ error }}
|
{{ error }}
|
||||||
</b-card-text>
|
</b-card-text>
|
||||||
</b-card>
|
</b-card>
|
||||||
|
@ -28,49 +34,71 @@
|
||||||
<b-card v-else-if="fileType.startsWith('image/')">
|
<b-card v-else-if="fileType.startsWith('image/')">
|
||||||
<b-card-text class="text-center">
|
<b-card-text class="text-center">
|
||||||
<a :href="path">
|
<a :href="path">
|
||||||
<b-img :src="path" fluid></b-img>
|
<b-img
|
||||||
|
:src="path"
|
||||||
|
fluid
|
||||||
|
/>
|
||||||
</a>
|
</a>
|
||||||
</b-card-text>
|
</b-card-text>
|
||||||
</b-card>
|
</b-card>
|
||||||
|
|
||||||
<b-card v-else-if="fileType.startsWith('video/')">
|
<b-card v-else-if="fileType.startsWith('video/')">
|
||||||
<b-embed type="video" :src="path" allowfullscreen controls></b-embed>
|
<b-embed
|
||||||
|
type="video"
|
||||||
|
:src="path"
|
||||||
|
allowfullscreen
|
||||||
|
controls
|
||||||
|
/>
|
||||||
</b-card>
|
</b-card>
|
||||||
|
|
||||||
<b-card v-else-if="fileType.startsWith('audio/')">
|
<b-card v-else-if="fileType.startsWith('audio/')">
|
||||||
<b-card-text class="text-center">
|
<b-card-text class="text-center">
|
||||||
<audio :src="path" controls></audio>
|
<audio
|
||||||
|
:src="path"
|
||||||
|
controls
|
||||||
|
/>
|
||||||
</b-card-text>
|
</b-card-text>
|
||||||
</b-card>
|
</b-card>
|
||||||
|
|
||||||
|
<b-card
|
||||||
|
v-else-if="fileType.startsWith('text/markdown')"
|
||||||
|
no-body
|
||||||
|
>
|
||||||
|
<b-card-body
|
||||||
|
v-html="renderMarkdown(text)"
|
||||||
|
/>
|
||||||
|
</b-card>
|
||||||
|
|
||||||
<b-card v-else-if="fileType.startsWith('text/')">
|
<b-card v-else-if="fileType.startsWith('text/')">
|
||||||
<pre><code>{{ text }}</code></pre>
|
<pre><code>{{ text }}</code></pre>
|
||||||
</b-card>
|
</b-card>
|
||||||
|
|
||||||
<b-card v-else>
|
<b-card v-else>
|
||||||
<b-card-text class="text-center">
|
<b-card-text class="text-center">
|
||||||
<h2><i class="fas fa-cloud-download-alt"></i></h2>
|
<h2><i class="fas fa-cloud-download-alt" /></h2>
|
||||||
<b-button :href="path" variant="success">{{ fileName }}</b-button>
|
<b-button
|
||||||
|
:href="path"
|
||||||
|
variant="success"
|
||||||
|
>
|
||||||
|
{{ fileName }}
|
||||||
|
</b-button>
|
||||||
</b-card-text>
|
</b-card-text>
|
||||||
</b-card>
|
</b-card>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
</b-container>
|
</b-container>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import axios from 'axios'
|
||||||
import hljs from 'highlight.js'
|
import hljs from 'highlight.js'
|
||||||
import rewrites from './mime-rewrite.js'
|
import rewrites from './mime-rewrite.js'
|
||||||
|
import showdown from 'showdown'
|
||||||
import strings from './strings.js'
|
import strings from './strings.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'app',
|
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
strings() {
|
strings() {
|
||||||
return strings
|
return strings
|
||||||
|
@ -80,8 +108,8 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
error: null,
|
error: null,
|
||||||
fileType: null,
|
|
||||||
fileName: '',
|
fileName: '',
|
||||||
|
fileType: null,
|
||||||
loading: true,
|
loading: true,
|
||||||
path: '',
|
path: '',
|
||||||
text: '',
|
text: '',
|
||||||
|
@ -99,6 +127,10 @@ export default {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
renderMarkdown(text) {
|
||||||
|
return new showdown.Converter().makeHtml(text)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -106,6 +138,8 @@ export default {
|
||||||
this.hashChange()
|
this.hashChange()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
name: 'App',
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
fileType(v) {
|
fileType(v) {
|
||||||
// Rewrite known file types not matching the expectations above
|
// Rewrite known file types not matching the expectations above
|
||||||
|
@ -121,7 +155,7 @@ export default {
|
||||||
.then(resp => {
|
.then(resp => {
|
||||||
this.text = resp.data
|
this.text = resp.data
|
||||||
|
|
||||||
if (this.text.length < 200*1024 && v !== 'text/plain') {
|
if (this.text.length < 200 * 1024 && v !== 'text/plain') {
|
||||||
// Only highlight up to 200k and not on text/plain
|
// Only highlight up to 200k and not on text/plain
|
||||||
window.setTimeout(() => hljs.initHighlighting(), 100)
|
window.setTimeout(() => hljs.initHighlighting(), 100)
|
||||||
}
|
}
|
||||||
|
@ -148,18 +182,18 @@ export default {
|
||||||
|
|
||||||
this.loading = false
|
this.loading = false
|
||||||
this.fileType = contentType
|
this.fileType = contentType
|
||||||
this.fileName = this.path.substring(this.path.lastIndexOf('/')+1)
|
this.fileName = this.path.substring(this.path.lastIndexOf('/') + 1)
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
switch (err.response.status) {
|
switch (err.response.status) {
|
||||||
case 403:
|
case 403:
|
||||||
this.error = strings.not_permitted
|
this.error = strings.not_permitted
|
||||||
break
|
break
|
||||||
case 404:
|
case 404:
|
||||||
this.error = strings.file_not_found
|
this.error = strings.file_not_found
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
this.error = `Something went wrong (Status ${err.response.status})`
|
this.error = `Something went wrong (Status ${err.response.status})`
|
||||||
}
|
}
|
||||||
this.loading = false
|
this.loading = false
|
||||||
})
|
})
|
||||||
|
|
14
src/main.js
14
src/main.js
|
@ -1,7 +1,15 @@
|
||||||
import app from './app.vue'
|
import 'bootstrap/dist/css/bootstrap.css'
|
||||||
|
import 'bootstrap-vue/dist/bootstrap-vue.css'
|
||||||
|
import 'bootswatch/dist/darkly/bootstrap.css'
|
||||||
|
|
||||||
|
import App from './app.vue'
|
||||||
|
import { BootstrapVue } from 'bootstrap-vue'
|
||||||
|
import Vue from 'vue'
|
||||||
|
|
||||||
|
Vue.use(BootstrapVue)
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
components: { app },
|
components: { App },
|
||||||
el: '#app',
|
el: '#app',
|
||||||
render: c => c('app'),
|
render: c => c('App'),
|
||||||
})
|
})
|
||||||
|
|
1365
src/package-lock.json
generated
1365
src/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -3,14 +3,17 @@
|
||||||
"description": "",
|
"description": "",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-core": "^6.26.3",
|
"babel-core": "^6.26.3",
|
||||||
|
"babel-eslint": "^10.0.0",
|
||||||
"babel-loader": "^7.1.5",
|
"babel-loader": "^7.1.5",
|
||||||
"babel-preset-env": "^1.7.0",
|
"babel-preset-env": "^1.7.0",
|
||||||
"css-loader": "^1.0.1",
|
"css-loader": "^1.0.1",
|
||||||
|
"eslint": "^7.0.0",
|
||||||
|
"eslint-plugin-vue": "^7.5.0",
|
||||||
"node-sass": "^4.14.1",
|
"node-sass": "^4.14.1",
|
||||||
"sass-loader": "^7.3.1",
|
"sass-loader": "^7.3.1",
|
||||||
"style-loader": "^0.21.0",
|
"style-loader": "^0.21.0",
|
||||||
"vue-loader": "^15.9.3",
|
"vue-loader": "^15.9.3",
|
||||||
"vue-template-compiler": "^2.6.11",
|
"vue-template-compiler": "^2.6.12",
|
||||||
"webpack": "^4.44.1",
|
"webpack": "^4.44.1",
|
||||||
"webpack-cli": "^3.3.12",
|
"webpack-cli": "^3.3.12",
|
||||||
"webpack-dev-middleware": "^1.4.0",
|
"webpack-dev-middleware": "^1.4.0",
|
||||||
|
@ -24,6 +27,11 @@
|
||||||
},
|
},
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"highlight.js": "^9.18.3"
|
"axios": "^0.21.1",
|
||||||
|
"bootstrap-vue": "^2.21.2",
|
||||||
|
"bootswatch": "^4.6.0",
|
||||||
|
"highlight.js": "^9.18.3",
|
||||||
|
"showdown": "^1.9.1",
|
||||||
|
"vue": "^2.6.12"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue