Add vue cli

This commit is contained in:
Chocobozzz 2019-09-11 13:52:20 +02:00
parent 222568cfb1
commit f62b724751
No known key found for this signature in database
GPG key ID: 583A612D890159BE
64 changed files with 1882 additions and 1400 deletions

2
.browserslistrc Normal file
View file

@ -0,0 +1,2 @@
> 1%
last 2 versions

5
.editorconfig Normal file
View file

@ -0,0 +1,5 @@
[*.{js,jsx,ts,tsx,vue}]
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
insert_final_newline = true

17
.eslintrc.js Normal file
View file

@ -0,0 +1,17 @@
module.exports = {
root: true,
env: {
node: true
},
'extends': [
'plugin:vue/essential',
'@vue/standard'
],
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
},
parserOptions: {
parser: 'babel-eslint'
}
}

26
.gitignore vendored
View file

@ -1,5 +1,21 @@
node_modules/ .DS_Store
public/ node_modules
.zanata-cache/etag-cache.xml /dist
npm-debug.log
/zanata.xml # local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

View file

@ -1,241 +0,0 @@
meta:
title: Join PeerTube
author: Framasoft
canonical: https://joinpeertube.org
i18n: https://trad.framasoft.org/project/view/join-peertube/master
txt:
# soft: text from color.soft
html:
# soft: <a href="link.soft">color.soft</a>
color:
soft: <b class="violet">Frama</b><b class="orange">soft</b>
cuo: <b class="violet">Contributopia</b>
evl: <b class="violet" lang="fr">EnVente</b><b class="jaune" lang="fr">Libre</b>
agenda: <b class="violet">Fram</b><b class="vert">agenda</b>
bag: <b class="violet">Frama</b><b class="vert">bag</b>
bee: <b class="violet">Frama</b><b class="vert" lang="en">bee</b>
bin: <b class="violet">Frama</b><b class="vert" lang="en">bin</b>
blog: <b class="violet">Frama</b><b class="rouge">blog</b>
board: <b class="violet">Frama</b><b class="vert" lang="en">board</b>
book: <b class="violet">Frama</b><b class="rouge" lang="en">book</b>
bookin: <b class="violet">Frama</b><b class="rouge" lang="en">bookin</b>
calc: <b class="violet">Frama</b><b class="vert">calc</b>
carte: <b class="violet">Frama</b><b class="vert">carte</b>
cloud: <b class="violet">Frama</b><b class="vert" lang="en">cloud</b>
colibri: <b class="violet">Frama</b><b class="jaune" lang="fr">colibri</b>
date: <b class="violet">Frama</b><b class="vert">date</b>
docs: <b class="violet">Frama</b><b class="jaune">docs</b>
drive: <b class="violet">Frama</b><b class="vert" lang="en">drive</b>
drop: <b class="violet">Frama</b><b class="vert">drop</b>
dvd: <b class="violet">Frama</b><b class="bleu"><abbr>dvd</abbr></b>
forms: <b class="violet">Frama</b><b class="vert">forms</b>
games: <b class="violet">Frama</b><b class="vert" lang="en">games</b>
git: <b class="violet">Frama</b><b class="vert" lang="en">git</b>
key: <b class="violet">Frama</b><b class="bleu" lang="en">key</b>
lab: <b class="violet">Frama</b><b class="jaune">lab</b>
lang: <b class="violet">Frama</b><b class="rouge" lang="en">lang</b>
libre: <b class="violet">Frama</b><b class="bleu" lang="fr">libre</b>
link: <b class="violet">Frama</b><b class="vert" lang="en">link</b>
listes: <b class="violet">Frama</b><b class="vert" lang="fr">listes</b>
maestro: <b class="violet">Fra</b><b class="vert" lang="it">maestro</b>
memo: <b class="violet">Fra</b><b class="vert" lang="fr">memo</b>
mindmap: <b class="violet">Fra</b><b class="vert" lang="en">mindmap</b>
minetest: <b class="violet">Fra</b><b class="vert" lang="en">minetest</b>
my: <b class="violet" lang="en">My</b><b class="vert">Frama</b>
news: <b class="violet">Frama</b><b class="vert" lang="en">news</b>
notes: <b class="violet">Frama</b><b class="vert">notes</b>
pack: <b class="violet">Frama</b><b class="bleu">pack</b>
pad: <b class="violet">Frama</b><b class="vert">pad</b>
piaf: <b class="violet">Frama</b><b class="vert">piaf</b>
pic: <b class="violet">Frama</b><b class="vert">pic</b>
site: <b class="violet">Frama</b><b class="vert">site</b>
slides: <b class="violet">Frama</b><b class="vert" lang="en">slides</b>
sphere: <b class="violet">Frama</b><b class="vert" lang="fr">sphère</b>
team: <b class="violet">Frama</b><b class="vert" lang="en">team</b>
talk: <b class="violet">Frama</b><b class="vert" lang="en">talk</b>
tube: <b class="violet">Frama</b><b class="rouge">tube</b>
vectoriel: <b class="violet">Frama</b><b class="vert" lang="fr">vectoriel</b>
vox: <b class="violet">Frama</b><b class="vert">vox</b>
wiki: <b class="violet">Frama</b><b class="vert">wiki</b>
zic: <b class="violet">Frama</b><b class="rouge">zic</b>
huitre: <b class="violet" lang="fr">Huit</b><b class="vert">re</b>
tontonroger: <b class="violet" lang="fr">Tonton</b> <b class="vert">Roger</b>
trouvons: <b class="violet" lang="fr">Trouvons</b><b class="vert">.org</b>
link:
gitPT: https://github.com/Chocobozzz/PeerTube
instancesPT: https://instances.joinpeertube.org
docsPT: https://docs.joinpeertube.org
mastodon: https://joinmastodon.org
activitypub: https://activitypub.rocks
tosdr: https://tosdr.org/#youtube
soft: https://framasoft.org
dio: https://degooglisons-internet.org
cuo: https://contributopia.org
soutenir: https://soutenir.framasoft.org
contact: https://contact.framasoft.org
newsletter: https://contact.framasoft.org/newsletter
participer: https://participer.framasoft.org
evl: https://enventelibre.org
wikifs: https://wiki.framasoft.org
press: https://wiki.framasoft.org/speakabout
agenda: https://framagenda.org
bag: https://framabag.org
bee: https://framabee.org
bin: https://framabin.org
blog: https://framablog.org
board: https://framaboard.org
book: https://framabook.org
bookin: https://framabookin.org
calc: https://framacalc.org
carte: https://framacarte.org
cloud: https://framacloud.org
colibri: https://framacolibri.org
date: https://framadate.org
docs: https://docs.framasoft.org
drive: https://framadrive.org
drop: https://framadrop.org
dvd: https://framadvd.org
forms: https://framaforms.org
games: https://framagames.org
git: https://framagit.org
key: https://framakey.org
lab: https://framalab.org
lang: https://participer.framasoft.org/traduction-rejoignez-framalang/
libre: https://framalibre.org
link: https://frama.link
listes: https://framalistes.org
maestro: https://framaestro.org
memo: https://framemo.org
mindmap: https://framindmap.org
minetest: https://framinetest.org
my: https://my.framasoft.org
news: https://framanews.org
notes: https://framanotes.org
pack: https://framapack.org
pad: https://framapad.org
piaf: https://framapiaf.org
pic: https://framapic.org
site: https://frama.site
slides: https://framaslides.org
sphere: https://framasphere.org
talk: https://framatalk.org
team: https://framateam.org
tube: https://framatube.org
vectoriel: https://framavectoriel.org
vox: https://framavox.org
wiki: https://frama.wiki
zic: https://framazic.org
huitre: https://huit.re
tontonroger: https://tontonroger.org
trouvons: https://trouvons.org
icon:
dio: fa-shield
cuo: fa-shield
soutenir: fa-heart
contact: fa-envelop
participer: fa-paw
evl: fa-shopping-cart
agenda: fa-calendar
bag: fa-briefcase
bee: fa-search
bin: fa-paste
blog: fa-pencil
board: fa-dashboard
book: fa-book
bookin: fa-coffee
calc: fa-th
carte: fa-map
colibri: fa-comment
date: fa-calendar-check-o
docs: fa-graduation-cap
drive: fa-cloud-upload
drop: fa-send
dvd: fa-play-circle-o
forms: fa-list-ul
games: fa-gamepad
git: fa-git
key: fa-usb
lab: fa-flask
lang: fa-language
libre: fa-linux
link: fa-link
listes: fa-group
maestro: fa-magic
memo: fa-object-group
mindmap: fa-sitemap
minetest: fa-cube
my: fa-star
news: fa-newspaper-o
notes: fa-sticky-note
pack: fa-download
pad: fa-align-left
piaf: fa-mastodon
pic: fa-photo
site: fa-globe
slides: fa-pie-chart
sphere: fa-diaspora
talk: fa-video-camera
team: fa-comments-o
tube: fa-film
vectoriel: fa-paint-brush
vox: fa-bullhorn
wiki: fa-puzzle-piece
zic: fa-music
huitre: fa-link
tontonroger: fa-search
trouvons: fa-search
license:
lal: <a href="http://artlibre.org">Art Libre</a>
cc0: <a href="https://creativecommons.org/publicdomain/zero/1.0">Creative Commons 0</a>
ccby3: <a href="https://creativecommons.org/licenses/by/3.0"><span lang="en">Creative Commons By</span> 3.0</a>
ccby4: <a href="https://creativecommons.org/licenses/by/4.0"><span lang="en">Creative Commons By</span> 4.0</a>
ccbysa3: <a href="https://creativecommons.org/licenses/by-sa/3.0"><span lang="en">Creative Commons By</span>-<abbr>SA</abbr> 3.0</a>
ccbysa4: <a href="https://creativecommons.org/licenses/by-sa/4.0"><span lang="en">Creative Commons By</span>-<abbr>SA</abbr> 4.0</a>
ccbysa2fr: <a href="https://creativecommons.org/licenses/by-sa/2.0/fr"><span lang="en">Creative Commons By</span>-<abbr>SA</abbr> 2.0</a>
ccbysa3fr: <a href="https://creativecommons.org/licenses/by-sa/3.0/fr"><span lang="en">Creative Commons By</span>-<abbr>SA</abbr> 3.0</a>
ccbysa4fr: <a href="https://creativecommons.org/licenses/by-sa/4.0/deed.fr"><span lang="en">Creative Commons By</span>-<abbr>SA</abbr> 4.0</a>
gpl2: <a href="https://www.gnu.org/licenses/gpl-2.0.html">GNU <abbr lang="en" title="General Public License">GPL</abbr> v2</a>
gpl3: <a href="https://www.gnu.org/licenses/gpl-3.0.txt">GNU <abbr lang="en" title="General Public License">GPL</abbr> v3</a>
gnufdl: <a href="https://www.gnu.org/copyleft/fdl.html">GNU <abbr lang="en" title="Free Documentation License">FDL</abbr></a>
agpl3: <a href="https://www.gnu.org/licenses/agpl-3.0.html">GNU <abbr lang="en" title="Affero General Public License">AGPL</abbr> v3</a>
apache2: <a href="http://www.apache.org/licenses/LICENSE-2.0.html">Apache 2.0</a>
cecillb: <a href="http://www.cecill.info/licences.fr.html">CeCILL-B</a>
people:
aka: Alexis Kauffmann
ben: Benjamin Jean
christophe: Christophe Masutti
cyrille: Cyrille Largillier
dorme: Geoffrey Dorme
fat115: fat115
fla: Flaburgan
fred: Fredéric Urbain
gab: Gabriel Dejeante
gee: Simon «Gee» Giraudot
jo: JosephK
kinou: Christelle Thomas
lam: Lamessen
lldemars: L.L. de Mars
luc: Luc Didry
martin: Martin Gubri
sandra: peupleLà (Sandra Guigonis)
simonl: Simon Leblanc
pouhiou: Pouhiou
pyg: Pierre-Yves Gosset
tcit: Thomas Citharel
emoji:
wink: 😉

