Commit 95d569d1 authored by SpinShare's avatar SpinShare

songdetail 2.0

parent 4d21f8bd
......@@ -2454,26 +2454,12 @@
"tryer": "^1.0.1"
}
},
"big-integer": {
"version": "1.6.48",
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz",
"integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w=="
},
"big.js": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
"integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
"dev": true
},
"binary": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz",
"integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=",
"requires": {
"buffers": "~0.1.1",
"chainsaw": "~0.1.0"
}
},
"binary-extensions": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
......@@ -2818,11 +2804,6 @@
"integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==",
"dev": true
},
"buffer-indexof-polyfill": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.1.tgz",
"integrity": "sha1-qfuAbOgUXVQoUQznLyeLs2OmOL8="
},
"buffer-json": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/buffer-json/-/buffer-json-2.0.0.tgz",
......@@ -2835,11 +2816,6 @@
"integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
"dev": true
},
"buffers": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz",
"integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s="
},
"builder-util": {
"version": "21.2.0",
"resolved": "https://registry.npmjs.org/builder-util/-/builder-util-21.2.0.tgz",
......@@ -3179,14 +3155,6 @@
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
"dev": true
},
"chainsaw": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz",
"integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=",
"requires": {
"traverse": ">=0.3.0 <0.4"
}
},
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
......@@ -3880,7 +3848,8 @@
"core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
"dev": true
},
"cosmiconfig": {
"version": "5.2.1",
......@@ -4776,14 +4745,6 @@
"integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
"dev": true
},
"duplexer2": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
"integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=",
"requires": {
"readable-stream": "^2.0.2"
}
},
"duplexer3": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
......@@ -5051,11 +5012,6 @@
}
}
},
"electron-download-manager": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/electron-download-manager/-/electron-download-manager-2.1.2.tgz",
"integrity": "sha512-9v8aeMVZTX69NjEveKlKfTlJY74twpKktTXrmDI+UcQHZg7FtwuqxWw0ZNrjtVAOBcVNKzwG4ekn44B+xhz1tg=="
},
"electron-publish": {
"version": "21.2.0",
"resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-21.2.0.tgz",
......@@ -5286,10 +5242,9 @@
"dev": true
},
"eventemitter3": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz",
"integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==",
"dev": true
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz",
"integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ=="
},
"events": {
"version": "3.1.0",
......@@ -5751,7 +5706,6 @@
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.11.0.tgz",
"integrity": "sha512-KZm0V+ll8PfBrKwMzdo5D13b1bur9Iq9Zd/RMmAoQQcl2PxxFml8cxXPaaPYVbV0RjNjq1CU7zIzAOqtUPudmA==",
"dev": true,
"requires": {
"debug": "^3.0.0"
},
......@@ -5760,7 +5714,6 @@
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
......@@ -6468,27 +6421,6 @@
}
}
},
"fstream": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
"integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
"requires": {
"graceful-fs": "^4.1.2",
"inherits": "~2.0.0",
"mkdirp": ">=0.5 0",
"rimraf": "2"
},
"dependencies": {
"rimraf": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
"requires": {
"glob": "^7.1.3"
}
}
}
},
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
......@@ -6664,7 +6596,8 @@
"graceful-fs": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
"integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ=="
"integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
"dev": true
},
"grapheme-splitter": {
"version": "1.0.4",
......@@ -7036,10 +6969,9 @@
}
},
"http-proxy": {
"version": "1.18.0",
"resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.0.tgz",
"integrity": "sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==",
"dev": true,
"version": "1.18.1",
"resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
"integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
"requires": {
"eventemitter3": "^4.0.0",
"follow-redirects": "^1.0.0",
......@@ -7642,7 +7574,8 @@
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
"dev": true
},
"isbinaryfile": {
"version": "4.0.6",
......@@ -7975,11 +7908,6 @@
"integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=",
"dev": true
},
"listenercount": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz",
"integrity": "sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc="
},
"load-json-file": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
......@@ -8398,7 +8326,8 @@
"minimist": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
"dev": true
},
"minipass": {
"version": "3.1.1",
......@@ -8487,10 +8416,16 @@
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
"dev": true,
"requires": {
"minimist": "^1.2.5"
}
},
"moment": {
"version": "2.26.0",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.26.0.tgz",
"integrity": "sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw=="
},
"move-concurrently": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
......@@ -8519,8 +8454,7 @@
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"multicast-dns": {
"version": "6.2.3",
......@@ -10017,7 +9951,8 @@
"process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
"dev": true
},
"progress-stream": {
"version": "1.2.0",
......@@ -10368,6 +10303,7 @@
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"dev": true,
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
......@@ -10670,8 +10606,7 @@
"requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
"dev": true
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
},
"resolve": {
"version": "1.16.0",
......@@ -10806,7 +10741,8 @@
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"dev": true
},
"safe-regex": {
"version": "1.1.0",
......@@ -11042,7 +10978,8 @@
"setimmediate": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
"integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
"integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
"dev": true
},
"setprototypeof": {
"version": "1.1.1",
......@@ -11719,6 +11656,7 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"dev": true,
"requires": {
"safe-buffer": "~5.1.0"
}
......@@ -12209,11 +12147,6 @@
"punycode": "^2.1.1"
}
},
"traverse": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz",
"integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk="
},
"trim-newlines": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
......@@ -12467,30 +12400,6 @@
"yaku": "^0.16.6"
}
},
"unzipper": {
"version": "0.10.11",
"resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.11.tgz",
"integrity": "sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==",
"requires": {
"big-integer": "^1.6.17",
"binary": "~0.3.0",
"bluebird": "~3.4.1",
"buffer-indexof-polyfill": "~1.0.0",
"duplexer2": "~0.1.4",
"fstream": "^1.0.12",
"graceful-fs": "^4.2.2",
"listenercount": "~1.0.1",
"readable-stream": "~2.3.6",
"setimmediate": "~1.0.4"
},
"dependencies": {
"bluebird": {
"version": "3.4.7",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz",
"integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM="
}
}
},
"upath": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
......@@ -12626,7 +12535,8 @@
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
"dev": true
},
"util.promisify": {
"version": "1.0.1",
......
......@@ -21,6 +21,7 @@
"axios": "^0.19.2",
"core-js": "^3.6.4",
"glob": "^7.1.6",
"moment": "^2.26.0",
"ncp": "^2.0.0",
"rimraf": "^3.0.2",
"uniqid": "^5.2.0",
......
......@@ -60,7 +60,6 @@
ipcRenderer.send("getDeeplink");
ipcRenderer.on('deeplink', (event, data) => {
console.log(data);
switch(data.view) {
case "Settings":
this.$router.push('Settings');
......
......@@ -62,10 +62,10 @@ app.setAsDefaultProtocolClient("spinshare-user");
function createWindow () {
win = new BrowserWindow({
title: "SpinSha.re",
width: 1300,
width: 1350,
height: 700,
minHeight: 700,
minWidth: 1300,
minWidth: 1350,
webPreferences: {
nodeIntegration: true
}
......
<template>
<div class="review">
<div class="metadata">
<router-link :to="{ name: 'UserDetail', params: { id: user.id } }" class="avatar" :style="'background-image: url(' + user.coverReference + '), url(' + require('@/assets/img/defaultAvatar.jpg') + ');'"></router-link>
<div class="text">
<router-link :to="{ name: 'UserDetail', params: { id: user.id } }" class="username">{{ user.username }}</router-link>
<div class="subline">
<i :class="recommended ? 'mdi mdi-thumb-up positive' : 'mdi mdi-thumb-down negative'"></i>
<span>{{ reviewDate.date | formatDate }}</span>
</div>
</div>
<div class="actions">
</div>
</div>
<div class="comment" v-if="comment">
{{ comment }}
</div>
</div>
</template>
<script>
import { remote } from 'electron';
const { clipboard } = remote;
export default {
name: 'SongReview',
props: [
'id',
'user',
'recommended',
'comment',
'reviewDate'
],
mounted: function() {
},
methods: {
}
}
</script>
<style scoped lang="less">
.review {
background: rgba(255,255,255,0.1);
border-radius: 4px;
padding: 20px;
& .metadata {
display: grid;
grid-template-columns: auto 1fr auto;
grid-gap: 15px;
& .avatar {
width: 48px;
height: 48px;
border-radius: 48px;
background-position: center;
background-size: cover;
display: block;
color: #fff;
text-decoration: none;
transition: 0.2s ease-in-out opacity;
&:hover {
opacity: 0.6;
}
}
& .text {
& .username {
font-size: 16px;
font-weight: bold;
margin-bottom: 5px;
display: block;
color: #fff;
text-decoration: none;
transition: 0.2s ease-in-out opacity;
&:hover {
opacity: 0.6;
}
}
& .subline {
display: grid;
grid-gap: 5px;
grid-template-columns: auto 1fr;
align-items: center;
& i.positive { color: #62d38a; }
& i.negative { color: #f73c56; }
& span {
opacity: 0.6;
}
}
}
& .actions {
align-self: center;
.action {
color: #fff;
text-decoration: none;
font-size: 18px;
background: linear-gradient(135deg, rgba(255,255,255,0.3), rgba(255,255,255,0.1));
border-radius: 4px;
padding: 5px 15px;
transition: 0.2s ease-in-out opacity;
&:hover {
opacity: 0.6;
}
}
}
}
& .comment {
margin-top: 15px;
line-height: 1.5em;
}
}
</style>
<template>
<div class="spinplay">
<div v-on:click="OpenVideo()" class="thumbnail" :style="'background-image: url(' + videoThumbnail + ');'"></div>
<div class="metadata">
<div class="avatar" :style="'background-image: url(' + user.coverReference + '), url(' + require('@/assets/img/defaultAvatar.jpg') + ');'"></div>
<div class="username">{{ user.username }}</div>
<div class="actions">
</div>
</div>
</div>
</template>
<script>
import { remote } from 'electron';
const { shell } = remote;
export default {
name: 'SongSpinPlay',
props: [
'id',
'user',
'videoUrl',
'videoThumbnail',
'submitDate'
],
mounted: function() {
},
methods: {
OpenVideo: function() {
shell.openExternal(this.$props.videoUrl);
}
}
}
</script>
<style scoped lang="less">
.spinplay {
background: rgba(255,255,255,0.1);
border-radius: 4px;
overflow: hidden;
color: #fff;
text-decoration: none;
& .thumbnail {
width: 100%;
display: block;
padding-top: 56.25%;
background: rgba(255,255,255,0.1);
background-position: center;
background-size: cover;
transition: 0.2s ease-in-out opacity;
cursor: pointer;
&:hover {
opacity: 0.6;
}
}
& .metadata {
padding: 15px;
display: grid;
grid-gap: 15px;
align-items: center;
grid-template-columns: auto 1fr auto;
& .avatar {
width: 32px;
height: 32px;
background: rgba(255,255,255,0.1);
background-position: center;
background-size: cover;
border-radius: 40px;
}
& .actions {
.action {
color: #fff;
text-decoration: none;
font-size: 18px;
background: linear-gradient(135deg, rgba(255,255,255,0.3), rgba(255,255,255,0.1));
border-radius: 4px;
padding: 5px 15px;
transition: 0.2s ease-in-out opacity;
&:hover {
opacity: 0.6;
}
}
}
}
}
</style>
{
"locale.translatedBy": "Übersetzung von thatanimeweirdo",
"locale.dateFormat": "DD.MM.YYYY",
"startup.tabs.frontpage": "Startseite",
"startup.tabs.new": "Neu",
"startup.tabs.hot": "Heiß",
......@@ -23,12 +26,7 @@
"library.deletemodal.close": "Schließen",
"library.deletemodal.explorer": "Im Explorer öffnen",
"songdetail.createdBy": "Erstellt von ",
"songdetail.actions.downloadButton": "Downloaden",
"songdetail.actions.playPreviewButton": "Vorschau abspielen",
"songdetail.actions.stopPreviewButton": "Vorschau abbrechen",
"songdetail.actions.copyLinkButton": "Link Kopieren",
"songdetail.actions.reportButton": "Melden",
"songdetail.createdBy": "Erstellt von {charter}",
"userdetail.uploaded.header": "Hochgeladene Songs",
"userdetail.uploaded.noresults": "Dieser Nutzer hat noch keine Songs hochgeladen.",
......@@ -40,7 +38,6 @@
"settings.general.update.button": "Auf Updates überprüfen",
"settings.language.header": "Sprache",
"settings.language.selectLanguage.label": "Sprache auswählen",
"settings.language.translatedBy": "Übersetzung von thatanimeweirdo",
"settings.directories.header": "Ordner",
"settings.directories.gameDirectory.label": "Spiel-Ordner",
"settings.directories.gameDirectory.changeButton": "Ändern",
......
{
"locale.translatedBy": " ",
"locale.dateFormat": "MM/DD/YYYY",
"startup.tabs.frontpage": "Frontpage",
"startup.tabs.new": "New",
"startup.tabs.hot": "Hot",
......@@ -23,12 +26,21 @@
"library.deletemodal.close": "Close",
"library.deletemodal.explorer": "Open in Explorer",
"songdetail.createdBy": "Created by ",
"songdetail.actions.downloadButton": "Download",
"songdetail.actions.playPreviewButton": "Play Preview",
"songdetail.actions.stopPreviewButton": "Stop Preview",
"songdetail.actions.copyLinkButton": "Copy Link",
"songdetail.actions.reportButton": "Report",
"songdetail.createdBy": "Created by {charter}",
"songdetail.uploadedBy": "Uploaded by ",
"songdetail.tabs.reviews": "REVIEWS",
"songdetail.tabs.spinplays": "SPINPLAYS",
"songdetail.reviews.recommended.label": "RECOMMENDED",
"songdetail.reviews.recommended.notenough": "This chart does not have enough user-reviews yet.",
"songdetail.reviews.recommended.basedon": "Based on {amountOfReviews} user-reviews",
"songdetail.reviews.recommended.addReview": "Add Review",
"songdetail.reviews.noresults.title": "There are no reviews yet.",
"songdetail.reviews.noresults.explaination": "Come back later or write a new one!",
"songdetail.spinplays.add.label": "Add your Gameplay Video",
"songdetail.spinplays.add.text": "Did you play this chart? Submit your video and get featured here!",
"songdetail.spinplays.add.submitVideo": "Submit Video",
"songdetail.spinplays.noresults.title": "There are no SpinPlays yet.",
"songdetail.spinplays.noresults.explaination": "Come back later or submit a new one!",
"userdetail.uploaded.header": "Uploaded Songs",
"userdetail.uploaded.noresults": "This user did not upload any songs yet.",
......@@ -40,7 +52,6 @@
"settings.general.update.button": "Check for Updates",
"settings.language.header": "Language",
"settings.language.selectLanguage.label": "Select Language",
"settings.language.translatedBy": " ",
"settings.directories.header": "Directories",
"settings.directories.gameDirectory.label": "Game Directory",
"settings.directories.gameDirectory.changeButton": "Change",
......
{
"locale.translatedBy": "Traducido por BirdHusband",
"locale.dateFormat": "DD/MM/YYYY",
"startup.tabs.frontpage": "Frontpage",
"startup.tabs.new": "New",
"startup.tabs.hot": "Hot",
......@@ -23,12 +26,7 @@
"library.deletemodal.close": "Cerrar",
"library.deletemodal.explorer": "Open in Explorer",
"songdetail.createdBy": "Creado por ",
"songdetail.actions.downloadButton": "Descargar",
"songdetail.actions.playPreviewButton": "Iniciar vista previa",
"songdetail.actions.stopPreviewButton": "Detener vista previa",
"songdetail.actions.copyLinkButton": "Copiar enlace",
"songdetail.actions.reportButton": "Reportar",
"songdetail.createdBy": "Creado por {charter}",
"userdetail.uploaded.header": "Canciones subidas",
"userdetail.uploaded.noresults": "Este usuario no ha subido ninguna canción aún.",
......@@ -40,7 +38,6 @@
"settings.general.update.button": "Buscar actualizaciones",
"settings.language.header": "Lenguaje",
"settings.language.selectLanguage.label": "Seleccionar lenguaje",
"settings.language.translatedBy": "Traducido por BirdHusband",
"settings.directories.header": "Directorios",
"settings.directories.gameDirectory.label": "Ubicación del juego",
"settings.directories.gameDirectory.changeButton": "Cambiar",
......
{
"locale.translatedBy": "Traduction par Frog King",
"locale.dateFormat": "DD/MM/YYYY",
"startup.tabs.frontpage": "Frontpage",
"startup.tabs.new": "New",
"startup.tabs.hot": "Hot",
......@@ -23,12 +26,7 @@
"library.deletemodal.close": "Fermer",
"library.deletemodal.explorer": "Open in Explorer",
"songdetail.createdBy": "Créée par ",
"songdetail.actions.downloadButton": "Télécharger",
"songdetail.actions.playPreviewButton": "Écouter un aperçu",
"songdetail.actions.stopPreviewButton": "Arrêter l'aperçu",
"songdetail.actions.copyLinkButton": "Copier le Lien",
"songdetail.actions.reportButton": "Signaler",
"songdetail.createdBy": "Créée par {charter}",
"userdetail.uploaded.header": "Chansons Publiées",
"userdetail.uploaded.noresults": "Cet utilisateur n'a pas encore publié de chansons.",
......@@ -40,7 +38,6 @@
"settings.general.update.button": "Vérifier les mises à jours",
"settings.language.header": "Langue",
"settings.language.selectLanguage.label": "Changer la langue",
"settings.language.translatedBy": "Traduction par Frog King",
"settings.directories.header": "Répertoire",
"settings.directories.gameDirectory.label": "Répertoire du Jeu",
"settings.directories.gameDirectory.changeButton": "Modifier",
......
{
"locale.translatedBy": "옮긴이: jongizombie",
"locale.dateFormat": "YYYY년 MM월 DD일",
"startup.tabs.frontpage": "Frontpage",
"startup.tabs.new": "New",
"startup.tabs.hot": "Hot",
......@@ -23,12 +26,7 @@
"library.deletemodal.close": "닫기",
"library.deletemodal.explorer": "Open in Explorer",
"songdetail.createdBy": "제작자 ",
"songdetail.actions.downloadButton": "다운로드",
"songdetail.actions.playPreviewButton": "미리보기 재생",
"songdetail.actions.stopPreviewButton": "미리보기 중지",
"songdetail.actions.copyLinkButton": "링크 복사",
"songdetail.actions.reportButton": "신고",
"songdetail.createdBy": "제작자 {charter}",
"userdetail.uploaded.header": "업로드된 곡",
"userdetail.uploaded.noresults": "이 사용자는 아직 곡을 업로드하지 않았습니다.",
......@@ -40,7 +38,6 @@
"settings.general.update.button": "업데이트 확인",
"settings.language.header": "언어",
"settings.language.selectLanguage.label": "언어 선택",
"settings.language.translatedBy": "옮긴이: jongizombie",
"settings.directories.header": "디렉터리",
"settings.directories.gameDirectory.label": "게임 디렉터리",
"settings.directories.gameDirectory.changeButton": "변경",
......
{
"locale.translatedBy": "Vertaling door Ellite",
"locale.dateFormat": "DD-MM-YYYY",
"startup.tabs.frontpage": "Frontpage",
"startup.tabs.new": "New",
"startup.tabs.hot": "Hot",
......@@ -23,12 +26,7 @@
"library.deletemodal.close": "Sluit",
"library.deletemodal.explorer": "Open in Explorer",
"songdetail.createdBy": "Gemaakt door ",
"songdetail.actions.downloadButton": "Download",
"songdetail.actions.playPreviewButton": "Speel Voorbeeld",
"songdetail.actions.stopPreviewButton": "Stop Voorbeeld",
"songdetail.actions.copyLinkButton": "Kopieer Link",
"songdetail.actions.reportButton": "Rapporteren",
"songdetail.createdBy": "Gemaakt door {charter}",
"userdetail.uploaded.header": "Geüploade nummers",
"userdetail.uploaded.noresults": "Deze gebruiker heeft nog geen nummers geüpload.",
......@@ -40,7 +38,6 @@
"settings.general.update.button": "Check voor Updates",
"settings.language.header": "Taal",
"settings.language.selectLanguage.label": "Selecteer Taal",
"settings.language.translatedBy": "Vertaling door Ellite",
"settings.directories.header": "Mappen",
"settings.directories.gameDirectory.label": "Game Directory",
"settings.directories.gameDirectory.changeButton": "Wijzig",
......
{
"locale.translatedBy": "Tłumaczenie autorstwa _λmbινα|eηce",
"locale.dateFormat": "YYYY-MM-DD",
"startup.tabs.frontpage": "Frontpage",
"startup.tabs.new": "New",
"startup.tabs.hot": "Hot",
......@@ -23,12 +26,7 @@
"library.deletemodal.close": "Zamknij",
"library.deletemodal.explorer": "Open in Explorer",
"songdetail.createdBy": "Autorstwa ",
"songdetail.actions.downloadButton": "Pobierz",
"songdetail.actions.playPreviewButton": "Pokaż Podgląd",
"songdetail.actions.stopPreviewButton": "Zatrzymaj Podgląd",
"songdetail.actions.copyLinkButton": "Kopiuj Link",
"songdetail.actions.reportButton": "Zgłoś",
"songdetail.createdBy": "Autorstwa {charter}",
"userdetail.uploaded.header": "Przesłane Utwory",
"userdetail.uploaded.noresults": "Ten użytkownik nie przesłał jeszcze żadnych utworów.",
......@@ -40,7 +38,6 @@
"settings.general.update.button": "Sprawdź Aktualizacje",
"settings.language.header": "Język",
"settings.language.selectLanguage.label": "Wybierz Język",
"settings.language.translatedBy": "Tłumaczenie autorstwa _λmbινα|eηce",
"settings.directories.header": "Katalog",
"settings.directories.gameDirectory.label": "Katalog Gry",
"settings.directories.gameDirectory.changeButton": "Zmień",
......
{
"locale.translatedBy": "Tradução por Tonuha",
"locale.dateFormat": "DD/MM/YYYY",
"startup.tabs.frontpage": "Frontpage",
"startup.tabs.new": "New",
"startup.tabs.hot": "Hot",
......@@ -23,12 +26,7 @@
"library.deletemodal.close": "Fechar",
"library.deletemodal.explorer": "Open in Explorer",
"songdetail.createdBy": "Criado por",
"songdetail.actions.downloadButton": "Baixar",
"songdetail.actions.playPreviewButton": "Ouvir Um Trecho",
"songdetail.actions.stopPreviewButton": "Parar Reprodução",
"songdetail.actions.copyLinkButton": "Copiar Link",
"songdetail.actions.reportButton": "Reportar",
"songdetail.createdBy": "Criado por {charter}",
"userdetail.uploaded.header": "Músicas Postadas",
"userdetail.uploaded.noresults": "Este usuário ainda não postou nenhuma música.",
......@@ -40,7 +38,6 @@
"settings.general.update.button": "Buscar Atualizações",
"settings.language.header": "Idioma",
"settings.language.selectLanguage.label": "Selecionar Idioma",
"settings.language.translatedBy": "Tradução por Tonuha",
"settings.directories.header": "Diretórios",
"settings.directories.gameDirectory.label": "Diretório do Jogo",
"settings.directories.gameDirectory.changeButton": "Mudar",
......
{
"locale.translatedBy": "Переведено D-Core",
"locale.dateFormat": "DD.MM.YYYY",
"startup.tabs.frontpage": "Frontpage",
"startup.tabs.new": "New",
"startup.tabs.hot": "Hot",
......@@ -23,12 +26,7 @@
"library.deletemodal.close": "Закрыть",
"library.deletemodal.explorer": "Open in Explorer",
"songdetail.createdBy": "Автор ",
"songdetail.actions.downloadButton": "Скачать",
"songdetail.actions.playPreviewButton": "Предпросмотр",
"songdetail.actions.stopPreviewButton": "Остановить предпросмотр",
"songdetail.actions.copyLinkButton": "Копировать ссылку",
"songdetail.actions.reportButton": "Пожаловаться",
"songdetail.createdBy": "Автор {charter}",
"userdetail.uploaded.header": "Загруженные песни",
"userdetail.uploaded.noresults": "Этот пользователь ещё не загрузил ни одной песни.",
......@@ -40,7 +38,6 @@
"settings.general.update.button": "Проверить обновления",
"settings.language.header": "Язык",
"settings.language.selectLanguage.label": "Выберите язык",
"settings.language.translatedBy": "Переведено D-Core",
"settings.directories.header": "Пути",
"settings.directories.gameDirectory.label": "Путь игры",
"settings.directories.gameDirectory.changeButton": "Изменить",
......
{
"locale.translatedBy": "SPEEN SPEEN SPEEN",
"locale.dateFormat": "SPEEN/SPEEN/SPEEN",
"startup.tabs.frontpage": "SPEEN",
"startup.tabs.new": "SPEEN",
"startup.tabs.hot": "SPEEN",
......@@ -23,12 +26,7 @@
"library.installed.install.text": "SPEEN",
"library.contextmenu.delete": "SPEEN",
"songdetail.createdBy": "SPEEN ",
"songdetail.actions.downloadButton": "SPEEN",
"songdetail.actions.playPreviewButton": "SPEEN",
"songdetail.actions.stopPreviewButton": "SPEEN",
"songdetail.actions.copyLinkButton": "SPEEN",
"songdetail.actions.reportButton": "SPEEN",
"songdetail.createdBy": "SPEEN {charter}",
"userdetail.uploaded.header": "SPEEN",
"userdetail.uploaded.noresults": "SPEEN",
......@@ -40,7 +38,6 @@
"settings.general.update.button": "SPEEN",
"settings.language.header": "SPEEN",
"settings.language.selectLanguage.label": "SPEEN",
"settings.language.translatedBy": "SPEEN SPEEN SPEEN",
"settings.directories.header": "SPEEN",
"settings.directories.gameDirectory.label": "SPEEN",
"settings.directories.gameDirectory.changeButton": "SPEEN",
......
{
"locale.translatedBy": "翻译者:AyanAmy.jy1263",
"locale.dateFormat": "YYYY年MM月DD日",
"startup.tabs.frontpage": "Frontpage",
"startup.tabs.new": "New",
"startup.tabs.hot": "Hot",
......@@ -23,12 +26,7 @@
"library.deletemodal.close": "关闭",
"library.deletemodal.explorer": "Open in Explorer",
"songdetail.createdBy": "创作家 ",
"songdetail.actions.downloadButton": "下载",
"songdetail.actions.playPreviewButton": "预览歌曲",
"songdetail.actions.stopPreviewButton": "暂停预览",
"songdetail.actions.copyLinkButton": "复制链接",
"songdetail.actions.reportButton": "提交报告",
"songdetail.createdBy": "创作家 {charter}",
"userdetail.uploaded.header": "以上传的音乐",
"userdetail.uploaded.noresults": "这用户还没有上传任何音乐。",
......@@ -40,7 +38,6 @@
"settings.general.update.button": "检查更新",
"settings.language.header": "语言",
"settings.language.selectLanguage.label": "选择语言",
"settings.language.translatedBy": "翻译者:AyanAmy.jy1263",
"settings.directories.header": "目录",
"settings.directories.gameDirectory.label": "游戏安装目录",
"settings.directories.gameDirectory.changeButton": "改变",
......
......@@ -3,10 +3,17 @@ import App from './App.vue';
import router from './router';
import store from './store';
import i18n from './i18n';
import moment from 'moment'
import { ipcRenderer } from 'electron';
Vue.config.productionTip = false;
Vue.filter('formatDate', function(value) {
if (value) {
return moment(String(value)).format(i18n.t('locale.dateFormat'))
}
});
window.VueRoot = new Vue({
router,
store,
......
......@@ -2,7 +2,6 @@ const glob = require('glob');
const fs = require('fs');
const path = require('path');
const rimraf = require('rimraf');
const unzipper = require('unzipper');
const ncp = require('ncp');
const admzip = require('adm-zip');
const uniqid = require('uniqid');
......
......@@ -10,6 +10,8 @@ import ViewStartupPopularSongs from '../views/StartupPopularSongs.vue';
import ViewSearch from '../views/Search.vue';
import ViewLibrary from '../views/Library.vue';
import ViewSongDetail from '../views/SongDetail.vue';
import ViewSongDetailReviews from '../views/SongDetailReviews.vue';
import ViewSongDetailSpinPlays from '../views/SongDetailSpinPlays.vue';
import ViewUserDetail from '../views/UserDetail.vue';
import ViewSettings from '../views/Settings.vue';
......@@ -22,7 +24,7 @@ const routes = [{
component: ViewStartup,
children: [
{
path: '/',
path: '',
name: 'Frontpage',
component: ViewStartupFrontpage
},
......@@ -53,7 +55,23 @@ const routes = [{
}, {
path: '/song/:id',
name: 'SongDetail',
component: ViewSongDetail
component: ViewSongDetail,
redirect: {
name: 'SongDetailReviews'
},
children: [
{
alias: '',
path: 'reviews',
name: 'SongDetailReviews',
component: ViewSongDetailReviews
},
{
path: 'spinplays',
name: 'SongDetailSpinPlays',
component: ViewSongDetailSpinPlays
}
]
},, {
path: '/user/:id',
name: 'UserDetail',
......
......@@ -34,7 +34,7 @@
<option value="speen">Speen (Speen)</option>
</select>
</div>
<div class="settings-hint">{{ $t('settings.language.translatedBy') }}</div>
<div class="settings-hint">{{ $t('locale.translatedBy') }}</div>
</div>
</div>
<div class="settings-box">
......
<template>
<div class="tab tab-reviews">
<div class="review-overview" v-if="apiFinished">
<div class="icon">
<i class="mdi mdi-thumbs-up-down"></i>
</div>
<div class="text" v-if="reviewAverage == false">
<div class="percentage">???%</div>
<div class="label">{{ $t('songdetail.reviews.recommended.label') }}</div>
<div class="disclaimer">{{ $t('songdetail.reviews.recommended.notenough') }}</div>
</div>
<div class="text" v-if="reviewAverage != false">
<div class="percentage">{{ reviewAverage }}%</div>
<div class="label">{{ $t('songdetail.reviews.recommended.label') }}</div>
<div class="disclaimer">{{ $t('songdetail.reviews.recommended.basedon', {amountOfReviews: reviews.length}) }}</div>
</div>
<div v-on:click="OpenAddReview()" class="action-button">{{ $t('songdetail.reviews.recommended.addReview') }}</div>
</div>
<div class="reviews" v-if="apiFinished && reviews.length > 0">
<SongReview
v-for="review in reviews"
v-bind:key="review.id"
v-bind="review" />
</div>
<div class="no-reviews" v-if="apiFinished && reviews.length == 0">
<div class="icon">
<i class="mdi mdi-comment-question"></i>
</div>
<div class="text">
<div class="title">{{ $t('songdetail.reviews.noresults.title') }}</div>
<div class="explaination">{{ $t('songdetail.reviews.noresults.explaination') }}</div>
</div>
</div>
</div>
</template>
<script>
import { remote } from 'electron';
const { clipboard, shell } = remote;
import SSAPI from '@/modules/module.api.js';
import SongReview from '@/components/Song/SongReview.vue';
export default {
name: 'SongDetailReviews',
data: function() {
return {
apiFinished: false,
reviewAverage: 0,
reviews: []
}
},
mounted: function() {
let ssapi = new SSAPI(process.env.NODE_ENV === 'development');
ssapi.getSongDetailReviews(this.$route.params.id).then((data) => {
this.$data.apiFinished = true;
this.$data.reviewAverage = data.data.average;
this.$data.reviews = data.data.reviews ? data.data.reviews : [];
});
},
components: {
SongReview
},
methods: {
OpenAddReview: function() {
shell.openExternal("https://spinsha.re/song/" + this.$route.params.id + "?tab=reviews");
},
}
}
</script>
<style scoped lang="less">
.tab-reviews {
& .review-overview {
background: rgba(255,255,255,0.1);
border-radius: 4px;
padding: 20px 30px;
display: grid;
grid-template-columns: auto 1fr auto;
grid-gap: 25px;
align-items: center;
& .icon {
color: #fff;
font-size: 48px;
}
& .text {
& .percentage {
font-size: 32px;
}
& .label {
font-size: 12px;
font-weight: bold;
text-transform: uppercase;
letter-spacing: 0.05em;
margin-bottom: 5px;
}
& .disclaimer {
opacity: 0.6;
}
}
& .action-button {
text-decoration: none;
color: #fff;
font-size: 12px;
font-weight: bold;
letter-spacing: 0.1em;
background: linear-gradient(135deg, rgba(255,255,255,0.3), rgba(255,255,255,0.1));
padding: 10px 20px;
border-radius: 4px;
text-transform: uppercase;
transition: 0.2s ease-in-out all;
cursor: pointer;
&:hover {
opacity: 0.6;
}
}
}
& .reviews {
display: grid;
grid-gap: 10px;
}
& .no-reviews {
background: rgba(255,255,255,0.1);
border-radius: 4px;
padding: 20px 30px;
display: grid;
grid-template-columns: auto 1fr;
grid-gap: 25px;
align-items: center;
& .icon {
color: #fff;
font-size: 48px;
}
& .text {
& .title {
font-size: 12px;
font-weight: bold;
letter-spacing: 0.05em;
margin-bottom: 5px;
text-transform: uppercase;
}
& .explaination {
opacity: 0.6;
}
}
}
}
</style>
\ No newline at end of file
<template>
<div class="tab tab-spinplays">
<div class="spinplay-overview" v-if="apiFinished">
<div class="icon">
<i class="mdi mdi-youtube"></i>
</div>
<div class="text">
<div class="label">{{ $t('songdetail.spinplays.add.label') }}</div>
<div class="disclaimer">{{ $t('songdetail.spinplays.add.text') }}</div>
</div>
<div v-on:click="OpenSubmitVideo()" class="action-button">{{ $t('songdetail.spinplays.add.submitVideo') }}</div>
</div>
<div class="spinplays" v-if="apiFinished && spinPlays.length > 0">
<SongSpinPlay
v-for="spinPlay in spinPlays"
v-bind:key="spinPlay.id"
v-bind="spinPlay" />
</div>
<div class="no-spinplays" v-if="apiFinished && spinPlays.length == 0">
<div class="icon">
<i class="mdi mdi-youtube"></i>
</div>
<div class="text">
<div class="title">{{ $t('songdetail.spinplays.noresults.title') }}</div>
<div class="explaination">{{ $t('songdetail.spinplays.noresults.explaination') }}</div>
</div>
</div>
</div>
</template>
<script>
import { remote } from 'electron';
const { clipboard, shell } = remote;
import SSAPI from '@/modules/module.api.js';
import SongSpinPlay from '@/components/Song/SongSpinPlay.vue';
export default {
name: 'SongDetailSpinPlays',
data: function() {
return {
apiFinished: false,
spinPlays: []
}
},
mounted: function() {
let ssapi = new SSAPI(process.env.NODE_ENV === 'development');
ssapi.getSongDetailSpinPlays(this.$route.params.id).then((data) => {
this.$data.apiFinished = true;
this.$data.spinPlays = data.data.spinPlays ? data.data.spinPlays : [];
});
},
components: {
SongSpinPlay
},
methods: {
OpenSubmitVideo: function() {
shell.openExternal("https://spinsha.re/song/" + this.$route.params.id + "?tab=spinplays");
},
}
}
</script>
<style scoped lang="less">
.tab-spinplays {
& .spinplay-overview {
background: rgba(255,255,255,0.1);
border-radius: 4px;
padding: 20px 30px;
display: grid;
grid-template-columns: auto 1fr auto;
grid-gap: 25px;
align-items: center;
& .icon {
color: #fff;
font-size: 48px;
}
& .text {
& .label {
font-size: 12px;
font-weight: bold;
letter-spacing: 0.05em;
margin-bottom: 5px;
text-transform: uppercase;
}
& .disclaimer {
opacity: 0.6;
}
}
& .action-button {
text-decoration: none;
color: #fff;
font-size: 12px;
font-weight: bold;
letter-spacing: 0.1em;
background: linear-gradient(135deg, rgba(255,255,255,0.3), rgba(255,255,255,0.1));
padding: 10px 20px;
border-radius: 4px;
text-transform: uppercase;
transition: 0.2s ease-in-out all;
cursor: pointer;
&:hover {
opacity: 0.6;
}
}
}
& .spinplays {
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 15px;
}
& .no-spinplays {
background: rgba(255,255,255,0.1);
border-radius: 4px;
padding: 20px 30px;
display: grid;
grid-template-columns: auto 1fr;
grid-gap: 25px;
align-items: center;
& .icon {
color: #fff;
font-size: 48px;
}
& .text {
& .title {
font-size: 12px;
font-weight: bold;
letter-spacing: 0.05em;
margin-bottom: 5px;
text-transform: uppercase;
}
& .explaination {
opacity: 0.6;
}
}
}
}
</style>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment