Skip to content
Snippets Groups Projects
Commit e6eb1b2a authored by syuilo's avatar syuilo
Browse files

Clean up

parent ddad9da1
No related branches found
No related tags found
No related merge requests found
Showing
with 0 additions and 1099 deletions
...@@ -324,8 +324,6 @@ desktop/views/components/home.vue: ...@@ -324,8 +324,6 @@ desktop/views/components/home.vue:
polls: "投票" polls: "投票"
post-form: "投稿フォーム" post-form: "投稿フォーム"
messaging: "メッセージ" messaging: "メッセージ"
channel: "チャンネル"
access-log: "アクセスログ"
server: "サーバー情報" server: "サーバー情報"
donation: "寄付のお願い" donation: "寄付のお願い"
nav: "ナビゲーション" nav: "ナビゲーション"
...@@ -336,12 +334,6 @@ desktop/views/input-dialog.vue: ...@@ -336,12 +334,6 @@ desktop/views/input-dialog.vue:
cancel: "キャンセル" cancel: "キャンセル"
ok: "決定" ok: "決定"
desktop/views/components/mentions.vue:
all: "すべて"
followed: "フォロー中"
empty: "あなた宛ての投稿はありません。"
empty-followed: "あなたがフォローしているユーザーからの言及はありません。"
desktop/views/components/messaging-room-window.vue: desktop/views/components/messaging-room-window.vue:
title: "メッセージ:" title: "メッセージ:"
...@@ -660,11 +652,6 @@ desktop/views/widgets/users.vue: ...@@ -660,11 +652,6 @@ desktop/views/widgets/users.vue:
refresh: "他を見る" refresh: "他を見る"
no-one: "いません!" no-one: "いません!"
desktop/views/widgets/channel.vue:
title: "チャンネル"
settings: "ウィジェットの設定"
get-started: "右上の歯車をクリックして受信するチャンネルを指定してください"
mobile/views/components/drive.vue: mobile/views/components/drive.vue:
drive: "ドライブ" drive: "ドライブ"
used: "使用中" used: "使用中"
......
/**
* Channels
*/
// Style
import './style.styl';
require('./tags');
import init from '../init';
/**
* init
*/
init(() => {
});
@import "../app"
html
padding 8px
background #efefef
#wait
top auto
bottom 15px
left 15px
<mk-channel>
<mk-header/>
<hr>
<main v-if="!fetching">
<h1>{ channel.title }</h1>
<div v-if="$root.$data.os.isSignedIn">
<p v-if="channel.isWatching">このチャンネルをウォッチしています <a @click="unwatch">ウォッチ解除</a></p>
<p v-if="!channel.isWatching"><a @click="watch">このチャンネルをウォッチする</a></p>
</div>
<div class="share">
<mk-twitter-button/>
<mk-line-button/>
</div>
<div class="body">
<p v-if="notesFetching">読み込み中<mk-ellipsis/></p>
<div v-if="!notesFetching">
<p v-if="notes == null || notes.length == 0">まだ投稿がありません</p>
<template v-if="notes != null">
<mk-channel-note each={ note in notes.slice().reverse() } note={ note } form={ parent.refs.form }/>
</template>
</div>
</div>
<hr>
<mk-channel-form v-if="$root.$data.os.isSignedIn" channel={ channel } ref="form"/>
<div v-if="!$root.$data.os.isSignedIn">
<p>参加するには<a href={ _URL_ }>ログインまたは新規登録</a>してください</p>
</div>
<hr>
<footer>
<small><a href={ _URL_ }>Misskey</a> ver { _VERSION_ } (葵 aoi)</small>
</footer>
</main>
<style lang="stylus" scoped>
:scope
display block
> main
> h1
font-size 1.5em
color #f00
> .share
> *
margin-right 4px
> .body
margin 8px 0 0 0
> mk-channel-form
max-width 500px
</style>
<script lang="typescript">
import Progress from '../../common/scripts/loading';
import ChannelStream from '../../common/scripts/streaming/channel-stream';
this.mixin('i');
this.mixin('api');
this.id = this.opts.id;
this.fetching = true;
this.notesFetching = true;
this.channel = null;
this.notes = null;
this.connection = new ChannelStream(this.id);
this.unreadCount = 0;
this.on('mount', () => {
document.documentElement.style.background = '#efefef';
Progress.start();
let fetched = false;
// チャンネル概要読み込み
this.$root.$data.os.api('channels/show', {
channelId: this.id
}).then(channel => {
if (fetched) {
Progress.done();
} else {
Progress.set(0.5);
fetched = true;
}
this.update({
fetching: false,
channel: channel
});
document.title = channel.title + ' | Misskey'
});
// 投稿読み込み
this.$root.$data.os.api('channels/notes', {
channelId: this.id
}).then(notes => {
if (fetched) {
Progress.done();
} else {
Progress.set(0.5);
fetched = true;
}
this.update({
notesFetching: false,
notes: notes
});
});
this.connection.on('note', this.onNote);
document.addEventListener('visibilitychange', this.onVisibilitychange, false);
});
this.on('unmount', () => {
this.connection.off('note', this.onNote);
this.connection.close();
document.removeEventListener('visibilitychange', this.onVisibilitychange);
});
this.onNote = note => {
this.notes.unshift(note);
this.update();
if (document.hidden && this.$root.$data.os.isSignedIn && note.userId !== this.$root.$data.os.i.id) {
this.unreadCount++;
document.title = `(${this.unreadCount}) ${this.channel.title} | Misskey`;
}
};
this.onVisibilitychange = () => {
if (!document.hidden) {
this.unreadCount = 0;
document.title = this.channel.title + ' | Misskey'
}
};
this.watch = () => {
this.$root.$data.os.api('channels/watch', {
channelId: this.id
}).then(() => {
this.channel.isWatching = true;
this.update();
}, e => {
alert('error');
});
};
this.unwatch = () => {
this.$root.$data.os.api('channels/unwatch', {
channelId: this.id
}).then(() => {
this.channel.isWatching = false;
this.update();
}, e => {
alert('error');
});
};
</script>
</mk-channel>
<mk-channel-note>
<header>
<a class="index" @click="reply">{ note.index }:</a>
<a class="name" href={ _URL_ + '/@' + acct }><b>{ getUserName(note.user) }</b></a>
<mk-time time={ note.createdAt }/>
<mk-time time={ note.createdAt } mode="detail"/>
<span>ID:<i>{ acct }</i></span>
</header>
<div>
<a v-if="note.reply">&gt;&gt;{ note.reply.index }</a>
{ note.text }
<div class="media" v-if="note.media">
<template each={ file in note.media }>
<a href={ file.url } target="_blank">
<img src={ file.url + '?thumbnail&size=512' } alt={ file.name } title={ file.name }/>
</a>
</template>
</div>
</div>
<style lang="stylus" scoped>
:scope
display block
margin 0
padding 0
> header
position -webkit-sticky
position sticky
z-index 1
top 0
background rgba(239, 239, 239, 0.9)
> .index
margin-right 0.25em
color #000
> .name
margin-right 0.5em
color #008000
> mk-time
margin-right 0.5em
&:first-of-type
display none
@media (max-width 600px)
> mk-time
&:first-of-type
display initial
&:last-of-type
display none
> div
padding 0 0 1em 2em
> .media
> a
display inline-block
> img
max-width 100%
vertical-align bottom
</style>
<script lang="typescript">
import getAcct from '../../../../acct/render';
import getUserName from '../../../../renderers/get-user-name';
this.note = this.opts.note;
this.form = this.opts.form;
this.acct = getAcct(this.note.user);
this.name = getUserName(this.note.user);
this.reply = () => {
this.form.update({
reply: this.note
});
};
</script>
</mk-channel-note>
<mk-channel-form>
<p v-if="reply"><b>&gt;&gt;{ reply.index }</b> ({ getUserName(reply.user) }): <a @click="clearReply">[x]</a></p>
<textarea ref="text" disabled={ wait } oninput={ update } onkeydown={ onkeydown } onpaste={ onpaste } placeholder="%i18n:ch.tags.mk-channel-form.textarea%"></textarea>
<div class="actions">
<button @click="selectFile">%fa:upload%%i18n:ch.tags.mk-channel-form.upload%</button>
<button @click="drive">%fa:cloud%%i18n:ch.tags.mk-channel-form.drive%</button>
<button :class="{ wait: wait }" ref="submit" disabled={ wait || (refs.text.value.length == 0) } @click="note">
<template v-if="!wait">%fa:paper-plane%</template>{ wait ? '%i18n:!ch.tags.mk-channel-form.posting%' : '%i18n:!ch.tags.mk-channel-form.note%' }<mk-ellipsis v-if="wait"/>
</button>
</div>
<mk-uploader ref="uploader"/>
<ol v-if="files">
<li each={ files }>{ name }</li>
</ol>
<input ref="file" type="file" accept="image/*" multiple="multiple" onchange={ changeFile }/>
<style lang="stylus" scoped>
:scope
display block
> textarea
width 100%
max-width 100%
min-width 100%
min-height 5em
> .actions
display flex
> button
> [data-fa]
margin-right 0.25em
&:last-child
margin-left auto
&.wait
cursor wait
> input[type='file']
display none
</style>
<script lang="typescript">
import getUserName from '../../../../renderers/get-user-name';
this.mixin('api');
this.channel = this.opts.channel;
this.files = null;
this.on('mount', () => {
this.$refs.uploader.on('uploaded', file => {
this.update({
files: [file]
});
});
});
this.upload = file => {
this.$refs.uploader.upload(file);
};
this.clearReply = () => {
this.update({
reply: null
});
};
this.clear = () => {
this.clearReply();
this.update({
files: null
});
this.$refs.text.value = '';
};
this.note = () => {
this.update({
wait: true
});
const files = this.files && this.files.length > 0
? this.files.map(f => f.id)
: undefined;
this.$root.$data.os.api('notes/create', {
text: this.$refs.text.value == '' ? undefined : this.$refs.text.value,
mediaIds: files,
replyId: this.reply ? this.reply.id : undefined,
channelId: this.channel.id
}).then(data => {
this.clear();
}).catch(err => {
alert('失敗した');
}).then(() => {
this.update({
wait: false
});
});
};
this.changeFile = () => {
Array.from(this.$refs.file.files).forEach(this.upload);
};
this.selectFile = () => {
this.$refs.file.click();
};
this.drive = () => {
window['cb'] = files => {
this.update({
files: files
});
};
window.open(_URL_ + '/selectdrive?multiple=true',
'drive_window',
'height=500,width=800');
};
this.onkeydown = e => {
if ((e.which == 10 || e.which == 13) && (e.ctrlKey || e.metaKey)) this.post();
};
this.onpaste = e => {
Array.from(e.clipboardData.items).forEach(item => {
if (item.kind == 'file') {
this.upload(item.getAsFile());
}
});
};
this.getUserName = getUserName;
</script>
</mk-channel-form>
<mk-twitter-button>
<a href="https://twitter.com/share?ref_src=twsrc%5Etfw" class="twitter-share-button" data-show-count="false">Tweet</a>
<script lang="typescript">
this.on('mount', () => {
const head = document.getElementsByTagName('head')[0];
const script = document.createElement('script');
script.setAttribute('src', 'https://platform.twitter.com/widgets.js');
script.setAttribute('async', 'async');
head.appendChild(script);
});
</script>
</mk-twitter-button>
<mk-line-button>
<div class="line-it-button" data-lang="ja" data-type="share-a" data-url={ _CH_URL_ } style="display: none;"></div>
<script lang="typescript">
this.on('mount', () => {
const head = document.getElementsByTagName('head')[0];
const script = document.createElement('script');
script.setAttribute('src', 'https://d.line-scdn.net/r/web/social-plugin/js/thirdparty/loader.min.js');
script.setAttribute('async', 'async');
head.appendChild(script);
});
</script>
</mk-line-button>
<mk-header>
<div>
<a href={ _CH_URL_ }>Index</a> | <a href={ _URL_ }>Misskey</a>
</div>
<div>
<a v-if="!$root.$data.os.isSignedIn" href={ _URL_ }>ログイン(新規登録)</a>
<a v-if="$root.$data.os.isSignedIn" href={ _URL_ + '/@' + I.username }>{ I.username }</a>
</div>
<style lang="stylus" scoped>
:scope
display flex
> div:last-child
margin-left auto
</style>
<script lang="typescript">
this.mixin('i');
</script>
</mk-header>
<mk-index>
<mk-header/>
<hr>
<button @click="n">%i18n:ch.tags.mk-index.new%</button>
<hr>
<ul v-if="channels">
<li each={ channels }><a href={ '/' + this.id }>{ this.title }</a></li>
</ul>
<style lang="stylus" scoped>
:scope
display block
</style>
<script lang="typescript">
this.mixin('api');
this.on('mount', () => {
this.$root.$data.os.api('channels', {
limit: 100
}).then(channels => {
this.update({
channels: channels
});
});
});
this.n = () => {
const title = window.prompt('%i18n:!ch.tags.mk-index.channel-title%');
this.$root.$data.os.api('channels/create', {
title: title
}).then(channel => {
location.href = '/' + channel.id;
});
};
</script>
</mk-index>
require('./index.tag');
require('./channel.tag');
require('./header.tag');
import Stream from './stream';
import MiOS from '../../../mios';
/**
* Channel stream connection
*/
export default class Connection extends Stream {
constructor(os: MiOS, channelId) {
super(os, 'channel', {
channel: channelId
});
}
}
<template>
<div class="mkw-access-log">
<mk-widget-container :show-header="props.design == 0">
<template slot="header">%fa:server%%i18n:@title%</template>
<div :class="$style.logs" ref="log">
<p v-for="req in requests">
<span :class="$style.ip" :style="`color:${ req.fg }; background:${ req.bg }`">{{ req.ip }}</span>
<b>{{ req.method }}</b>
<span>{{ req.path }}</span>
</p>
</div>
</mk-widget-container>
</div>
</template>
<script lang="ts">
import define from '../../../common/define-widget';
import * as seedrandom from 'seedrandom';
export default define({
name: 'broadcast',
props: () => ({
design: 0
})
}).extend({
data() {
return {
requests: [],
connection: null,
connectionId: null
};
},
mounted() {
this.connection = (this as any).os.streams.requestsStream.getConnection();
this.connectionId = (this as any).os.streams.requestsStream.use();
this.connection.on('request', this.onRequest);
},
beforeDestroy() {
this.connection.off('request', this.onRequest);
(this as any).os.streams.requestsStream.dispose(this.connectionId);
},
methods: {
onRequest(request) {
const random = seedrandom(request.ip);
const r = Math.floor(random() * 255);
const g = Math.floor(random() * 255);
const b = Math.floor(random() * 255);
const luma = (0.2126 * r) + (0.7152 * g) + (0.0722 * b); // SMPTE C, Rec. 709 weightings
request.bg = `rgb(${r}, ${g}, ${b})`;
request.fg = luma >= 165 ? '#000' : '#fff';
this.requests.push(request);
if (this.requests.length > 30) this.requests.shift();
(this.$refs.log as any).scrollTop = (this.$refs.log as any).scrollHeight;
},
func() {
if (this.props.design == 1) {
this.props.design = 0;
} else {
this.props.design++;
}
this.save();
}
}
});
</script>
<style lang="stylus" module>
.logs
max-height 250px
overflow auto
> p
margin 0
padding 8px
font-size 0.8em
color #555
&:nth-child(odd)
background rgba(#000, 0.025)
> b
margin-right 4px
.ip
margin-right 4px
padding 0 4px
</style>
import Vue from 'vue'; import Vue from 'vue';
import wAccessLog from './access-log.vue';
import wVersion from './version.vue'; import wVersion from './version.vue';
import wRss from './rss.vue'; import wRss from './rss.vue';
import wServer from './server.vue'; import wServer from './server.vue';
...@@ -22,4 +21,3 @@ Vue.component('mkw-broadcast', wBroadcast); ...@@ -22,4 +21,3 @@ Vue.component('mkw-broadcast', wBroadcast);
Vue.component('mkw-server', wServer); Vue.component('mkw-server', wServer);
Vue.component('mkw-rss', wRss); Vue.component('mkw-rss', wRss);
Vue.component('mkw-version', wVersion); Vue.component('mkw-version', wVersion);
Vue.component('mkw-access-log', wAccessLog);
...@@ -21,8 +21,6 @@ ...@@ -21,8 +21,6 @@
<option value="polls">%i18n:@polls%</option> <option value="polls">%i18n:@polls%</option>
<option value="post-form">%i18n:@post-form%</option> <option value="post-form">%i18n:@post-form%</option>
<option value="messaging">%i18n:@messaging%</option> <option value="messaging">%i18n:@messaging%</option>
<option value="channel">%i18n:@channel%</option>
<option value="access-log">%i18n:@access-log%</option>
<option value="server">%i18n:@server%</option> <option value="server">%i18n:@server%</option>
<option value="donation">%i18n:@donation%</option> <option value="donation">%i18n:@donation%</option>
<option value="nav">%i18n:@nav%</option> <option value="nav">%i18n:@nav%</option>
......
<template>
<div class="mk-mentions">
<header>
<span :data-active="mode == 'all'" @click="mode = 'all'">%i18n:@all%</span>
<span :data-active="mode == 'following'" @click="mode = 'following'">%i18n:@followed%</span>
</header>
<div class="fetching" v-if="fetching">
<mk-ellipsis-icon/>
</div>
<p class="empty" v-if="notes.length == 0 && !fetching">
%fa:R comments%
<span v-if="mode == 'all'">%i18n:@empty%</span>
<span v-if="mode == 'following'">%i18n:@empty-followed%</span>
</p>
<mk-notes :notes="notes" ref="timeline"/>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
data() {
return {
fetching: true,
moreFetching: false,
mode: 'all',
notes: []
};
},
watch: {
mode() {
this.fetch();
}
},
mounted() {
document.addEventListener('keydown', this.onDocumentKeydown);
window.addEventListener('scroll', this.onScroll);
this.fetch(() => this.$emit('loaded'));
},
beforeDestroy() {
document.removeEventListener('keydown', this.onDocumentKeydown);
window.removeEventListener('scroll', this.onScroll);
},
methods: {
onDocumentKeydown(e) {
if (e.target.tagName != 'INPUT' && e.target.tagName != 'TEXTAREA') {
if (e.which == 84) { // t
(this.$refs.timeline as any).focus();
}
}
},
onScroll() {
const current = window.scrollY + window.innerHeight;
if (current > document.body.offsetHeight - 8) this.more();
},
fetch(cb?) {
this.fetching = true;
this.notes = [];
(this as any).api('notes/mentions', {
following: this.mode == 'following'
}).then(notes => {
this.notes = notes;
this.fetching = false;
if (cb) cb();
});
},
more() {
if (this.moreFetching || this.fetching || this.notes.length == 0) return;
this.moreFetching = true;
(this as any).api('notes/mentions', {
following: this.mode == 'following',
untilId: this.notes[this.notes.length - 1].id
}).then(notes => {
this.notes = this.notes.concat(notes);
this.moreFetching = false;
});
}
}
});
</script>
<style lang="stylus" scoped>
@import '~const.styl'
.mk-mentions
background #fff
border solid 1px rgba(#000, 0.075)
border-radius 6px
> header
padding 8px 16px
border-bottom solid 1px #eee
> span
margin-right 16px
line-height 27px
font-size 18px
color #555
&:not([data-active])
color $theme-color
cursor pointer
&:hover
text-decoration underline
> .fetching
padding 64px 0
> .empty
display block
margin 0 auto
padding 32px
max-width 400px
text-align center
color #999
> [data-fa]
display block
margin-bottom 16px
font-size 3em
color #ccc
</style>
...@@ -33,9 +33,6 @@ ...@@ -33,9 +33,6 @@
</div> </div>
</header> </header>
<div class="body"> <div class="body">
<p class="channel" v-if="p.channel">
<a :href="`${_CH_URL_}/${p.channel.id}`" target="_blank">{{ p.channel.title }}</a>:
</p>
<p v-if="p.cw != null" class="cw"> <p v-if="p.cw != null" class="cw">
<span class="text" v-if="p.cw != ''">{{ p.cw }}</span> <span class="text" v-if="p.cw != ''">{{ p.cw }}</span>
<span class="toggle" @click="showContent = !showContent">{{ showContent ? '隠す' : 'もっと見る' }}</span> <span class="toggle" @click="showContent = !showContent">{{ showContent ? '隠す' : 'もっと見る' }}</span>
...@@ -574,9 +571,6 @@ root(isDark) ...@@ -574,9 +571,6 @@ root(isDark)
.mk-url-preview .mk-url-preview
margin-top 8px margin-top 8px
> .channel
margin 0
> .mk-poll > .mk-poll
font-size 80% font-size 80%
......
<template>
<div class="form">
<input v-model="text" :disabled="wait" @keydown="onKeydown" placeholder="書いて">
</div>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
data() {
return {
text: '',
wait: false
};
},
methods: {
onKeydown(e) {
if (e.which == 10 || e.which == 13) this.post();
},
post() {
this.wait = true;
let reply = null;
if (/^>>([0-9]+) /.test(this.text)) {
const index = this.text.match(/^>>([0-9]+) /)[1];
reply = (this.$parent as any).notes.find(p => p.index.toString() == index);
this.text = this.text.replace(/^>>([0-9]+) /, '');
}
(this as any).api('notes/create', {
text: this.text,
replyId: reply ? reply.id : undefined,
channelId: (this.$parent as any).channel.id
}).then(data => {
this.text = '';
}).catch(err => {
alert('失敗した');
}).then(() => {
this.wait = false;
});
}
}
});
</script>
<style lang="stylus" scoped>
.form
width 100%
height 38px
padding 4px
border-top solid 1px #ddd
> input
padding 0 8px
width 100%
height 100%
font-size 14px
color #55595c
border solid 1px #dadada
border-radius 4px
&:hover
&:focus
border-color #aeaeae
</style>
<template>
<div class="note">
<header>
<a class="index" @click="reply">{{ note.index }}:</a>
<router-link class="name" :to="note.user | userPage" v-user-preview="note.user.id"><b>{{ note.user | userName }}</b></router-link>
<span>ID:<i>{{ note.user | acct }}</i></span>
</header>
<div>
<a v-if="note.reply">&gt;&gt;{{ note.reply.index }}</a>
{{ note.text }}
<div class="media" v-if="note.media">
<a v-for="file in note.media" :href="file.url" target="_blank">
<img :src="`${file.url}?thumbnail&size=512`" :alt="file.name" :title="file.name"/>
</a>
</div>
</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
props: ['note'],
methods: {
reply() {
this.$emit('reply', this.note);
}
}
});
</script>
<style lang="stylus" scoped>
.note
margin 0
padding 0
color #444
> header
position -webkit-sticky
position sticky
z-index 1
top 0
padding 8px 4px 4px 16px
background rgba(255, 255, 255, 0.9)
> .index
margin-right 0.25em
> .name
margin-right 0.5em
color #008000
> div
padding 0 16px 16px 16px
> .media
> a
display inline-block
> img
max-width 100%
vertical-align bottom
</style>
<template>
<div class="channel">
<p v-if="fetching">読み込み中<mk-ellipsis/></p>
<div v-if="!fetching" ref="notes" class="notes">
<p v-if="notes.length == 0">まだ投稿がありません</p>
<x-note class="note" v-for="note in notes.slice().reverse()" :note="note" :key="note.id" @reply="reply"/>
</div>
<x-form class="form" ref="form"/>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import ChannelStream from '../../../common/scripts/streaming/channel';
import XForm from './channel.channel.form.vue';
import XNote from './channel.channel.note.vue';
export default Vue.extend({
components: {
XForm,
XNote
},
props: ['channel'],
data() {
return {
fetching: true,
notes: [],
connection: null
};
},
watch: {
channel() {
this.zap();
}
},
mounted() {
this.zap();
},
beforeDestroy() {
this.disconnect();
},
methods: {
zap() {
this.fetching = true;
(this as any).api('channels/notes', {
channelId: this.channel.id
}).then(notes => {
this.notes = notes;
this.fetching = false;
this.$nextTick(() => {
this.scrollToBottom();
});
this.disconnect();
this.connection = new ChannelStream((this as any).os, this.channel.id);
this.connection.on('note', this.onNote);
});
},
disconnect() {
if (this.connection) {
this.connection.off('note', this.onNote);
this.connection.close();
}
},
onNote(note) {
this.notes.unshift(note);
this.scrollToBottom();
},
scrollToBottom() {
(this.$refs.notes as any).scrollTop = (this.$refs.notes as any).scrollHeight;
},
reply(note) {
(this.$refs.form as any).text = `>>${ note.index } `;
}
}
});
</script>
<style lang="stylus" scoped>
.channel
> p
margin 0
padding 16px
text-align center
color #aaa
> .notes
height calc(100% - 38px)
overflow auto
font-size 0.9em
> .note
border-bottom solid 1px #eee
&:last-child
border-bottom none
> .form
position absolute
left 0
bottom 0
</style>
<template>
<div class="mkw-channel">
<template v-if="!props.compact">
<p class="title">%fa:tv%{{ channel ? channel.title : '%i18n:!@title%' }}</p>
<button @click="settings" title="%i18n:@settings%">%fa:cog%</button>
</template>
<p class="get-started" v-if="props.channel == null">%i18n:@get-started%</p>
<x-channel class="channel" :channel="channel" v-if="channel != null"/>
</div>
</template>
<script lang="ts">
import define from '../../../common/define-widget';
import XChannel from './channel.channel.vue';
export default define({
name: 'server',
props: () => ({
channel: null,
compact: false
})
}).extend({
components: {
XChannel
},
data() {
return {
fetching: true,
channel: null
};
},
mounted() {
if (this.props.channel) {
this.zap();
}
},
methods: {
func() {
this.props.compact = !this.props.compact;
this.save();
},
settings() {
const id = window.prompt('チャンネルID');
if (!id) return;
this.props.channel = id;
this.zap();
},
zap() {
this.fetching = true;
(this as any).api('channels/show', {
channelId: this.props.channel
}).then(channel => {
this.channel = channel;
this.fetching = false;
});
}
}
});
</script>
<style lang="stylus" scoped>
.mkw-channel
background #fff
border solid 1px rgba(#000, 0.075)
border-radius 6px
overflow hidden
> .title
z-index 2
margin 0
padding 0 16px
line-height 42px
font-size 0.9em
font-weight bold
color #888
box-shadow 0 1px rgba(#000, 0.07)
> [data-fa]
margin-right 4px
> button
position absolute
z-index 2
top 0
right 0
padding 0
width 42px
font-size 0.9em
line-height 42px
color #ccc
&:hover
color #aaa
&:active
color #999
> .get-started
margin 0
padding 16px
text-align center
color #aaa
> .channel
height 200px
</style>
...@@ -8,7 +8,6 @@ import wUsers from './users.vue'; ...@@ -8,7 +8,6 @@ import wUsers from './users.vue';
import wPolls from './polls.vue'; import wPolls from './polls.vue';
import wPostForm from './post-form.vue'; import wPostForm from './post-form.vue';
import wMessaging from './messaging.vue'; import wMessaging from './messaging.vue';
import wChannel from './channel.vue';
import wProfile from './profile.vue'; import wProfile from './profile.vue';
Vue.component('mkw-notifications', wNotifications); Vue.component('mkw-notifications', wNotifications);
...@@ -19,5 +18,4 @@ Vue.component('mkw-users', wUsers); ...@@ -19,5 +18,4 @@ Vue.component('mkw-users', wUsers);
Vue.component('mkw-polls', wPolls); Vue.component('mkw-polls', wPolls);
Vue.component('mkw-post-form', wPostForm); Vue.component('mkw-post-form', wPostForm);
Vue.component('mkw-messaging', wMessaging); Vue.component('mkw-messaging', wMessaging);
Vue.component('mkw-channel', wChannel);
Vue.component('mkw-profile', wProfile); Vue.component('mkw-profile', wProfile);
...@@ -32,7 +32,6 @@ ...@@ -32,7 +32,6 @@
</div> </div>
</header> </header>
<div class="body"> <div class="body">
<p class="channel" v-if="p.channel != null"><a target="_blank">{{ p.channel.title }}</a>:</p>
<p v-if="p.cw != null" class="cw"> <p v-if="p.cw != null" class="cw">
<span class="text" v-if="p.cw != ''">{{ p.cw }}</span> <span class="text" v-if="p.cw != ''">{{ p.cw }}</span>
<span class="toggle" @click="showContent = !showContent">{{ showContent ? '隠す' : 'もっと見る' }}</span> <span class="toggle" @click="showContent = !showContent">{{ showContent ? '隠す' : 'もっと見る' }}</span>
...@@ -470,9 +469,6 @@ root(isDark) ...@@ -470,9 +469,6 @@ root(isDark)
.mk-url-preview .mk-url-preview
margin-top 8px margin-top 8px
> .channel
margin 0
> .tags > .tags
margin 4px 0 0 0 margin 4px 0 0 0
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
<option value="photo-stream">フォトストリーム</option> <option value="photo-stream">フォトストリーム</option>
<option value="slideshow">スライドショー</option> <option value="slideshow">スライドショー</option>
<option value="version">バージョン</option> <option value="version">バージョン</option>
<option value="access-log">アクセスログ</option>
<option value="server">サーバー情報</option> <option value="server">サーバー情報</option>
<option value="donation">寄付のお願い</option> <option value="donation">寄付のお願い</option>
<option value="nav">ナビゲーション</option> <option value="nav">ナビゲーション</option>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment