Being common

This commit is contained in:
sheychen 2019-04-16 14:04:25 +02:00
parent 2f52372e35
commit 2e3a988518
20 changed files with 280 additions and 92 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -48,12 +48,12 @@
"vue-chartjs": "^3.4.2",
"vue-loader": "^15.4.2",
"vue-style-loader": "^4.1.2",
"vue-template-compiler": "^2.5.22",
"vue-template-compiler": "^2.6.10",
"webpack": "^4.6.0",
"webpack-cli": "^3.2.1"
},
"dependencies": {
"vue": "^2.5.22"
"vue": "^2.6.10"
},
"babel": {
"presets": [

View File

@ -0,0 +1,19 @@
<script>
import { emitErrorMixin, handleOptionsMixin } from '../core/tools'
import serviceHeaderVue from '../core/serviceHeader.vue'
import settingBooleanVue from '../core/input/settingBoolean.vue'
import settingIntVue from '../core/input/settingInt.vue'
import settingStringVue from './input/settingString.vue'
export default {
mixins: [ emitErrorMixin, handleOptionsMixin ],
components: {
serviceHeader: serviceHeaderVue,
settingBoolean: settingBooleanVue,
settingInt: settingIntVue,
settingString: settingStringVue
}
}
</script>

View File

@ -0,0 +1,13 @@
<script>
export default {
props: {
id: String,
title: String
},
methods: {
sendChange(value) {
this.$emit('change', { name: this.id, value: value })
}
}
}
</script>

View File

@ -0,0 +1,3 @@
p.setting
label(:for="id") {{ title }}:
block input

View File

@ -0,0 +1,14 @@
<template lang="pug">
extends model
block input
input(:id="id" type="checkbox" :checked="value" @change.stop="sendChange($event.target.checked)")
</template>
<script>
import baseSettingVue from './baseSetting.vue'
export default {
extends: baseSettingVue,
props: { value: Boolean }
}
</script>

View File

@ -0,0 +1,14 @@
<template lang="pug">
extends model
block input
input(:id="id" type="number" step="1" :value="value" @keyup.enter="sendChange(parseInt($event.target.value))")
</template>
<script>
import baseSettingVue from './baseSetting.vue'
export default {
extends: baseSettingVue,
props: { value: Number }
}
</script>

View File

@ -0,0 +1,14 @@
<template lang="pug">
extends model
block input
input(:id="id" type="text" :value="value" @keyup.enter="sendChange($event.target.value)")
</template>
<script>
import baseSettingVue from './baseSetting.vue'
export default {
extends: baseSettingVue,
props: { value: String }
}
</script>

View File

@ -0,0 +1,15 @@
<template lang="pug">
.service-header
.title(@click="showSettings = !showSettings")
slot(name="title")
.settings(v-show="showSettings")
slot(name="settings")
</template>
<script>
export default {
data() { return {
showSettings: false
} }
}
</script>

View File

@ -15,6 +15,9 @@ export const handleOptionsMixin = {
const options = {...this.$props}
options[name] = value
this.saveOptions(options)
},
setOptionCouple(couple) {
this.setOption(couple.name, couple.value)
}
}
}

View File

@ -5,8 +5,9 @@
.list(v-if="statues.length > 0" @scroll="onScroll")
template(v-for="status in statues")
status(v-if="showStatus(status)" :key="status.id" :status="status" :now="now" :showMedia="showMedia" @mark="onStatusMark")
.status(v-show="loadingOlder") Loading...
template(v-else) Loading...
.status(v-show="loadingOlder")
.service-loader
.service-loader(v-else)
.notifications(v-if="notifications.length > 0")
.header
| Notifications

View File