View file

@ -1,202 +0,0 @@
import Vue from 'vue';
import VueMatomo from 'vue-matomo';
import VueRouter from 'vue-router';
import VueI18n from 'vue-i18n';
import vueHeadful from 'vue-headful';
import App from './App.vue';
import Home from './views/Home.vue';
import './assets/scss/bootstrap.scss';
import '../node_modules/fork-awesome/css/fork-awesome.css';
import './assets/scss/main.scss';
Vue.use(VueRouter);
Vue.use(VueI18n);
Vue.component('vue-headful', vueHeadful);
const defaultLocale = 'fr';
const locales = [];
const pages = [];
// Import locales list
let req = require.context('./locales/', false, /\.yml$/);
req.keys().forEach((key) => {
locales.push(key.replace(/\.\/(.*)\.yml/, '$1'));
});
// Import pages list
req = require.context('./views', false, /\.vue$/);
req.keys().forEach((key) => {
pages.push(key.replace(/\.\/(.*)\.vue/, '$1'));
});
const lang = window.location.href
.split('/')[(process.env.BASE_URL === '' || (window.location.href.match(/\//g)).length === 3) ? 3 : 4]
.substr(0, 2)
.toLowerCase() || defaultLocale;
document.getElementsByTagName('html')[0].setAttribute('lang', lang);
const userLang = navigator.languages
|| [navigator.language || navigator.userLanguage];
let defaultRouteLang = '';
const messages = {};
messages.locales = require('./lang.yml'); // eslint-disable-line
messages.locales.avalaible = Object.keys(messages.locales).filter(n => locales.indexOf(n) > -1);
// Data import
let data = {};
data = require('./data.yml'); // eslint-disable-line
data['/'] = `/${process.env.BASE_URL.replace(/(.+)/, '$1/')}`;
data.hash = window.location.hash.replace('#', '');
data.txt = data.txt || {};
data.html = data.html || {};
Object.keys(data.color).forEach((k) => {
if (data.txt[k] === undefined) {
const tmp = document.createElement('div');
tmp.innerHTML = data.color[k];
data.txt[k] = tmp.textContent || tmp.innerText;
}
});
Object.keys(data.link).forEach((k) => {
if (data.html[k] === undefined) {
if (data.color[k] !== undefined) {
data.html[k] = `<a href="${data.link[k]}">${data.color[k]}</a>`;
} else if (data.txt[k] !== undefined) {
data.html[k] = `<a href="${data.link[k]}">${data.txt[k]}</a>`;
}
}
});
const routes = [
{ path: '/', component: Home, meta: { id: 'home', lang: defaultLocale } },
];
for (let i = 0; i < locales.length; i += 1) {
messages[locales[i]] = {};
// Locales import
/* eslint-disable */
import(/* webpackChunkName: "lang-[request]" */`./locales/${locales[i]}.yml`).then((locale) => {
messages[locales[i]] = locale;
messages[locales[i]].data = data;
messages[locales[i]].lang = locales[i];
}).catch((err) => {
console.error(err);
});
/* eslint-enable */
// Localized routes
for (let j = 0; j < pages.length; j += 1) {
const component = require(`./views/${pages[j]}.vue`); // eslint-disable-line
routes.push({
path: `/${locales[i]}${pages[j].toLowerCase().replace(/^/, '/').replace('/home', '')}`,
component: component.default,
meta: { id: pages[j].toLowerCase(), lang: locales[i] },
});
}
}
// define defaultRouteLang
for (let j = 0; j < userLang.length; j += 1) { // check if user locales
for (let i = 0; i < locales.length; i += 1) { // matches with app locales
if (defaultRouteLang === '' && userLang[j].substring(0, 2).toLowerCase() === locales[i]) {
defaultRouteLang = locales[i];
}
}
}
// Home redirection
const currentURL = window.location.href.replace(/\/+$/, '');
if ((currentURL.split('/')[3] === undefined || currentURL.split('/')[3] === process.env.BASE_URL)
&& (currentURL.split('/')[4] === undefined)) {
if (defaultRouteLang === '') {
defaultRouteLang = defaultLocale;
}
window.location.href = `${currentURL}/${defaultRouteLang}/`;
}
// Create VueI18n instance with options
const i18n = new VueI18n({
locale: lang,
fallbackLocale: defaultLocale,
messages,
silentTranslationWarn: true,
});
// Framanav
if (!window.vuefsPrerender
&& document.querySelectorAll('script[src$="nav.js"]').length < 1
&& process.env.NODE_ENV !== 'development') {
const navConfig = document.createElement('script');
navConfig.innerHTML = 'l$ = { js: { j$: \'noConflict\' } }';
document.getElementsByTagName('head')[0].appendChild(navConfig);
const nav = document.createElement('script');
nav.src = 'https://framasoft.org/nav/nav.js';
// document.getElementsByTagName('head')[0].appendChild(nav);
}
// Routes
const router = new VueRouter({
routes,
mode: 'history',
base: `${__dirname}${process.env.BASE_URL}`,
});
// Stats Matomo
if (!(navigator.doNotTrack === 'yes'
|| navigator.doNotTrack === '1'
|| navigator.msDoNotTrack === '1'
|| window.doNotTrack === '1')
) {
Vue.use(VueMatomo, {
// Configure your matomo server and site
host: 'https://stats.framasoft.org/',
siteId: 68,
// Enables automatically registering pageviews on the router
router,
// Require consent before sending tracking information to matomo
// Default: false
requireConsent: false,
// Whether to track the initial page view
// Default: true
trackInitialView: true,
// Changes the default .js and .php endpoint's filename
// Default: 'piwik'
trackerFileName: 'p',
enableLinkTracking: true,
});
const _paq = _paq || []; // eslint-disable-line
// Conformité CNIL
_paq.push([function piwikCNIL() {
const self = this;
function getOriginalVisitorCookieTimeout() {
const now = new Date();
const nowTs = Math.round(now.getTime() / 1000);
const visitorInfo = self.getVisitorInfo();
const createTs = parseInt(visitorInfo[2], 10);
const cookieTimeout = 33696000; // 13 mois en secondes
const originalTimeout = (createTs + cookieTimeout) - nowTs;
return originalTimeout;
}
this.setVisitorCookieTimeout(getOriginalVisitorCookieTimeout());
}]);
}
new Vue({ // eslint-disable-line no-new
el: '#app',
router,
i18n,
data,
mounted() {
// You'll need this for renderAfterDocumentEvent.
document.dispatchEvent(new Event('render-event'));
},
render: h => h(App),
});

5
babel.config.js Normal file
View file

@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/app'
]
}

View file

@ -1,61 +1,33 @@
{ {
"name": "joinpeertube", "name": "joinpeertube",
"description": "", "version": "0.1.0",
"version": "1.0.0",
"author": "JosephK",
"private": true, "private": true,
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1", "serve": "vue-cli-service serve",
"dev": "rm -rf ./public && cross-env NODE_ENV=development webpack-dev-server --open --hot --mode development", "build": "vue-cli-service build",
"preview": "rm -rf ./public && cross-env NODE_ENV=preview webpack --progress --hide-modules --mode production", "lint": "vue-cli-service lint"
"prod": "rm -rf ./public && cross-env NODE_ENV=production webpack --progress --hide-modules --mode production"
}, },
"dependencies": { "dependencies": {
"axios": "^0.18.0", "axios": "^0.19.0",
"bootstrap": "^4.3.1", "bootstrap": "^4.3.1",
"bootstrap-vue": "^2.0.0-rc.28", "bootstrap-vue": "^2.0.0",
"fork-awesome": "^1.1.5", "core-js": "^2.6.5",
"vue": "^2.5.16", "vue": "^2.6.10",
"vue-gettext": "^2.1.5",
"vue-headful": "^2.0.1", "vue-headful": "^2.0.1",
"vue-i18n": "^8.4.0", "vue-matomo": "^3.9.1-2",
"vue-matomo": "^0.3.2", "vue-router": "^3.1.3"
"vue-router": "^3.0.2"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.2.0", "@vue/cli-plugin-babel": "^3.11.0",
"@babel/plugin-proposal-object-rest-spread": "^7.2.0", "@vue/cli-plugin-eslint": "^3.11.0",
"@babel/plugin-syntax-dynamic-import": "^7.2.0", "@vue/cli-service": "^3.11.0",
"@babel/preset-env": "^7.2.0", "@vue/eslint-config-standard": "^4.0.0",
"autoprefixer": "^9.4.2",
"babel-eslint": "^10.0.1", "babel-eslint": "^10.0.1",
"babel-loader": "^8.0.4", "eslint": "^5.16.0",
"copy-webpack-plugin": "^4.6.0",
"cross-env": "^5.2.0",
"css-hot-loader": "^1.4.2",
"css-loader": "^1.0.1",
"eslint": "^5.9.0",
"eslint-config-airbnb-base": "^13.1.0",
"eslint-loader": "^2.1.1",
"eslint-plugin-filenames": "^1.3.2",
"eslint-plugin-html": "^5.0.0",
"eslint-plugin-import": "^2.14.0",
"eslint-plugin-promise": "^4.0.1",
"eslint-plugin-vue": "^5.0.0", "eslint-plugin-vue": "^5.0.0",
"file-loader": "^2.0.0", "node-sass": "^4.12.0",
"html-webpack-plugin": "^3.2.0", "sass-loader": "^8.0.0",
"mini-css-extract-plugin": "^0.4.5", "vue-template-compiler": "^2.6.10"
"node-sass": "^4.10.0",
"optimize-css-assets-webpack-plugin": "^5.0.1",
"postcss-loader": "^3.0.0",
"prerender-spa-plugin": "^3.4.0",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"terser-webpack-plugin": "^1.1.0",
"vue-loader": "^15.4.2",
"vue-template-compiler": "^2.5.16",
"webpack": "^4.27.1",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.10",
"yaml-import-loader": "^1.3.6"
} }
} }

