ページにいいねできるように

This commit is contained in:
syuilo
2019-05-17 19:56:47 +09:00
parent d6ccb1725b
commit 380749051d
18 changed files with 489 additions and 191 deletions

View File

@@ -12,6 +12,11 @@
<small>@{{ page.user.username }}</small>
<router-link v-if="$store.getters.isSignedIn && $store.state.i.id === page.userId" :to="`/i/pages/edit/${page.id}`">{{ $t('edit-this-page') }}</router-link>
<router-link :to="`./${page.name}/view-source`">{{ $t('view-source') }}</router-link>
<div class="like">
<button @click="unlike()" v-if="page.isLiked" :title="$t('unlike')"><fa :icon="faHeartS"/></button>
<button @click="like()" v-else :title="$t('like')"><fa :icon="faHeart"/></button>
<span class="count" v-if="page.likedCount > 0">{{ page.likedCount }}</span>
</div>
</footer>
</div>
</template>
@@ -19,8 +24,8 @@
<script lang="ts">
import Vue from 'vue';
import i18n from '../../../../i18n';
import { faICursor, faPlus } from '@fortawesome/free-solid-svg-icons';
import { faSave, faStickyNote } from '@fortawesome/free-regular-svg-icons';
import { faHeart as faHeartS } from '@fortawesome/free-solid-svg-icons';
import { faHeart } from '@fortawesome/free-regular-svg-icons';
import XBlock from './page.block.vue';
import { ASEvaluator } from '../../../../../../misc/aiscript/evaluator';
import { collectPageVars } from '../../../scripts/collect-page-vars';
@@ -76,7 +81,7 @@ export default Vue.extend({
return {
page: null,
script: null,
faPlus, faICursor, faSave, faStickyNote
faHeartS, faHeart
};
},
@@ -103,6 +108,24 @@ export default Vue.extend({
getPageVars() {
return collectPageVars(this.page.content);
},
like() {
this.$root.api('pages/like', {
pageId: this.page.id,
}).then(() => {
this.page.isLiked = true;
this.page.likedCount++;
});
},
unlike() {
this.$root.api('pages/unlike', {
pageId: this.page.id,
}).then(() => {
this.page.isLiked = false;
this.page.likedCount--;
});
}
}
});
</script>
@@ -161,4 +184,7 @@ export default Vue.extend({
> a + a
margin-left 8px
> .like
margin-top 16px
</style>

View File

@@ -0,0 +1,138 @@
<template>
<div>
<ui-container :body-togglable="true">
<template #header><fa :icon="faEdit" fixed-width/>{{ $t('my-pages') }}</template>
<div class="rknalgpo" v-if="!fetching">
<ui-button class="new" @click="create()"><fa :icon="faPlus"/></ui-button>
<sequential-entrance animation="entranceFromTop" delay="25" tag="div" class="pages">
<x-page-preview v-for="page in pages" class="page" :page="page" :key="page.id"/>
</sequential-entrance>
<ui-button v-if="existMore" @click="fetchMore()">{{ $t('@.load-more') }}</ui-button>
</div>
</ui-container>
<ui-container :body-togglable="true">
<template #header><fa :icon="faHeart" fixed-width/>{{ $t('liked-pages') }}</template>
<div class="rknalgpo" v-if="!fetching">
<sequential-entrance animation="entranceFromTop" delay="25" tag="div" class="pages">
<x-page-preview v-for="like in likes" class="page" :page="like.page" :key="like.page.id"/>
</sequential-entrance>
<ui-button v-if="existMoreLikes" @click="fetchMoreLiked()">{{ $t('@.load-more') }}</ui-button>
</div>
</ui-container>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import { faPlus, faEdit } from '@fortawesome/free-solid-svg-icons';
import { faStickyNote, faHeart } from '@fortawesome/free-regular-svg-icons';
import i18n from '../../../i18n';
import Progress from '../../scripts/loading';
import XPagePreview from '../../views/components/page-preview.vue';
export default Vue.extend({
i18n: i18n('pages'),
components: {
XPagePreview
},
data() {
return {
fetching: true,
pages: [],
existMore: false,
moreFetching: false,
likes: [],
existMoreLikes: false,
moreLikesFetching: false,
faStickyNote, faPlus, faEdit, faHeart
};
},
created() {
this.fetch();
},
methods: {
async fetch() {
Progress.start();
this.fetching = true;
const pages = await this.$root.api('i/pages', {
limit: 11
});
if (pages.length == 11) {
this.existMore = true;
pages.pop();
}
const likes = await this.$root.api('i/page-likes', {
limit: 11
});
if (likes.length == 11) {
this.existMoreLikes = true;
likes.pop();
}
this.pages = pages;
this.likes = likes;
this.fetching = false;
Progress.done();
},
fetchMore() {
this.moreFetching = true;
this.$root.api('i/pages', {
limit: 11,
untilId: this.pages[this.pages.length - 1].id
}).then(pages => {
if (pages.length == 11) {
this.existMore = true;
pages.pop();
} else {
this.existMore = false;
}
this.pages = this.pages.concat(pages);
this.moreFetching = false;
});
},
fetchMoreLiked() {
this.moreLikesFetching = true;
this.$root.api('i/page-likes', {
limit: 11,
untilId: this.likes[this.likes.length - 1].id
}).then(pages => {
if (pages.length == 11) {
this.existMoreLikes = true;
pages.pop();
} else {
this.existMoreLikes = false;
}
this.likes = this.likes.concat(pages);
this.moreLikesFetching = false;
});
},
create() {
this.$router.push(`/i/pages/new`);
}
}
});
</script>
<style lang="stylus" scoped>
.rknalgpo
padding 16px
> .new
margin-bottom 16px
> * > .page
margin-bottom 8px
@media (min-width 500px)
> * > .page
margin-bottom 16px
</style>

View File

@@ -156,7 +156,7 @@ init(async (launch, os) => {
{ path: '/explore', name: 'explore', component: () => import('../common/views/pages/explore.vue').then(m => m.default) },
{ path: '/explore/tags/:tag', name: 'explore-tag', props: true, component: () => import('../common/views/pages/explore.vue').then(m => m.default) },
{ path: '/i/favorites', component: () => import('./views/home/favorites.vue').then(m => m.default) },
{ path: '/i/pages', component: () => import('./views/home/pages.vue').then(m => m.default) },
{ path: '/i/pages', component: () => import('../common/views/pages/pages.vue').then(m => m.default) },
]},
{ path: '/@:user/pages/:page', props: true, component: () => import('./views/pages/page.vue').then(m => m.default) },
{ path: '/@:user/pages/:pageName/view-source', props: true, component: () => import('./views/pages/page-editor.vue').then(m => m.default) },

View File

@@ -1,92 +0,0 @@
<template>
<div class="rknalgpo" v-if="!fetching">
<ui-button @click="create()"><fa :icon="faPlus"/></ui-button>
<sequential-entrance animation="entranceFromTop" delay="25">
<template v-for="page in pages">
<x-page-preview class="page" :page="page" :key="page.id"/>
</template>
</sequential-entrance>
<ui-button v-if="existMore" @click="fetchMore()">{{ $t('@.load-more') }}</ui-button>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../../i18n';
import Progress from '../../../common/scripts/loading';
import { faPlus } from '@fortawesome/free-solid-svg-icons';
import { faStickyNote } from '@fortawesome/free-regular-svg-icons';
import XPagePreview from '../../../common/views/components/page-preview.vue';
export default Vue.extend({
i18n: i18n(),
components: {
XPagePreview
},
data() {
return {
fetching: true,
pages: [],
existMore: false,
moreFetching: false,
faStickyNote, faPlus
};
},
created() {
this.fetch();
},
methods: {
fetch() {
Progress.start();
this.fetching = true;
this.$root.api('i/pages', {
limit: 11
}).then(pages => {
if (pages.length == 11) {
this.existMore = true;
pages.pop();
}
this.pages = pages;
this.fetching = false;
Progress.done();
});
},
fetchMore() {
this.moreFetching = true;
this.$root.api('i/pages', {
limit: 11,
untilId: this.pages[this.pages.length - 1].id
}).then(pages => {
if (pages.length == 11) {
this.existMore = true;
pages.pop();
} else {
this.existMore = false;
}
this.pages = this.pages.concat(pages);
this.moreFetching = false;
});
},
create() {
this.$router.push(`/i/pages/new`);
}
}
});
</script>
<style lang="stylus" scoped>
.rknalgpo
margin 0 auto
> * > .page
margin-bottom 8px
@media (min-width 500px)
> * > .page
margin-bottom 16px
</style>

View File

@@ -3,92 +3,27 @@
<template #header><span style="margin-right:4px;"><fa :icon="faStickyNote"/></span>{{ $t('@.pages') }}</template>
<main>
<ui-button @click="create()"><fa :icon="faPlus"/></ui-button>
<sequential-entrance animation="entranceFromTop" delay="25">
<template v-for="page in pages">
<x-page-preview class="page" :page="page" :key="page.id"/>
</template>
</sequential-entrance>
<ui-button v-if="existMore" @click="fetchMore()">{{ $t('@.load-more') }}</ui-button>
<x-pages v-bind="$attrs"/>
</main>
</mk-ui>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../../i18n';
import Progress from '../../../common/scripts/loading';
import { faPlus } from '@fortawesome/free-solid-svg-icons';
import { faStickyNote } from '@fortawesome/free-regular-svg-icons';
import XPagePreview from '../../../common/views/components/page-preview.vue';
import { faHashtag } from '@fortawesome/free-solid-svg-icons';
import XPages from '../../../common/views/pages/pages.vue';
export default Vue.extend({
i18n: i18n(),
i18n: i18n(''),
components: {
XPagePreview
XPages
},
data() {
return {
fetching: true,
pages: [],
existMore: false,
moreFetching: false,
faStickyNote, faPlus
faHashtag
};
},
created() {
this.fetch();
},
methods: {
fetch() {
Progress.start();
this.fetching = true;
this.$root.api('i/pages', {
limit: 11
}).then(pages => {
if (pages.length == 11) {
this.existMore = true;
pages.pop();
}
this.pages = pages;
this.fetching = false;
Progress.done();
});
},
fetchMore() {
this.moreFetching = true;
this.$root.api('i/pages', {
limit: 11,
untilId: this.pages[this.pages.length - 1].id
}).then(pages => {
if (pages.length == 11) {
this.existMore = true;
pages.pop();
} else {
this.existMore = false;
}
this.pages = this.pages.concat(pages);
this.moreFetching = false;
});
},
create() {
this.$router.push(`/i/pages/new`);
}
}
});
</script>
<style lang="stylus" scoped>
main
> * > .page
margin-bottom 8px
@media (min-width 500px)
> * > .page
margin-bottom 16px
</style>