@ -1,25 +1,16 @@
<template lang="pug">
.mastodon
.header(@click="showSettings = !showSettings")
| Mastodon:
span(v-html="parseEmojis(account.display_name, account.emojis)")
| {{ server ? '@' + server : '' }}
.settings(v-show="showSettings")
p
label(for="reconnect") Reconnect:
input#reconnect(type="checkbox" :checked="reconnect" @change="setOption('reconnect', $event.target.checked)")
p
label(for="reblog") Show reblogs:
input#reblog(type="checkbox" :checked="reblog" @change="setOption('reblog', $event.target.checked)")
p
label(for="reply") Show replies:
input#reply(type="checkbox" :checked="reply" @change="setOption('reply', $event.target.checked)")
p
label(for="buffer") Buffer:
input#buffer(type="number" :value="buffer" @keyup.enter="setOption('buffer', parseInt($event.target.value))")
p
label(for="showMedia") Show media:
input#showMedia(type="checkbox" :checked="showMedia" @change="setOption('showMedia', $event.target.checked)")
service-header
template(#title)
| Mastodon:
span(v-html="parseEmojis(account.display_name, account.emojis)")
| {{ server ? '@' + server : '' }}
template(#settings)
setting-boolean(:id="'reconnect'" :title="'Reconnect'" :value="reconnect" @change="setOptionCouple")
setting-boolean(:id="'reblog'" :title="'Show reblogs'" :value="reblog" @change="setOptionCouple")
setting-boolean(:id="'reply'" :title="'Show replies'" :value="reply" @change="setOptionCouple")
setting-int(:id="'buffer'" :title="'Buffer size'" :value="buffer" @change="setOptionCouple")
setting-boolean(:id="'showMedia'" :title="'Show medias'" :value="showMedia" @change="setOptionCouple")
client(v-if="server && token" v-bind="$props")
.auth(v-else)
form(@submit.prevent="setServer")
@ -34,13 +25,15 @@
</template>
<script>
import { emitErrorMixin, handleOptionsMixin } from '../core/tools'
import baseServiceVue from '../core/baseService.vue'
import { parseEmojisMixin } from './tools'
import clientVue from './client.vue'
export default { //TODO: Use oauth
name: 'mastodon',
mixins: [ emitErrorMixin, handleOptionsMixin, parseEmojisMixin ],
extends: baseServiceVue,
mixins: [ parseEmojisMixin ],
components: {
client: clientVue
},
@ -76,7 +69,6 @@ export default { //TODO: Use oauth
return {
newServer: this.server,
newToken: this.token,
showSettings: false,
account: { display_name: 'Loading...', emojis: [] }
};
},

View File

@ -1,13 +1,10 @@
<template lang="pug">
.nextcloud-news(v-show="unreaded.length > 0 || !server || !token || !username")
.header(@click="showSettings = !showSettings") Nextcloud News
.settings(v-show="showSettings")
p
label(for="update") Update interval:
input#update(type="number" :value="update" @keyup.enter="setOption('update', parseInt($event.target.value))")
p
label(for="buffer") Buffer:
input#buffer(type="number" :value="buffer" @keyup.enter="setOption('buffer', parseInt($event.target.value))")
service-header
template(#title) Nextcloud News
template(#settings)
setting-boolean(:id="'update'" :title="'Update interval'" :value="update" @change="setOptionCouple")
setting-int(:id="'buffer'" :title="'Buffer size'" :value="buffer" @change="setOptionCouple")
.unreaded
.news(v-for="news in unreaded")
a(:href="news.url" target="_blank")
@ -31,12 +28,13 @@
</template>
<script>
import { emitErrorMixin, handleOptionsMixin } from '../core/tools'
import fromNowVue, { timerMinin } from '../core/fromNow.vue';
import baseServiceVue from '../core/baseService.vue'
import fromNowVue, { timerMinin } from '../core/fromNow.vue'
export default {
name: 'nextcloud-news',
mixins: [ emitErrorMixin, timerMinin, handleOptionsMixin ],
extends: baseServiceVue,
mixins: [ timerMinin ],
components: {
fromNow: fromNowVue
},
@ -68,7 +66,6 @@ export default {
}),
unreaded: [],
now: Date.now(),
showSettings: false,
newServer: this.server,
newUsername: this.username,
newToken: this.token,

View File

@ -1,18 +1,13 @@
<template lang="pug">
.openweathermap
.header(@click="showSettings = !showSettings") OpenWeatherMap
.settings(v-show="showSettings")
p
label(for="token") Token:
input#token(:value="token" @keyup.enter="setOption('token', $event.target.value)")
p
label(for="update") Update interval:
input#update(type="number" :value="update" @keyup.enter="setOption('update', parseInt($event.target.value))")
p
label(for="forecastLimit") Forecast limit:
input#forecastLimit(type="number" :value="forecastLimit" @keyup.enter="setOption('forecastLimit', parseInt($event.target.value))")
p
button(@click="showAdd = true") Add city
service-header
template(#title) OpenWeatherMap
template(#settings)
setting-string(:id="'token'" :title="'Token'" :value="token" @change="setOptionCouple")
setting-int(:id="'update'" :title="'Update interval'" :value="update" @change="setOptionCouple")
setting-int(:id="'forecastLimit'" :title="'Forecast limit'" :value="forecastLimit" @change="setOptionCouple")
p.setting
button(@click="showAdd = true") Add city
template(v-if="weathers.length > 0 || cities.length == 0")
.list
.weather(v-for="(city, id) in weathers" :class="{ selected: selected == id }" @click.stop.prevent="makeSelect(id)")
@ -20,6 +15,7 @@
p {{ main.description }}
.ic
img(:src="`https://openweathermap.org/img/w/${main.icon}.png`" :alt="main.main")
span.remove(@click.stop.prevent="removeCity(id)")
.header
| {{ city.name }}&nbsp;
img.icon(:src="`https://openweathermap.org/images/flags/${city.sys.country.toLowerCase()}.png`" :alt="city.sys.country" :title="city.sys.country")
@ -28,20 +24,21 @@
input.weather(v-show="showAdd" placeholder="city id" @keyup.enter="addCity(parseInt($event.target.value))")
.forecast
chart(v-if="forecast" :chartData="forecastChart")
template(v-else) Loading...
template(v-else) Loading...
.service-loader(v-else)
.service-loader(v-else)
</template>
<script>
import { emitErrorMixin, handleOptionsMixin } from '../core/tools'
import baseServiceVue from '../core/baseService.vue'
import chartVue from './chart.vue'
export default {
name: 'openweathermap',
extends: baseServiceVue,
components: {
chart: chartVue
},
mixins: [ emitErrorMixin, handleOptionsMixin ],
props: {
token: String,
cities: {
@ -79,7 +76,6 @@ export default {
weathers: [],
forecast: null,
selected: 0,
showSettings: false,
showAdd: this.cities.length == 0
};
},
@ -144,6 +140,11 @@ export default {
const options = {...this.$props}
options.cities.push({id: id})
this.saveOptions(options)
},
removeCity(i) {
const options = {...this.$props}
options.cities.splice(i, 1)
this.saveOptions(options)
}
},
created() {

View File

@ -63,19 +63,60 @@ a {
flex: 1;
}
#services > div > .header, #services > div > .settings {
#services > div .service-header .title, #services > div .service-header .settings {
margin: 0.3em;
background-color: #222;
border-radius: 0.3em;
padding: 0.3em;
}
#services > div > .header {
#services > div .service-header .title {
font-size: large;
text-align: center;
font-weight: bold;
}
#services .service-loader {
display: inline-block;
width: 64px;
height: 64px;
}
#services .service-loader:after {
content: " ";
display: block;
width: 46px;
height: 46px;
margin: 1px;
border-radius: 50%;
border: 5px solid #aaa;
border-color: #aaa transparent #aaa transparent;
-webkit-animation: service-loader 1.2s linear infinite;
animation: service-loader 1.2s linear infinite;
}
@-webkit-keyframes service-loader {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes service-loader {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
.mastodon .client {
display: -webkit-box;
display: -ms-flexbox;
@ -190,16 +231,6 @@ a {
max-width: 30%;
}
.openweathermap .ic {
overflow: hidden;
height: 30px;
display: inline-block;
}
.openweathermap .ic img {
margin-top: -10px;
}
.openweathermap .list {
display: -webkit-box;
display: -ms-flexbox;
@ -230,6 +261,13 @@ a {
.openweathermap .weather {
min-width: 17em;
border: 1px solid #222;
display: -ms-grid;
display: grid;
-ms-grid-columns: auto auto;
grid-template-columns: auto auto;
-ms-grid-rows: 1.2em auto;
grid-template-rows: 1.2em auto;
grid-template-areas: "header main" "data remove";
}
.openweathermap .weather.selected {
@ -237,15 +275,25 @@ a {
}
.openweathermap .weather .header {
-ms-grid-row: 1;
-ms-grid-column: 1;
grid-area: header;
font-size: 1.2em;
}
.openweathermap .weather .data {
-ms-grid-row: 2;
-ms-grid-column: 1;
grid-area: data;
margin-top: .5em;
}
.openweathermap .weather .main {
float: right;
-ms-grid-row: 1;
-ms-grid-column: 2;
grid-area: main;
-ms-grid-column-align: right;
justify-self: right;
}
.openweathermap .weather .main p {
@ -254,6 +302,28 @@ a {
vertical-align: top;
}
.openweathermap .weather .remove {
-ms-grid-row: 2;
-ms-grid-column: 2;
grid-area: remove;
-ms-grid-column-align: right;
justify-self: right;
-ms-flex-item-align: bottom;
-ms-grid-row-align: bottom;
align-self: bottom;
font-size: .8em;
}
.openweathermap .ic {
overflow: hidden;
height: 30px;
display: inline-block;
}
.openweathermap .ic img {
margin-top: -10px;
}
.nextcloud-news .news {
margin: 0.3em;
background-color: #222;

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
//TODO: discord, weather graph
//TODO: discord
const servicesStorage = 'services'
var app = new Vue({

View File

@ -5,6 +5,7 @@ $backColor: #333
$tileColor: #222
$darkColor: #111
$halfColor: #999
$noneColor: #aaa
$foreColor: #eee
@mixin tile
@ -24,7 +25,7 @@ body
a
text-decoration: none
color: #aaa
color: $noneColor
.icon
width: 1em
@ -56,12 +57,32 @@ a
display: flex
& > div
flex: 1
& > .header, & > .settings
@include tile
& > .header
font-size: large
text-align: center
font-weight: bold
.service-header
.title, .settings
@include tile
.title
font-size: large
text-align: center
font-weight: bold
.service-loader
display: inline-block
width: 64px
height: 64px
&:after
content: " "
display: block
width: 46px
height: 46px
margin: 1px
border-radius: 50%
border: 5px solid $noneColor
border-color: $noneColor transparent $noneColor transparent
animation: service-loader 1.2s linear infinite
@keyframes service-loader
0%
transform: rotate(0deg)
100%
transform: rotate(360deg)
.mastodon
.client
@ -82,7 +103,7 @@ a
.account
.name
margin: 0 $borderRadius
color: #eee
color: $foreColor
.avatar
float: left
border-radius: $borderRadius
@ -128,13 +149,6 @@ a
float: right
.openweathermap
.ic
overflow: hidden
height: 30px
display: inline-block
img
margin-top: -10px
display: flex
flex-direction: column
max-width: 30%
@ -152,18 +166,36 @@ a
.weather
min-width: 17em
border: 1px solid $tileColor
display: grid
grid-template-columns: auto auto
grid-template-rows: 1.2em auto
grid-template-areas: "header main" "data remove"
&.selected
border-color: $halfColor
.header
grid-area: header
font-size: 1.2em
.data
grid-area: data
margin-top: .5em
.main
float: right
grid-area: main
justify-self: right
p
margin: $borderRadius
display: inline
vertical-align: top
.remove
grid-area: remove
justify-self: right
align-self: bottom
font-size: .8em
.ic
overflow: hidden
height: 30px
display: inline-block
img
margin-top: -10px
.nextcloud-news
.news