View file

@ -1,5 +1,5 @@
module.exports = { module.exports = {
plugins: [ plugins: {
require("autoprefixer") autoprefixer: {}
] }
} }

View file

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View file

Before

Width:  |  Height:  |  Size: 746 B

After

Width:  |  Height:  |  Size: 746 B

View file

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

View file

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

View file

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View file

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

Before

Width:  |  Height:  |  Size: 107 KiB

After

Width:  |  Height:  |  Size: 107 KiB

View file

Before

Width:  |  Height:  |  Size: 156 KiB

After

Width:  |  Height:  |  Size: 156 KiB

View file

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 76 KiB

View file

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 55 KiB

View file

Before

Width:  |  Height:  |  Size: 441 KiB

After

Width:  |  Height:  |  Size: 441 KiB

View file

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 88 KiB

View file

Before

Width:  |  Height:  |  Size: 108 KiB

After

Width:  |  Height:  |  Size: 108 KiB

View file

Before

Width:  |  Height:  |  Size: 205 KiB

After

Width:  |  Height:  |  Size: 205 KiB

View file

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

View file

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 2 KiB

View file

@ -1,7 +1,7 @@
<template> <template>
<div id="app" class="container"> <div id="app" class="container">
<vue-headful <vue-headful
:title="$t('meta.title')" title="JoinPeerTube"
:html="{ body: {id: $route.meta.id } }" :html="{ body: {id: $route.meta.id } }"
:lang="$route.meta.lang" :lang="$route.meta.lang"
/> />
@ -21,12 +21,12 @@
</style> </style>
<script> <script>
import HeaderComponent from './components/Header.vue' import HeaderComponent from './components/Header.vue'
export default { export default {
name: 'app', name: 'app',
components: { components: {
HeaderComponent, HeaderComponent
},
} }
}
</script> </script>

