From 18ac056d159d2c74d83ab09f7a973b4d7e8f80b8 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Mon, 14 Dec 2020 15:08:38 +0000 Subject: [PATCH] feat: blog card iterative load --- package-lock.json | 5 + package.json | 1 + src/.vuepress/config.js | 28 +- src/.vuepress/theme/components/Footer.vue | 245 +++--------------- .../theme/components/FooterLegal.vue | 51 ++++ src/.vuepress/theme/components/Nav.vue | 2 +- .../theme/components/RSSSubscription.vue | 42 ++- .../theme/components/blog/ActiveTags.vue | 11 +- .../theme/components/blog/LinksAndSocial.vue | 4 +- .../blog/SearchCategoriesAndTags.vue | 4 + .../theme/components/blog/SortAndFilter.vue | 10 +- src/.vuepress/theme/enhanceApp.js | 2 + src/.vuepress/theme/layouts/Blog.vue | 75 +++++- src/.vuepress/theme/svg-icon/github-icon.svg | 1 + src/.vuepress/theme/svg-icon/rss.svg | 7 +- src/.vuepress/theme/tailwind.config.js | 2 +- src/.vuepress/theme/util/blogUtils.js | 8 +- src/_blog/newslinks/README.md | 2 - 18 files changed, 247 insertions(+), 253 deletions(-) create mode 100644 src/.vuepress/theme/components/FooterLegal.vue create mode 100644 src/.vuepress/theme/svg-icon/github-icon.svg diff --git a/package-lock.json b/package-lock.json index c9cc54d7..7ca38e7f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18379,6 +18379,11 @@ "resolved": "https://registry.npmjs.org/vue-multiselect/-/vue-multiselect-2.1.6.tgz", "integrity": "sha512-s7jmZPlm9FeueJg1RwJtnE9KNPtME/7C8uRWSfp9/yEN4M8XcS/d+bddoyVwVnvFyRh9msFo0HWeW0vTL8Qv+w==" }, + "vue-observe-visibility": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/vue-observe-visibility/-/vue-observe-visibility-0.4.6.tgz", + "integrity": "sha512-xo0CEVdkjSjhJoDdLSvoZoQrw/H2BlzB5jrCBKGZNXN2zdZgMuZ9BKrxXDjNP2AxlcCoKc8OahI3F3r3JGLv2Q==" + }, "vue-property-decorator": { "version": "8.5.1", "resolved": "https://registry.npmjs.org/vue-property-decorator/-/vue-property-decorator-8.5.1.tgz", diff --git a/package.json b/package.json index d258f59d..8987b66e 100644 --- a/package.json +++ b/package.json @@ -74,6 +74,7 @@ "v-scroll-lock": "^1.3.1", "vue-mq": "^1.0.1", "vue-multiselect": "^2.1.6", + "vue-observe-visibility": "^0.4.6", "vuepress-plugin-img-lazy": "^1.0.4", "vuex": "^3.5.1" } diff --git a/src/.vuepress/config.js b/src/.vuepress/config.js index 30cad6e5..9ac1378c 100644 --- a/src/.vuepress/config.js +++ b/src/.vuepress/config.js @@ -35,9 +35,19 @@ module.exports = { themeConfig: { dateFormat: 'DD MMMM YYYY', socialLinks: [ + { + text: 'Github', + link: 'https://github.com/ipfs', + icon: 'github-icon', + }, + { + text: 'YouTube', + link: 'https://www.youtube.com/channel/UCdjsUXJ3QawK4O5L1kqqsew', + icon: 'youtube-icon', + }, { text: 'Twitter', - link: 'https://twitter.com/protocollabs', + link: 'http://twitter.com/ipfs', icon: 'twitter-icon', }, { @@ -45,13 +55,21 @@ module.exports = { link: 'https://www.linkedin.com/company/protocollabs/', icon: 'linkedin-icon', }, + ], + footerLinks: [ + { text: 'Blog & News', link: '/' }, + { text: 'Press', link: 'https://ipfs.io/media/' }, { - text: 'YouTube', - link: 'https://www.youtube.com/ProtocolLabs/', - icon: 'youtube-icon', + text: 'Code of Conduct', + link: + 'https://github.com/ipfs/community/blob/master/code-of-conduct.md', + }, + { + text: 'Security', + link: + 'https://github.com/ipfs/community/blob/master/CONTRIBUTING.md#security-issues', }, ], - footerLinks: [], footerLegal: '', headerLinks: [ { text: 'About', link: 'https://ipfs.io/#why' }, diff --git a/src/.vuepress/theme/components/Footer.vue b/src/.vuepress/theme/components/Footer.vue index 0ca06dfd..5cc03ffc 100644 --- a/src/.vuepress/theme/components/Footer.vue +++ b/src/.vuepress/theme/components/Footer.vue @@ -2,224 +2,55 @@ + diff --git a/src/.vuepress/theme/components/Nav.vue b/src/.vuepress/theme/components/Nav.vue index 9f464c69..7bce85be 100644 --- a/src/.vuepress/theme/components/Nav.vue +++ b/src/.vuepress/theme/components/Nav.vue @@ -16,7 +16,7 @@
+ + + @@ -18,15 +32,19 @@ import SVGIcon from '@theme/components/base/SVGIcon' export default { name: 'RSSSubscription', components: { SVGIcon }, + data: () => ({ + socialLinks: [ + { + text: 'Twitter', + link: 'http://twitter.com/ipfs', + icon: 'twitter-icon', + }, + { + text: 'YouTube', + link: 'https://www.youtube.com/channel/UCdjsUXJ3QawK4O5L1kqqsew', + icon: 'youtube-icon', + }, + ], + }), } - - diff --git a/src/.vuepress/theme/components/blog/ActiveTags.vue b/src/.vuepress/theme/components/blog/ActiveTags.vue index 67978b12..548953db 100644 --- a/src/.vuepress/theme/components/blog/ActiveTags.vue +++ b/src/.vuepress/theme/components/blog/ActiveTags.vue @@ -1,6 +1,8 @@ diff --git a/src/.vuepress/theme/components/blog/SearchCategoriesAndTags.vue b/src/.vuepress/theme/components/blog/SearchCategoriesAndTags.vue index ca7d313e..6e600d30 100644 --- a/src/.vuepress/theme/components/blog/SearchCategoriesAndTags.vue +++ b/src/.vuepress/theme/components/blog/SearchCategoriesAndTags.vue @@ -65,6 +65,10 @@ export default { ...this.$route.query, tags, search: texts, + category: + this.selectedCat === this.categories[0] + ? undefined + : this.selectedCat, } this.$router.replace({ path: currentPath, query: newQuery }) diff --git a/src/.vuepress/theme/components/blog/SortAndFilter.vue b/src/.vuepress/theme/components/blog/SortAndFilter.vue index cf517d2c..7a37eb9a 100644 --- a/src/.vuepress/theme/components/blog/SortAndFilter.vue +++ b/src/.vuepress/theme/components/blog/SortAndFilter.vue @@ -1,7 +1,11 @@ @@ -19,6 +23,10 @@ export default { SearchCategoriesAndTags, }, props: { + categories: { + type: Array, + required: true, + }, tags: { type: Array, required: true, diff --git a/src/.vuepress/theme/enhanceApp.js b/src/.vuepress/theme/enhanceApp.js index fa540149..d7b4b684 100644 --- a/src/.vuepress/theme/enhanceApp.js +++ b/src/.vuepress/theme/enhanceApp.js @@ -4,6 +4,7 @@ import { createStore } from '@theme/store/store' import VScrollLock from 'v-scroll-lock' import VueMq from 'vue-mq' import { VLazyImagePlugin } from 'v-lazy-image' +import VueObserveVisibility from 'vue-observe-visibility' import Transition from '@theme/components/directives/Transition.js' @@ -28,6 +29,7 @@ export default ({ Vue, router, siteData }) => { Vue.use(VScrollLock) Vue.use(VueMq, { breakpoints }) Vue.use(VLazyImagePlugin) + Vue.use(VueObserveVisibility) Vue.directive(Transition.name, Transition.directive) diff --git a/src/.vuepress/theme/layouts/Blog.vue b/src/.vuepress/theme/layouts/Blog.vue index 77256533..9718de98 100644 --- a/src/.vuepress/theme/layouts/Blog.vue +++ b/src/.vuepress/theme/layouts/Blog.vue @@ -13,27 +13,38 @@
- +
-
- Prev - Next +
+
@@ -47,7 +58,8 @@ import Breadcrumbs from '@theme/components/Breadcrumbs' import { getTags } from '@theme/util/tagUtils' import { parseProtectedPost } from '@theme/util/blogUtils' -const protectedCardTypes = ['newslinks'] +const protectedCardTypes = ['newslink'] +const defaultCategory = 'Blog Post' export default { name: 'BlogIndex', @@ -59,16 +71,21 @@ export default { }, data: function () { return { - numberOfPagesToShow: 20, + categories: ['All Content', defaultCategory, ...protectedCardTypes], + numberOfPagesToShow: 21, + infiniteScroll: false, delayValues: [0, 0.15, 0.3], tags: [], breadcrumbs: [ - { title: 'Home', link: 'https://blog.ipfs.io/', external: true }, + { title: 'Home', link: 'https://ipfs.io/', external: true }, { title: 'Blog & News' }, ], } }, computed: { + activeCategory() { + return this.$route.query.category + }, activeTags() { const queryTags = this.$route.query.tags return queryTags ? queryTags.split(',') : [] @@ -80,14 +97,26 @@ export default { publicPages: function () { let result = [] this.$pagination.pages.forEach((page) => { - if (protectedCardTypes.includes(page.frontmatter.url)) { + if (protectedCardTypes.includes(page.frontmatter.type)) { result = [ ...result, - ...parseProtectedPost(page, this.activeTags, this.searchedText), + ...parseProtectedPost( + page, + this.activeTags, + this.searchedText, + this.activeCategory + ), ] return } + if ( + this.activeCategory && + decodeURI(this.activeCategory) !== defaultCategory + ) { + return false + } + for (let i = 0; i < this.activeTags.length; i++) { if ( !page.frontmatter.tags || @@ -111,17 +140,35 @@ export default { page.frontmatter && (page.frontmatter.sitemap ? !page.frontmatter.sitemap.exclude : true) ) { - result.push(page) + result.push({ + ...page, + category: defaultCategory, + }) } }) return result }, + pagesToShow() { + return this.numberOfPagesToShow > this.publicPages.length + ? this.publicPages + : this.publicPages.slice(0, this.numberOfPagesToShow) + }, }, mounted() { this.tags = getTags(this.publicPages) }, methods: { + showMorePages() { + this.numberOfPagesToShow = this.numberOfPagesToShow + 21 + }, + handleLoadMoreClick() { + this.infiniteScroll = true + this.numberOfPagesToShow = 40 + }, + handleBottomVisibilityChange(isVisible) { + isVisible && this.showMorePages() + }, delayVal: function () { this.current = this.current < this.delayValues.length - 1 ? this.current : -1 diff --git a/src/.vuepress/theme/svg-icon/github-icon.svg b/src/.vuepress/theme/svg-icon/github-icon.svg new file mode 100644 index 00000000..8a485ae1 --- /dev/null +++ b/src/.vuepress/theme/svg-icon/github-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/.vuepress/theme/svg-icon/rss.svg b/src/.vuepress/theme/svg-icon/rss.svg index c820b97f..1abdd089 100644 --- a/src/.vuepress/theme/svg-icon/rss.svg +++ b/src/.vuepress/theme/svg-icon/rss.svg @@ -1,6 +1 @@ - - - - - - + diff --git a/src/.vuepress/theme/tailwind.config.js b/src/.vuepress/theme/tailwind.config.js index 944e8ec0..0f7083aa 100644 --- a/src/.vuepress/theme/tailwind.config.js +++ b/src/.vuepress/theme/tailwind.config.js @@ -233,7 +233,7 @@ module.exports = { margin: ['responsive', 'first', 'last'], scale: ['group-hover', 'hover'], rotate: ['group-hover'], - opacity: ['group-hover', 'responsive'], + opacity: ['group-hover', 'responsive', 'hover'], }, plugins: [ require('tailwindcss-typography')({ componentPrefix: 'type-' }), diff --git a/src/.vuepress/theme/util/blogUtils.js b/src/.vuepress/theme/util/blogUtils.js index eb6c6fa4..4e5ff833 100644 --- a/src/.vuepress/theme/util/blogUtils.js +++ b/src/.vuepress/theme/util/blogUtils.js @@ -1,7 +1,8 @@ export const parseProtectedPost = ( post, activeTags = [], - searchedText = [] + searchedText = [], + activeCategory = '' ) => { if (!post.frontmatter.data) { return [] @@ -10,6 +11,10 @@ export const parseProtectedPost = ( const result = [] post.frontmatter.data.forEach((item) => { + if (activeCategory && decodeURI(activeCategory) !== post.frontmatter.type) { + return false + } + for (let i = 0; i < activeTags.length; i++) { if (!item.tags || !item.tags.includes(activeTags[i])) { return false @@ -23,6 +28,7 @@ export const parseProtectedPost = ( } result.push({ + category: post.frontmatter.type, type: post.frontmatter.type, date: item.date, title: item.title, diff --git a/src/_blog/newslinks/README.md b/src/_blog/newslinks/README.md index ee16a991..3a961bd9 100644 --- a/src/_blog/newslinks/README.md +++ b/src/_blog/newslinks/README.md @@ -1,6 +1,4 @@ --- -date: 2020-10-21 -url: newslinks title: Newslinks type: newslink data: