mirror of
https://github.com/ipfs/ipfs-blog.git
synced 2026-03-28 17:32:37 +01:00
fix: author filter & visual updates
This commit is contained in:
@@ -121,6 +121,7 @@ module.exports = {
|
||||
feeds: {
|
||||
rss2: {
|
||||
enable: true,
|
||||
file_name: 'index.xml',
|
||||
},
|
||||
atom1: {
|
||||
enable: false,
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<SVGIcon
|
||||
class="w-6 h-6 opacity-50 hover:opacity-100 transition transition-opacity duration-300 ease-in-out"
|
||||
class="w-6 h-6 opacity-50 hover:opacity-100 fill-current text-blueGreen transition transition-opacity duration-300 ease-in-out"
|
||||
:name="link.icon"
|
||||
:title="link.text"
|
||||
/>
|
||||
@@ -20,7 +20,7 @@
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<SVGIcon
|
||||
class="w-6 h-6 opacity-50 hover:opacity-100 transition transition-opacity duration-300 ease-in-out"
|
||||
class="w-6 h-6 color-green fill-current text-blueGreen opacity-50 hover:opacity-100 transition transition-opacity duration-300 ease-in-out"
|
||||
name="rss"
|
||||
title="rss"
|
||||
/>
|
||||
|
||||
@@ -3,36 +3,39 @@
|
||||
v-if="
|
||||
activeTags.length ||
|
||||
searchedText.length ||
|
||||
resolvedActiveCategory !== 'all types'
|
||||
resolvedActiveCategory !== 'all types' ||
|
||||
activeAuthor
|
||||
"
|
||||
class="border border-opacity-10 flex items-center rounded px-1 py-2"
|
||||
class="border-2 border-plBlack border-opacity-10 flex items-center rounded px-1 py-2"
|
||||
>
|
||||
<span class="p-1">
|
||||
Displaying
|
||||
<strong
|
||||
>{{ numberOfPosts }} result{{ numberOfPosts > 1 ? 's' : '' }}</strong
|
||||
>{{ numberOfPosts }} result{{ numberOfPosts !== 1 ? 's' : '' }}</strong
|
||||
>
|
||||
(newest first) of {{ resolvedActiveCategory }}
|
||||
<span v-if="searchedText.length">
|
||||
for
|
||||
<span v-for="text in searchedText" :key="text" class=""
|
||||
>"{{ text }}"
|
||||
</span>
|
||||
</span>
|
||||
<span v-if="activeAuthor"> by {{ activeAuthor }} </span>
|
||||
<span v-if="searchedText.length"> for {{ resolvedSearchedText }} </span>
|
||||
<span v-if="activeTags.length"
|
||||
>with tag{{ activeTags.length > 1 ? 's' : '' }}:</span
|
||||
>
|
||||
</span>
|
||||
<ul class="tags flex" itemprop="keywords">
|
||||
<ul class="tags flex items-center" itemprop="keywords">
|
||||
<li
|
||||
v-for="tag in activeTags"
|
||||
:key="tag"
|
||||
class="bg-gray-pale py-1 px-2 ml-1 rounded cursor-pointer hover:underline post-tag"
|
||||
@click="tagClick(tag)"
|
||||
class="multiselect__tag active-tag"
|
||||
>
|
||||
<span class="text-blueGreen">x</span> {{ tag }}
|
||||
<span>#{{ tag }}</span
|
||||
><i class="multiselect__tag-icon" @click="tagClick(tag)"></i>
|
||||
</li>
|
||||
</ul>
|
||||
<div
|
||||
class="p-1 ml-auto opacity-50 hover:opacity-100 text-blueGreen transition transition-opacity duration-300 ease-in-out cursor-pointer"
|
||||
@click="handleClear()"
|
||||
>
|
||||
✕
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -48,10 +51,18 @@ export default {
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
...mapState('appState', ['activeCategory', 'activeTags', 'searchedText']),
|
||||
...mapState('appState', [
|
||||
'activeCategory',
|
||||
'activeTags',
|
||||
'searchedText',
|
||||
'activeAuthor',
|
||||
]),
|
||||
resolvedActiveCategory() {
|
||||
return this.activeCategory ? `type "${this.activeCategory}"` : 'all types'
|
||||
},
|
||||
resolvedSearchedText() {
|
||||
return `"${this.searchedText.join(' ')}"`
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
tagClick(tagToRemove) {
|
||||
@@ -59,6 +70,15 @@ export default {
|
||||
|
||||
this.$store.commit('appState/setActiveTags', newTags)
|
||||
},
|
||||
handleClear() {
|
||||
this.$store.commit('appState/clearFilters')
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.active-tag {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
</UnstyledLink>
|
||||
<div>
|
||||
<PostMeta
|
||||
:author="frontmatter.author"
|
||||
category="newslink"
|
||||
:date="frontmatter.date"
|
||||
:tags="frontmatter.tags"
|
||||
class="type-p4 text-primary"
|
||||
|
||||
@@ -6,23 +6,33 @@
|
||||
itemscope
|
||||
class="flex items-center"
|
||||
>
|
||||
<Avatar
|
||||
v-if="avatar || svgIcon || avatarUrl"
|
||||
v-bind="$props"
|
||||
class="mr-2 bg-plBlack"
|
||||
/>
|
||||
<span itemprop="name" class="whitespace-no-wrap">{{ name }}</span>
|
||||
<span
|
||||
itemprop="name"
|
||||
class="whitespace-no-wrap hover:text-blueGreen hover:underline cursor-pointer"
|
||||
@click="handleAuthorClick()"
|
||||
>{{ name }}</span
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Avatar from '@theme/components/base/Avatar'
|
||||
import { mapState } from 'vuex'
|
||||
import Author from '@theme/components/mixins/Author'
|
||||
|
||||
export default {
|
||||
name: 'PostAuthor',
|
||||
components: { Avatar },
|
||||
components: {},
|
||||
mixins: [Author],
|
||||
computed: {
|
||||
...mapState('appState', ['activeAuthor']),
|
||||
},
|
||||
methods: {
|
||||
handleAuthorClick() {
|
||||
if (!this.activeAuthor !== this.name) {
|
||||
this.$store.commit('appState/setActiveAuthor', this.name)
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -6,7 +6,12 @@
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 pt-4">
|
||||
<div class="flex flex-col">
|
||||
<h1 class="type-h1">{{ title }}</h1>
|
||||
<PostAuthor v-if="author && author.name" v-bind="author" />
|
||||
<router-link
|
||||
v-if="author && author.name"
|
||||
:to="{ path: '/', query: { author: author.name } }"
|
||||
>
|
||||
<PostAuthor v-bind="author" />
|
||||
</router-link>
|
||||
<time
|
||||
class="italic opacity-50"
|
||||
pubdate
|
||||
|
||||
@@ -11,8 +11,18 @@
|
||||
{{ resolvedDate }}
|
||||
</time>
|
||||
</div>
|
||||
<ul v-if="resolvedTags.length" class="tags flex mt-1" itemprop="keywords">
|
||||
<PostTag v-for="tag in resolvedTags" :key="tag" :tag="tag" />
|
||||
<ul
|
||||
v-if="resolvedTags.length"
|
||||
class="tags flex flex-wrap"
|
||||
itemprop="keywords"
|
||||
>
|
||||
<li
|
||||
v-if="category"
|
||||
class="p-1 mr-1 bg-white text-blueGreen hover:underline rounded cursor-pointer mt-1"
|
||||
>
|
||||
<div @click="handleCatClick">{{ category }}</div>
|
||||
</li>
|
||||
<PostTag v-for="tag in resolvedTags" :key="tag" class="mt-1" :tag="tag" />
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
@@ -41,6 +51,10 @@ export default {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
category: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
resolvedDate() {
|
||||
@@ -57,5 +71,10 @@ export default {
|
||||
.filter((tag) => tag)
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleCatClick() {
|
||||
this.$store.commit('appState/setActiveCategory', this.category)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -3,11 +3,9 @@
|
||||
class="post-tag p-1 mr-1 bg-white text-blueGreen hover:underline rounded cursor-pointer"
|
||||
>
|
||||
<router-link v-if="link" :to="{ path: '/', query: { tags: tag } }">
|
||||
{{ tag }}
|
||||
#{{ tag }}
|
||||
</router-link>
|
||||
<div v-else @click="handleTagClick">
|
||||
{{ tag }}
|
||||
</div>
|
||||
<div v-else @click="handleTagClick">#{{ tag }}</div>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -27,12 +27,15 @@
|
||||
</div>
|
||||
<div class="pt-1 pb-4 px-4 flex flex-grow flex-col">
|
||||
<router-link :to="path">
|
||||
<h1 class="type-h5 font-bold text-primary hover:underline">
|
||||
<h1
|
||||
class="type-h5 font-bold text-primary hover:underline overflow-ellipsis overflow-hidden"
|
||||
>
|
||||
{{ title }}
|
||||
</h1>
|
||||
</router-link>
|
||||
<div>
|
||||
<PostMeta
|
||||
category="Blog Post"
|
||||
:author="frontmatter.author"
|
||||
:date="frontmatter.date"
|
||||
:tags="frontmatter.tags"
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
></multiselect>
|
||||
|
||||
<button
|
||||
class="p-2 text-white bg-blueGreen rounded opacity-75 hover:opacity-75"
|
||||
class="p-2 text-white bg-blueGreen rounded opacity-75 hover:opacity-100 transition transition-opacity duration-300 ease-in-out"
|
||||
@click="handleSearch"
|
||||
>
|
||||
Search
|
||||
@@ -98,4 +98,8 @@ export default {
|
||||
.multiselect__option--highlight::after {
|
||||
@apply bg-blueGreen;
|
||||
}
|
||||
|
||||
.multiselect__placeholder {
|
||||
font-size: 16px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -84,7 +84,12 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState('appState', ['activeCategory', 'activeTags', 'searchedText']),
|
||||
...mapState('appState', [
|
||||
'activeCategory',
|
||||
'activeTags',
|
||||
'searchedText',
|
||||
'activeAuthor',
|
||||
]),
|
||||
tags() {
|
||||
return getTags(this.publicPages)
|
||||
},
|
||||
@@ -98,7 +103,8 @@ export default {
|
||||
page,
|
||||
this.activeTags,
|
||||
this.searchedText,
|
||||
this.activeCategory
|
||||
this.activeCategory,
|
||||
this.activeAuthor
|
||||
),
|
||||
]
|
||||
return
|
||||
@@ -108,8 +114,10 @@ export default {
|
||||
!checkItem({
|
||||
postType: defaultCategory,
|
||||
tags: page.frontmatter.tags,
|
||||
author: page.frontmatter.author,
|
||||
title: page.frontmatter.title,
|
||||
activeTags: this.activeTags,
|
||||
activeAuthor: this.activeAuthor,
|
||||
searchedText: this.searchedText,
|
||||
activeCategory: this.activeCategory,
|
||||
})
|
||||
@@ -137,15 +145,12 @@ export default {
|
||||
? this.publicPages
|
||||
: this.publicPages.slice(0, this.numberOfPagesToShow)
|
||||
},
|
||||
queryProptertyWatchlist() {
|
||||
return `${this.activeCategory}|${this.activeTags}|${this.searchedText}|${this.activeAuthor}`
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
activeCategory() {
|
||||
this.updateQuery()
|
||||
},
|
||||
activeTags() {
|
||||
this.updateQuery()
|
||||
},
|
||||
searchedText() {
|
||||
queryProptertyWatchlist() {
|
||||
this.updateQuery()
|
||||
},
|
||||
},
|
||||
@@ -153,16 +158,20 @@ export default {
|
||||
const queryTags = this.$route.query.tags
|
||||
const queryCategory = this.$route.query.category
|
||||
const queryText = this.$route.query.search
|
||||
const queryAuthor = this.$route.query.author
|
||||
|
||||
if (queryTags && !this.activeTags.length) {
|
||||
this.$store.commit('appState/setActiveTags', queryTags.split(','))
|
||||
}
|
||||
if (queryCategory && !this.activeTags.length) {
|
||||
if (queryCategory) {
|
||||
this.$store.commit('appState/setActiveCategory', queryCategory)
|
||||
}
|
||||
if (queryText && !this.activeTags.length) {
|
||||
if (queryText && !this.searchedText.length) {
|
||||
this.$store.commit('appState/setSearchedText', queryText.split(','))
|
||||
}
|
||||
if (queryAuthor) {
|
||||
this.$store.commit('appState/setActiveAuthor', queryAuthor)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateQuery() {
|
||||
@@ -171,6 +180,7 @@ export default {
|
||||
tags: this.activeTags.join(','),
|
||||
search: this.searchedText.join(','),
|
||||
category: this.activeCategory,
|
||||
author: this.activeAuthor,
|
||||
}
|
||||
this.$router.replace({ query: newQuery }).catch(() => {})
|
||||
},
|
||||
|
||||
@@ -9,6 +9,7 @@ const appState = {
|
||||
activeTags: [],
|
||||
searchedText: [],
|
||||
activeCategory: null,
|
||||
activeAuthor: null,
|
||||
},
|
||||
mutations: {
|
||||
toggleMobileNav: (state, data) => {
|
||||
@@ -29,6 +30,15 @@ const appState = {
|
||||
setActiveCategory: (state, data) => {
|
||||
Vue.set(state, 'activeCategory', data)
|
||||
},
|
||||
setActiveAuthor: (state, data) => {
|
||||
Vue.set(state, 'activeAuthor', data)
|
||||
},
|
||||
clearFilters: (state) => {
|
||||
Vue.set(state, 'activeTags', [])
|
||||
Vue.set(state, 'searchedText', [])
|
||||
Vue.set(state, 'activeCategory', null)
|
||||
Vue.set(state, 'activeAuthor', null)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" fill="#000" height="24" viewBox="-2 -2 34 34" class="pb2 ml2" data-v-5480b51c=""><path d="M6.503 20.752c0 1.794-1.456 3.248-3.251 3.248-1.796 0-3.252-1.454-3.252-3.248 0-1.794 1.456-3.248 3.252-3.248 1.795.001 3.251 1.454 3.251 3.248zm-6.503-12.572v4.811c6.05.062 10.96 4.966 11.022 11.009h4.817c-.062-8.71-7.118-15.758-15.839-15.82zm0-3.368c10.58.046 19.152 8.594 19.183 19.188h4.817c-.03-13.231-10.755-23.954-24-24v4.812z" data-v-5480b51c=""></path></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="-1 -1 34 34" class="pb2 ml2" data-v-5480b51c=""><path d="M6.503 20.752c0 1.794-1.456 3.248-3.251 3.248-1.796 0-3.252-1.454-3.252-3.248 0-1.794 1.456-3.248 3.252-3.248 1.795.001 3.251 1.454 3.251 3.248zm-6.503-12.572v4.811c6.05.062 10.96 4.966 11.022 11.009h4.817c-.062-8.71-7.118-15.758-15.839-15.82zm0-3.368c10.58.046 19.152 8.594 19.183 19.188h4.817c-.03-13.231-10.755-23.954-24-24v4.812z" data-v-5480b51c=""></path></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 509 B After Width: | Height: | Size: 497 B |
@@ -1 +1 @@
|
||||
<svg height="34" viewBox="0 0 34 34" width="34" xmlns="http://www.w3.org/2000/svg"><path d="m13.0553 25.6358c8.0155 0 12.4015-6.647 12.4015-12.4015 0-.187 0-.374-.0085-.561.85-.612 1.5895-1.3855 2.176-2.261-.782.3485-1.6235.578-2.5075.6885.901-.5355 1.5895-1.39403 1.921-2.41403-.8415.5015-1.7765.8585-2.771 1.054-.799-.85-1.9295-1.377-3.179-1.377-2.4055 0-4.3605 1.95503-4.3605 4.36053 0 .34.0425.6715.1105.9945-3.621-.1785-6.834-1.921-8.98449-4.55603-.374.646-.5865 1.39403-.5865 2.19303 0 1.513.7735 2.8475 1.938 3.6295-.714-.0255-1.3855-.221-1.972-.544v.0595c0 2.108 1.5045 3.876 3.49349 4.2755-.3655.102-.74799.153-1.14749.153-.2805 0-.5525-.0255-.816-.0765.5525 1.734 2.16749 2.992 4.07149 3.026-1.496 1.173-3.37449 1.87-5.41449 1.87-.3485 0-.697-.017-1.037-.0595 1.921 1.224 4.21599 1.9465 6.67249 1.9465z"/></svg>
|
||||
<svg height="34" viewBox="4 4 24 24" width="34" xmlns="http://www.w3.org/2000/svg"><path d="m13.0553 25.6358c8.0155 0 12.4015-6.647 12.4015-12.4015 0-.187 0-.374-.0085-.561.85-.612 1.5895-1.3855 2.176-2.261-.782.3485-1.6235.578-2.5075.6885.901-.5355 1.5895-1.39403 1.921-2.41403-.8415.5015-1.7765.8585-2.771 1.054-.799-.85-1.9295-1.377-3.179-1.377-2.4055 0-4.3605 1.95503-4.3605 4.36053 0 .34.0425.6715.1105.9945-3.621-.1785-6.834-1.921-8.98449-4.55603-.374.646-.5865 1.39403-.5865 2.19303 0 1.513.7735 2.8475 1.938 3.6295-.714-.0255-1.3855-.221-1.972-.544v.0595c0 2.108 1.5045 3.876 3.49349 4.2755-.3655.102-.74799.153-1.14749.153-.2805 0-.5525-.0255-.816-.0765.5525 1.734 2.16749 2.992 4.07149 3.026-1.496 1.173-3.37449 1.87-5.41449 1.87-.3485 0-.697-.017-1.037-.0595 1.921 1.224 4.21599 1.9465 6.67249 1.9465z"/></svg>
|
||||
|
Before Width: | Height: | Size: 821 B After Width: | Height: | Size: 821 B |
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 35 35"><defs/><path d="M25.949 18.022c0 1.395-.175 2.787-.175 2.787s-.174 1.133-.696 1.656c-.61.696-1.395.696-1.742.696-2.352.175-5.923.175-5.923.175s-4.442 0-5.748-.175c-.349-.086-1.22-.086-1.916-.696-.523-.523-.697-1.656-.697-1.656s-.174-1.392-.174-2.787v-1.306c0-1.394.174-2.787.174-2.787s.174-1.132.697-1.655c.61-.696 1.393-.696 1.741-.696 2.352-.175 5.923-.175 5.923-.175s3.571 0 5.923.175c.347 0 1.045 0 1.742.696.522.523.696 1.655.696 1.655s.175 1.393.175 2.787v1.306zM15.67 19.591l4.616-2.352-4.616-2.44v4.792zm-11.67-2.178c0 7.404 6.009 13.413 13.412 13.413 7.403 0 13.413-6.01 13.413-13.413C30.913 10.009 24.816 4 17.413 4 10.01 4 4 10.01 4 17.413z"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="2 2 32 32"><defs/><path d="M25.949 18.022c0 1.395-.175 2.787-.175 2.787s-.174 1.133-.696 1.656c-.61.696-1.395.696-1.742.696-2.352.175-5.923.175-5.923.175s-4.442 0-5.748-.175c-.349-.086-1.22-.086-1.916-.696-.523-.523-.697-1.656-.697-1.656s-.174-1.392-.174-2.787v-1.306c0-1.394.174-2.787.174-2.787s.174-1.132.697-1.655c.61-.696 1.393-.696 1.741-.696 2.352-.175 5.923-.175 5.923-.175s3.571 0 5.923.175c.347 0 1.045 0 1.742.696.522.523.696 1.655.696 1.655s.175 1.393.175 2.787v1.306zM15.67 19.591l4.616-2.352-4.616-2.44v4.792zm-11.67-2.178c0 7.404 6.009 13.413 13.412 13.413 7.403 0 13.413-6.01 13.413-13.413C30.913 10.009 24.816 4 17.413 4 10.01 4 4 10.01 4 17.413z"/></svg>
|
||||
|
Before Width: | Height: | Size: 720 B After Width: | Height: | Size: 720 B |
@@ -72,6 +72,9 @@ const theme = {
|
||||
'gray-dark': '#707175',
|
||||
'gray-default': '#d1d1d6',
|
||||
},
|
||||
borderOpacity: {
|
||||
10: '0.1',
|
||||
},
|
||||
textColor: {
|
||||
primary: '#16161F',
|
||||
},
|
||||
|
||||
@@ -2,14 +2,20 @@ export const checkItem = ({
|
||||
postType,
|
||||
tags,
|
||||
title,
|
||||
author = {},
|
||||
activeTags = [],
|
||||
searchedText = [],
|
||||
activeCategory = '',
|
||||
activeAuthor = '',
|
||||
}) => {
|
||||
if (activeCategory && decodeURI(activeCategory) !== postType) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (activeAuthor && decodeURI(activeAuthor) !== author.name) {
|
||||
return false
|
||||
}
|
||||
|
||||
for (let i = 0; i < activeTags.length; i++) {
|
||||
if (!tags || !tags.includes(activeTags[i])) {
|
||||
return false
|
||||
@@ -31,7 +37,8 @@ export const parseProtectedPost = (
|
||||
post,
|
||||
activeTags = [],
|
||||
searchedText = [],
|
||||
activeCategory = ''
|
||||
activeCategory = '',
|
||||
activeAuthor = ''
|
||||
) => {
|
||||
if (!post.frontmatter.data) {
|
||||
return []
|
||||
@@ -45,26 +52,30 @@ export const parseProtectedPost = (
|
||||
postType: post.frontmatter.type,
|
||||
tags: item.tags,
|
||||
title: item.title,
|
||||
author: item.author,
|
||||
activeTags,
|
||||
searchedText,
|
||||
activeCategory,
|
||||
activeAuthor,
|
||||
})
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
||||
result.push({
|
||||
...item,
|
||||
category: post.frontmatter.type,
|
||||
type: post.frontmatter.type,
|
||||
date: item.date,
|
||||
title: item.title,
|
||||
author: { name: item.author },
|
||||
path: item.path,
|
||||
...item,
|
||||
frontmatter: {
|
||||
...item,
|
||||
date: item.date,
|
||||
title: item.title,
|
||||
author: { name: item.author },
|
||||
path: item.path,
|
||||
...item,
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user