View file

@ -43,11 +43,10 @@
</div> </div>
</div> </div>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
@import '../assets/scss/_variables'; @import '../scss/_variables';
.root { .root {
display: flex; display: flex;
@ -109,23 +108,23 @@
</style> </style>
<script> <script>
import IconVideo from './icons/IconVideo.vue' import IconVideo from './icons/IconVideo.vue'
import IconInstance from './icons/IconInstance.vue' import IconInstance from './icons/IconInstance.vue'
import IconChannel from './icons/IconChannel.vue' import IconChannel from './icons/IconChannel.vue'
export default { export default {
props: { props: {
type: String, type: String,
title: String, title: String,
thumbnailUrl: String, thumbnailUrl: String,
url: String, url: String,
tags: Array, tags: Array,
description: String, description: String
}, },
components: { components: {
IconVideo, IconVideo,
IconInstance, IconInstance,
IconChannel IconChannel
}
} }
}
</script> </script>

View file

@ -2,13 +2,12 @@
<header id="main-header"> <header id="main-header">
<nav class="navbar navbar-expand-lg"> <nav class="navbar navbar-expand-lg">
<router-link :to="'/' + $t('lang') + '/'" class="navbar-brand"> <router-link :to="getPath('/')" class="navbar-brand">
<img alt="PeerTube" :src="`${$root['/']}img/brand-small.png`"> <img alt="PeerTube" :src="`${$root['/']}img/brand-small.png`">
<div> <div>
soutenu par soutenu par
</div> </div>
</router-link> </router-link>
@ -22,15 +21,15 @@
<div id="navbar" class="collapse navbar-collapse"> <div id="navbar" class="collapse navbar-collapse">
<ul class="navbar-nav ml-auto"> <ul class="navbar-nav ml-auto">
<li class="nav-item"> <li class="nav-item">
<router-link class="nav-link" :to="'/' + $t('lang') + '/'">Home</router-link> <router-link class="nav-link" :to="getPath('/')">Home</router-link>
</li> </li>
<li class="nav-item "> <li class="nav-item ">
<router-link class="nav-link create-account" :to="'/' + $t('lang') + '/'">Create an account</router-link> <router-link class="nav-link create-account" :to="getPath('/')">Create an account</router-link>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<router-link class="nav-link" :to="'/' + $t('lang') + '/news'" v-html="$t('menu.faq')">News</router-link> <router-link class="nav-link" :to="getPath('/news')">News</router-link>
</li> </li>
<li class="nav-item"> <li class="nav-item">
@ -42,7 +41,7 @@
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" :href="$root.link.gitPT">Git</a> <a class="nav-link">Git</a>
</li> </li>
<div class="pull-right"> <div class="pull-right">
@ -55,7 +54,7 @@
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
@import '../assets/scss/_variables.scss'; @import '../scss/_variables.scss';
header { header {
margin-bottom: 30px; margin-bottom: 30px;
@ -88,12 +87,16 @@
</style> </style>
<script> <script>
import I18n from './I18n.vue' import I18n from './I18n.vue'
export default { export default {
components: { components: {
I18n, I18n
}, },
methods: {
getPath (path) {
return path
}
} }
}
</script> </script>

View file

@ -11,16 +11,16 @@
</template> </template>
<template slot="dropdown"> <template slot="dropdown">
<b-dropdown-item v-for="lang in locales.avalaible" @click="changeLanguage(lang)"> <b-dropdown-item v-for="lang in $language.availableLanguages" @click="changeLanguage(lang)">
<router-link :to="'/' + lang + '/' + ($route.path.split('/')[2] || '')">{{ locales[lang] }}</router-link> <router-link :to="'/' + lang + '/' + ($route.path.split('/')[2] || '')">{{ locales[lang] }}</router-link>
</b-dropdown-item> </b-dropdown-item>
<b-dropdown-divider v-if="$root.meta.i18n"></b-dropdown-divider> <b-dropdown-divider></b-dropdown-divider>
<b-dropdown-item v-if="$root.meta.i18n"> <b-dropdown-item>
<a :href="$root.meta.i18n"> <a>
<i class="fa fa-fw fa-plus" aria-hidden="true"></i> <i class="fa fa-fw fa-plus" aria-hidden="true"></i>
<span v-html="$t('nav.translate')"></span> <span v-translate>Translate</span>
</a> </a>
</b-dropdown-item> </b-dropdown-item>
</template> </template>
@ -50,25 +50,24 @@
</style> </style>
<script> <script>
import { BDropdown, BDropdownDivider, BDropdownItem } from 'bootstrap-vue' import { BDropdown, BDropdownDivider, BDropdownItem } from 'bootstrap-vue'
export default { export default {
components: { components: {
BDropdown, BDropdownDivider, BDropdownItem BDropdown, BDropdownDivider, BDropdownItem
}, },
data () { data () {
return { return {
currentComponent: '', currentComponent: '',
switchLanguage: 'en', switchLanguage: 'en'
locales: this.$i18n.messages.locales, }
} },
}, methods: {
methods: { changeLanguage (lang) {
changeLanguage (lang) { this.switchLanguage = lang
this.switchLanguage = lang this.$i18n.locale = lang
this.$i18n.locale = lang this.currentComponent = this.$route.path.split('/')[2] // eslint-disable-line prefer-destructuring
this.currentComponent = this.$route.path.split('/')[2] // eslint-disable-line prefer-destructuring }
},
},
} }
}
</script> </script>

View file

@ -36,7 +36,7 @@ import axios from 'axios'
export default { export default {
name: 'peertube-instances', name: 'peertube-instances',
data() { data () {
return { return {
error: false, error: false,
instances: [] instances: []
@ -70,7 +70,7 @@ export default {
return calc + format.type return calc + format.type
} }
}, },
mounted() { mounted () {
const options = { const options = {
method: 'GET', method: 'GET',
params: { params: {
@ -100,6 +100,4 @@ export default {
} }
} }
</script> </script>

View file

@ -7,6 +7,5 @@
</template> </template>
<script> <script>
export default {} export default {}
</script> </script>

View file

@ -10,6 +10,5 @@
</template> </template>
<script> <script>
export default {} export default {}
</script> </script>

View file

@ -11,6 +11,5 @@
</template> </template>
<script> <script>
export default {} export default {}
</script> </script>

View file

@ -11,6 +11,5 @@
</template> </template>
<script> <script>
export default {} export default {}
</script> </script>

5
src/data.yml Normal file
View file

@ -0,0 +1,5 @@
meta:
title: Join PeerTube
author: Framasoft
canonical: https://joinpeertube.org
i18n: https://trad.framasoft.org/project/view/join-peertube/master

99
src/main.js Normal file
View file

@ -0,0 +1,99 @@
import Vue from 'vue'
import VueMatomo from 'vue-matomo'
import VueRouter from 'vue-router'
import vueHeadful from 'vue-headful'
import GetTextPlugin from 'vue-gettext'
import App from './App.vue'
import Home from './views/Home.vue'
import './scss/bootstrap.scss'
import './scss/main.scss'
Vue.use(VueRouter)
Vue.use(GetTextPlugin, { translations: {} })
Vue.component('vue-headful', vueHeadful)
const router = new VueRouter({
mode: 'history',
base: `${__dirname}${process.env.BASE_URL}`,
routes: [
{
path: '/',
component: Home
}
]
})
// Framanav
if (
!window.vuefsPrerender &&
document.querySelectorAll('script[src$="nav.js"]').length < 1 &&
process.env.NODE_ENV !== 'development'
) {
const navConfig = document.createElement('script')
navConfig.innerHTML = 'l$ = { js: { j$: \'noConflict\' } }'
document.getElementsByTagName('head')[0].appendChild(navConfig)
const nav = document.createElement('script')
nav.src = 'https://framasoft.org/nav/nav.js'
// document.getElementsByTagName('head')[0].appendChild(nav);
}
// Stats Matomo
if (!(navigator.doNotTrack === 'yes' ||
navigator.doNotTrack === '1' ||
navigator.msDoNotTrack === '1' ||
window.doNotTrack === '1')
) {
Vue.use(VueMatomo, {
// Configure your matomo server and site
host: 'https://stats.framasoft.org/',
siteId: 68,
// Enables automatically registering pageviews on the router
router,
// Require consent before sending tracking information to matomo
// Default: false
requireConsent: false,
// Whether to track the initial page view
// Default: true
trackInitialView: true,
// Changes the default .js and .php endpoint's filename
// Default: 'piwik'
trackerFileName: 'p',
enableLinkTracking: true
})
const _paq = _paq || [] // eslint-disable-line
// CNIL conformity
_paq.push([function piwikCNIL () {
const self = this
function getOriginalVisitorCookieTimeout () {
const now = new Date()
const nowTs = Math.round(now.getTime() / 1000)
const visitorInfo = self.getVisitorInfo()
const createTs = parseInt(visitorInfo[2], 10)
const cookieTimeout = 33696000 // 13 mois en secondes
return (createTs + cookieTimeout) - nowTs
}
this.setVisitorCookieTimeout(getOriginalVisitorCookieTimeout())
}])
}
new Vue({ // eslint-disable-line no-new
el: '#app',
router,
mounted () {
// You'll need this for renderAfterDocumentEvent.
document.dispatchEvent(new Event('render-event'))
},
render: h => h(App)
})

View file

@ -1,9 +1,7 @@
export default { export default {
methods: { methods: {
buildImgUrl: function (imageName) { buildImgUrl: function (imageName) {
console.log(this) return '/img/' + imageName
return this.$root['/'] + 'img/' + imageName
} }
} }
} }

View file

@ -8,7 +8,7 @@
font-weight: 400; font-weight: 400;
src: local('Proza Libre Regular'), src: local('Proza Libre Regular'),
local('Proza Libre-Regular'), local('Proza Libre-Regular'),
url('../fonts/proza-libre-v4-latin-regular.woff2') format('woff2') url('../../public/fonts/proza-libre-v4-latin-regular.woff2') format('woff2')
} }
@font-face { @font-face {
@ -18,7 +18,7 @@
font-weight: 600; font-weight: 600;
src: local('Proza Libre SemiBold'), src: local('Proza Libre SemiBold'),
local('Proza Libre-SemiBold'), local('Proza Libre-SemiBold'),
url('../fonts/proza-libre-v4-latin-600.woff2') format('woff2') url('../../public/fonts/proza-libre-v4-latin-600.woff2') format('woff2')
} }
@font-face { @font-face {
@ -27,7 +27,7 @@
font-display: swap; font-display: swap;
font-weight: 400; font-weight: 400;
src: local('PT Sans'), local('PTSans-Regular'), src: local('PT Sans'), local('PTSans-Regular'),
url('../fonts/pt-sans-v11-latin-regular.woff2') format('woff2') url('../../public/fonts/pt-sans-v11-latin-regular.woff2') format('woff2')
} }
@font-face { @font-face {
@ -36,7 +36,7 @@
font-display: swap; font-display: swap;
font-weight: 600; font-weight: 600;
src: local('PT Sans Bold'), local('PTSans-Bold'), src: local('PT Sans Bold'), local('PTSans-Bold'),
url('../fonts/pt-sans-v11-latin-700.woff2') format('woff2') url('../../public/fonts/pt-sans-v11-latin-700.woff2') format('woff2')
} }
/* Default */ /* Default */

View file

@ -86,28 +86,27 @@
</template> </template>
<script> <script>
import { BCollapse } from 'bootstrap-vue' import { BCollapse } from 'bootstrap-vue'
export default { export default {
components: { components: {
BCollapse, BCollapse
}, },
data () { data () {
return { return {
prez: [...Array(9).keys()].map(i => (i < 1)), prez: [...Array(9).keys()].map(i => (i < 1)),
content: [...Array(5).keys()].map(i => false), content: [...Array(5).keys()].map(i => false),
tech: [...Array(4).keys()].map(i => false), tech: [...Array(4).keys()].map(i => false)
} }
}, },
methods: { methods: {
toggleAccordion (section, index) { toggleAccordion (section, index) {
if (this[section][index]) { if (this[section][index]) {
this.$set(this[section], index, false) this.$set(this[section], index, false)
} else { } else {
this[section] = this[section].map((v, i) => i === index) this[section] = this[section].map((v, i) => i === index)
}
} }
} }
} }
}
</script> </script>

View file

@ -466,4 +466,3 @@
</section> </section>
</main> </main>
</template> </template>

View file

@ -5,7 +5,7 @@
<div class="first-row"> <div class="first-row">
<img class="brand" :src="buildImgUrl('brand.png')" alt="PeerTube logo" /> <img class="brand" :src="buildImgUrl('brand.png')" alt="PeerTube logo" />
<div class="description">A free software to take back control of your videos</div> <div class="description" v-translate>A free software to take back control of your videos</div>
</div> </div>
<div class="marketing"> <div class="marketing">
@ -277,7 +277,7 @@
Créée en 2004, l'association se consacre désormais à <strong>léducation populaire aux enjeux du numérique.</strong> Créée en 2004, l'association se consacre désormais à <strong>léducation populaire aux enjeux du numérique.</strong>
Notre petite structure (moins de 40 membres, moins de 10 salarié·e·s) est connue pour avoir réalisé le projet Dégooglisons Internet, Notre petite structure (moins de 40 membres, moins de 10 salarié·e·s) est connue pour avoir réalisé le projet Dégooglisons Internet,
proposant 34 outils en ligne éthiques et alternatifs. Reconnue dintérêt général, notre association est proposant 34 outils en ligne éthiques et alternatifs. Reconnue dintérêt général, notre association est
<strong>financée à plus de 90% par vos dons</strong>, déductibles des impôts pour les contribuables français·es. <strong>financée à plus de 90% par vos dons</strong>, déductibles des impôts pour les contribuables français·es.
</p> </p>
<p> <p>
@ -420,8 +420,8 @@ export default {
title: 'Nothing to hide', title: 'Nothing to hide',
thumbnailUrl: 'https://peertube2.cpy.re/static/thumbnails/d2a5ec78-5f85-4090-8ec5-dc1102e022ea.jpg', thumbnailUrl: 'https://peertube2.cpy.re/static/thumbnails/d2a5ec78-5f85-4090-8ec5-dc1102e022ea.jpg',
url: 'https://peertube2.cpy.re/videos/watch/d2a5ec78-5f85-4090-8ec5-dc1102e022ea', url: 'https://peertube2.cpy.re/videos/watch/d2a5ec78-5f85-4090-8ec5-dc1102e022ea',
tags: [ 'tag', 'tag2', 'tag3 '], tags: [ 'tag', 'tag2', 'tag3' ],
description: 'Nothing to Hide (2017) est un film documentaire franco-allemand de Marc Meillassoux et Mihaela Gladovic, qui s\'intéresse aux effets de la surveillance de masse sur les individus et la société. Proposant un regard critique à propos des lois sur le renseignement mises en place par de nombreux États ces dernières années, le film nous rappelle à quel point le débat sur lusage des données personnelles est actuel et questionne les fondements de nos démocraties.', description: 'Nothing to Hide (2017) est un film documentaire franco-allemand de Marc Meillassoux et Mihaela Gladovic, qui s\'intéresse aux effets de la surveillance de masse sur les individus et la société. Proposant un regard critique à propos des lois sur le renseignement mises en place par de nombreux États ces dernières années, le film nous rappelle à quel point le débat sur lusage des données personnelles est actuel et questionne les fondements de nos démocraties.'
} }
] ]
}) })

View file

@ -37,4 +37,3 @@
</div> </div>
</main> </main>
</template> </template>

3
vue.config.js Normal file
View file

@ -0,0 +1,3 @@
module.exports = {
// options...
}

View file

@ -1,210 +0,0 @@
const webpack = require('webpack');
const fs = require('fs');
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const PrerenderSPAPlugin = require('prerender-spa-plugin');
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer;
const CopyWebpackPlugin = require('copy-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
let root = (process.env.NODE_ENV === 'preview') ? `/${process.env.INIT_CWD.match(/([^\/]*)\/*$/)[1]}/` : '/';
for (let i = 0; i < process.argv.length; i += 1) {
if (process.argv[i].indexOf('--root=') > -1) {
root = `/${process.argv[i].split('=')[1]}/`;
}
}
let config = {
entry: './app/index.js',
output: {
path: path.resolve(__dirname, `public${root}`),
publicPath: root,
filename: 'app.js',
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: 'img/[name].[ext]',
},
},
{
test: /\.(ttf|eot|woff(2)?)(\?[a-z0-9=&.]+)?$/,
loader: 'file-loader',
options: {
name: 'fonts/[name].[ext]',
},
},
{
test: /\.ya?ml$/,
loader: 'yaml-import-loader',
},
{
test: /\.scss$/,
use: [
'vue-style-loader',
'css-hot-loader',
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
'sass-loader',
],
},
{
test: /\.css$/,
use: [
'css-hot-loader',
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
],
},
{
enforce: 'pre',
test: /\.js$/,
exclude: /node_modules/,
loader: 'eslint-loader',
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
},
],
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js',
},
},
plugins: [
new VueLoaderPlugin(),
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css',
}),
new webpack.HotModuleReplacementPlugin(),
new CopyWebpackPlugin([
{ from: path.resolve(__dirname, './app/assets/fonts'), to: 'fonts' },
{ from: path.resolve(__dirname, './app/assets/icons'), to: 'icons' },
{ from: path.resolve(__dirname, './app/assets/img'), to: 'img' },
]),
],
devServer: {
contentBase: path.resolve(__dirname, './public'),
publicPath: '/',
historyApiFallback: true,
inline: true,
open: true,
hot: true,
},
devtool: 'eval-source-map',
};
module.exports = config;
const locales = [];
// Import locales list
fs.readdirSync('./app/locales').forEach(file => {
locales.push(file.replace(/(.*)\.yml/, '$1'));
});
if (process.env.NODE_ENV === 'development') {
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"development"',
BASE_URL: '""',
},
}),
new HtmlWebpackPlugin({
title: 'DEVELOPMENT prerender-spa-plugin',
template: 'index.html',
filename: 'index.html',
}),
]);
} else { // NODE_ENV === 'production|preview'
const routes = [root];
const pages = [];
// Import pages list
fs.readdirSync('./app/views').forEach(file => {
pages.push(file.replace(/(.*)\.vue/, '$1'));
});
// Localized routes
for (let i = 0; i < locales.length; i += 1) {
for (let j = 0; j < pages.length; j += 1) {
routes.push(
`${root}${locales[i]}${pages[j].toLowerCase().replace(/^/, '/').replace('/home', '')}`
);
}
}
module.exports.devtool = '#source-map';
module.exports.optimization = {
minimizer: [
new TerserPlugin({
cache: true,
parallel: true,
sourceMap: true, // set to true if you want JS source maps
}),
new OptimizeCSSAssetsPlugin({}),
],
};
module.exports.plugins.push(
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: ((process.env.NODE_ENV !== 'production') ? '"preview"' : '"production"'),
BASE_URL: `"${root.split('/')[1]}"`,
},
}),
new HtmlWebpackPlugin({
title: 'PRODUCTION prerender-spa-plugin',
template: 'index.html',
filename: path.resolve(__dirname, 'public/index.html'),
}),
new PrerenderSPAPlugin({
staticDir: path.join(__dirname, 'public'),
routes,
renderer: new Renderer({
headless: true,
renderAfterDocumentEvent: 'render-event',
maxConcurrentRoutes: 1,
injectProperty: 'vuefsPrerender',
inject: {
prerender: true,
},
}),
}),
);
}
// Create ./public/img/lg/* symlinks only if images need translation
if (fs.existsSync('./app/assets/img/fr')) {
if (!fs.existsSync('./public')){ fs.mkdirSync('./public'); }
if (!fs.existsSync(`./public${root}`)){ fs.mkdirSync(`./public${root}`); }
if (!fs.existsSync(`./public${root}img`)){ fs.mkdirSync(`./public${root}img`); }
for (let i = 0; i < locales.length; i += 1) {
if (!fs.existsSync(`./public${root}img/${locales[i]}`)){
fs.mkdirSync(`./public${root}img/${locales[i]}`);
}
fs.readdirSync('./app/assets/img/fr').forEach(file => {
if (!fs.existsSync(`./app/assets/img/${locales[i]}/${file}`)) {
const symlinkOrigin = (process.env.NODE_ENV === 'development')
? `../../../app/assets/img/fr/${file}` // [dev] relative to assets
: `../fr/${file}` // [prod] relative to public
fs.symlink(symlinkOrigin, `./public${root}img/${locales[i]}/${file}`,
function (err) { console.log(err); } // eslint-disable-line
);
}
});
}
}

2189
yarn.lock

File diff suppressed because it is too large Load diff