mirror of
https://github.com/ipfs/ipfs-blog.git
synced 2026-07-02 07:51:51 +02:00
feat: add countly analytics (#68)
This commit is contained in:
Generated
+24031
-29
File diff suppressed because it is too large
Load Diff
@@ -151,7 +151,6 @@ module.exports = {
|
||||
],
|
||||
[require('./plugins/pageData')],
|
||||
[require('./plugins/vuepress-plugin-trigger-scroll')],
|
||||
// [require('./plugins/vuepress-plugin-ga-dnt'), { ga: 'UA-xxxxxx' }],
|
||||
['vuepress-plugin-img-lazy'],
|
||||
[
|
||||
'@vuepress/blog',
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
export default {
|
||||
mounted() {
|
||||
// track outbound clicks
|
||||
document.addEventListener('click', this.trackOutbound)
|
||||
},
|
||||
beforeDestroy() {
|
||||
// remove on unmount
|
||||
document.removeEventListener('click', this.trackOutbound)
|
||||
},
|
||||
methods: {
|
||||
trackOutbound(e) {
|
||||
if (!window.ga) return
|
||||
const link = e.target.closest('a')
|
||||
if (link === null || window.location.host === link.host) return
|
||||
window.ga('send', 'event', 'outbound', 'click', link.href)
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/* global GA_ID, ga */
|
||||
|
||||
export default ({ router, isServer }) => {
|
||||
// only apply on client
|
||||
if (isServer) return
|
||||
|
||||
const initAnalytics = () => {
|
||||
// ga integration
|
||||
if (process.env.NODE_ENV === 'production' && GA_ID) {
|
||||
;(function (i, s, o, g, r, a, m) {
|
||||
i.GoogleAnalyticsObject = r
|
||||
i[r] =
|
||||
i[r] ||
|
||||
function () {
|
||||
;(i[r].q = i[r].q || []).push(arguments)
|
||||
}
|
||||
i[r].l = 1 * new Date()
|
||||
a = s.createElement(o)
|
||||
m = s.getElementsByTagName(o)[0]
|
||||
a.async = 1
|
||||
a.src = g
|
||||
m.parentNode.insertBefore(a, m)
|
||||
})(
|
||||
window,
|
||||
document,
|
||||
'script',
|
||||
'https://www.google-analytics.com/analytics.js',
|
||||
'ga'
|
||||
)
|
||||
|
||||
ga('create', GA_ID, 'auto')
|
||||
ga('set', 'anonymizeIp', true)
|
||||
|
||||
router.afterEach(function (to) {
|
||||
ga('set', 'page', to.fullPath)
|
||||
ga('send', 'pageview')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
window.doNotTrack ||
|
||||
navigator.doNotTrack ||
|
||||
navigator.msDoNotTrack ||
|
||||
(window.external && 'msTrackingProtectionEnabled' in window.external)
|
||||
) {
|
||||
// DNT available
|
||||
if (
|
||||
window.doNotTrack === '1' ||
|
||||
navigator.doNotTrack === 'yes' ||
|
||||
navigator.doNotTrack === '1' ||
|
||||
navigator.msDoNotTrack === '1' ||
|
||||
(typeof window.external.msTrackingProtectionEnabled === 'function' &&
|
||||
window.external.msTrackingProtectionEnabled())
|
||||
) {
|
||||
// DNT enabled
|
||||
} else {
|
||||
// DNT disabled
|
||||
initAnalytics()
|
||||
}
|
||||
} else {
|
||||
// DNT not supported
|
||||
initAnalytics()
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
const { path } = require('@vuepress/shared-utils')
|
||||
|
||||
// eslint-disable-next-line default-param-last
|
||||
module.exports = (options = {}, context) => ({
|
||||
name: 'vuepress-plugin-ga-dnt',
|
||||
define() {
|
||||
const { siteConfig = {} } = context
|
||||
const ga = options.ga || siteConfig.ga
|
||||
const GA_ID = ga || false
|
||||
return { GA_ID }
|
||||
},
|
||||
|
||||
clientRootMixin: path.resolve(__dirname, 'clientRootMixin.js'),
|
||||
enhanceAppFiles: path.resolve(__dirname, 'enhanceAppFile.js'),
|
||||
})
|
||||
@@ -13,6 +13,7 @@
|
||||
:key="'link-' + index"
|
||||
class="sm:mr-10 last:mr-0"
|
||||
:class="[{ 'mb-4': item.children && item.children.length }]"
|
||||
@click="onlinkClick(item)"
|
||||
>
|
||||
<NavLink
|
||||
:item="item"
|
||||
@@ -26,6 +27,7 @@
|
||||
v-for="(childItem, childIndex) in item.children"
|
||||
:key="'link-child' + childIndex"
|
||||
class="mb-2 last:mb-0"
|
||||
@click="onlinkClick(item)"
|
||||
>
|
||||
<NavLink
|
||||
:item="childItem"
|
||||
@@ -50,6 +52,8 @@ import FooterLegal from '@theme/components/FooterLegal'
|
||||
import NavLink from '@theme/components/NavLink.vue'
|
||||
import NewsletterForm from '@theme/components/blog/NewsletterForm'
|
||||
|
||||
import countly from '../util/countly'
|
||||
|
||||
export default {
|
||||
name: 'Footer',
|
||||
components: { SocialLinks, NewsletterForm, NavLink, FooterLegal },
|
||||
@@ -58,6 +62,15 @@ export default {
|
||||
return this.$themeLocaleConfig.footerLinks
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onlinkClick(item) {
|
||||
countly.trackEvent(countly.events.LINK_CLICK_FOOTER, {
|
||||
path: this.$route.path,
|
||||
text: item.text,
|
||||
href: item.link,
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
href="https://protocol.ai"
|
||||
target="_blank"
|
||||
class="mr-1 inline-block align-middle"
|
||||
@click="(event) => onLinkClick(event, true)"
|
||||
>
|
||||
<SVGIcon
|
||||
name="logo-icon"
|
||||
@@ -17,6 +18,7 @@
|
||||
class="text-blueGreenLight hover:underline"
|
||||
href="https://protocol.ai"
|
||||
target="_blank"
|
||||
@click="onLinkClick"
|
||||
>Protocol Labs</a
|
||||
>
|
||||
| Except as
|
||||
@@ -24,12 +26,14 @@
|
||||
class="text-blueGreenLight hover:underline"
|
||||
href="https://protocol.ai/legal/"
|
||||
target="_blank"
|
||||
@click="onLinkClick"
|
||||
>noted</a
|
||||
>, content licensed
|
||||
<a
|
||||
class="text-blueGreenLight hover:underline"
|
||||
href="https://creativecommons.org/licenses/by/3.0/"
|
||||
target="_blank"
|
||||
@click="onLinkClick"
|
||||
>CC-BY 3.0</a
|
||||
>
|
||||
|
|
||||
@@ -37,6 +41,7 @@
|
||||
class="text-blueGreenLight hover:underline"
|
||||
href="https://protocol.ai/legal/#terms-of-service"
|
||||
target="_blank"
|
||||
@click="onLinkClick"
|
||||
>Terms</a
|
||||
>
|
||||
|
|
||||
@@ -44,6 +49,7 @@
|
||||
class="text-blueGreenLight hover:underline"
|
||||
href="https://protocol.ai/legal/#privacy-policy"
|
||||
target="_blank"
|
||||
@click="onLinkClick"
|
||||
>Privacy</a
|
||||
></span
|
||||
>
|
||||
@@ -53,8 +59,27 @@
|
||||
<script>
|
||||
import SVGIcon from '@theme/components/base/SVGIcon.vue'
|
||||
|
||||
import countly from '../util/countly'
|
||||
|
||||
export default {
|
||||
name: 'FooterLegal',
|
||||
components: { SVGIcon },
|
||||
methods: {
|
||||
onLinkClick(event, isSvg) {
|
||||
const href = isSvg
|
||||
? event.srcElement.parentElement.href
|
||||
: event.srcElement.href
|
||||
|
||||
const text = isSvg
|
||||
? event.srcElement.firstChild.textContent
|
||||
: event.srcElement.text
|
||||
|
||||
countly.trackEvent(countly.events.LINK_CLICK_FOOTER, {
|
||||
view: this.$route.path,
|
||||
text: text.trim(),
|
||||
href: href,
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -15,7 +15,11 @@
|
||||
:key="page.title"
|
||||
class="mb-3"
|
||||
>
|
||||
<Link class="mobile-nav__link type-h1" :item="page" />
|
||||
<Link
|
||||
class="mobile-nav__link type-h1"
|
||||
:item="page"
|
||||
:on-click="onClickNavLink"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
@@ -33,6 +37,8 @@ import SocialLinks from '@theme/components/SocialLinks'
|
||||
import Link from '@theme/components/base/Link'
|
||||
import trapFocus from '@theme/util/trapFocus'
|
||||
|
||||
import countly from '../util/countly'
|
||||
|
||||
export default {
|
||||
name: 'MobileNav',
|
||||
components: {
|
||||
@@ -83,6 +89,13 @@ export default {
|
||||
afterEnter() {
|
||||
this.setTabItems()
|
||||
},
|
||||
onClickNavLink(item) {
|
||||
countly.trackEvent(countly.events.LINK_CLICK_NAV, {
|
||||
view: this.$route.path,
|
||||
href: item.link,
|
||||
text: item.text,
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -32,7 +32,11 @@
|
||||
:key="page.text"
|
||||
class="nav__link-item first:m-0 font-semibold"
|
||||
>
|
||||
<Link class="nav__link font-display font-medium" :item="page" />
|
||||
<Link
|
||||
class="nav__link font-display font-medium"
|
||||
:item="page"
|
||||
:on-click="onClickNavLink"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
<button
|
||||
@@ -53,6 +57,8 @@ import { mapState } from 'vuex'
|
||||
import SVGIcon from '@theme/components/base/SVGIcon'
|
||||
import Link from '@theme/components/base/Link'
|
||||
|
||||
import countly from '../util/countly'
|
||||
|
||||
export default {
|
||||
name: 'Nav',
|
||||
components: {
|
||||
@@ -131,6 +137,13 @@ export default {
|
||||
toggleMobileMenu() {
|
||||
this.$store.commit('appState/toggleMobileNav', !this.mobileNavActive)
|
||||
},
|
||||
onClickNavLink(item) {
|
||||
countly.trackEvent(countly.events.LINK_CLICK_NAV, {
|
||||
view: this.$route.path,
|
||||
href: item.link,
|
||||
text: item.text,
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
:href="link.link"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
@click="socialLinkClick(link)"
|
||||
>
|
||||
<SVGIcon
|
||||
class="w-8 h-8 fill-current hover:opacity-75 transition transition-opacity duration-300 ease-in-out"
|
||||
@@ -18,6 +19,9 @@
|
||||
</template>
|
||||
<script>
|
||||
import SVGIcon from '@theme/components/base/SVGIcon'
|
||||
|
||||
import countly from '../util/countly'
|
||||
|
||||
export default {
|
||||
name: 'SocialLinks',
|
||||
components: { SVGIcon },
|
||||
@@ -26,5 +30,14 @@ export default {
|
||||
return this.$themeLocaleConfig.socialLinks
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
socialLinkClick(link) {
|
||||
countly.trackEvent(countly.events.SOCIAL_MEDIA_OUTBOUNDS, {
|
||||
view: this.$route.path,
|
||||
text: link.text,
|
||||
link: link.link,
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
<template>
|
||||
<RouterLink v-if="isInternal" :to="link" :exact="exact">
|
||||
<RouterLink
|
||||
v-if="isInternal"
|
||||
:to="link"
|
||||
:exact="exact"
|
||||
@click="onClick(item)"
|
||||
>
|
||||
{{ item.text }}
|
||||
</RouterLink>
|
||||
<a v-else :href="link" :target="target" :rel="rel">
|
||||
<a v-else :href="link" :target="target" :rel="rel" @click="onClick(item)">
|
||||
{{ item.text }}
|
||||
</a>
|
||||
</template>
|
||||
@@ -18,6 +23,10 @@ export default {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
onClick: {
|
||||
type: Function,
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
|
||||
@@ -42,12 +42,15 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="numberOfPosts === 0" class="flex mt-2">
|
||||
Try removing some your search parameters, or
|
||||
<button class="text-blueGreen" @click="handleClear()">
|
||||
return to the blog & news index
|
||||
</button>
|
||||
.
|
||||
<div v-if="numberOfPosts === 0" class="mt-2">
|
||||
{{ 'Try removing some your search parameters, or ' }}
|
||||
<router-link
|
||||
:to="{ path: '/' }"
|
||||
class="text-blueGreen"
|
||||
@click.native="handleClear()"
|
||||
>
|
||||
return to the blog & news index.
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
href="https://airtable.com/shrNH8YWole1xc70I"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
@click="trackSubmitItem"
|
||||
>
|
||||
Submit</a
|
||||
>
|
||||
@@ -15,6 +16,7 @@
|
||||
class="text-blueGreen hover:underline"
|
||||
href="https://ipfs.io/media/"
|
||||
rel="noopener noreferrer"
|
||||
@click="trackPressKit"
|
||||
>IPFS press kit.</a
|
||||
>
|
||||
</h2>
|
||||
@@ -43,6 +45,8 @@
|
||||
<script>
|
||||
import RSSSubscription from '@theme/components/RSSSubscription.vue'
|
||||
|
||||
import countly from '../../util/countly'
|
||||
|
||||
export default {
|
||||
name: 'LinksAndSocial',
|
||||
components: {
|
||||
@@ -55,6 +59,13 @@ export default {
|
||||
},
|
||||
},
|
||||
computed: {},
|
||||
methods: {},
|
||||
methods: {
|
||||
trackSubmitItem() {
|
||||
countly.trackEvent(countly.events.LINK_CLICK_SUBMIT_ITEM)
|
||||
},
|
||||
trackPressKit() {
|
||||
countly.trackEvent(countly.events.LINK_CLICK_PRESS_KIT)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
action="https://ipfs.us4.list-manage.com/subscribe/post?u=25473244c7d18b897f5a1ff6b&id=cad54b2230"
|
||||
method="post"
|
||||
target="_blank"
|
||||
@submit="subscribeClick"
|
||||
>
|
||||
<div id="mc_embed_signup_scroll" class="grid gric-col-2 w-full">
|
||||
<div
|
||||
@@ -78,6 +79,8 @@
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
import countly from '../../util/countly'
|
||||
|
||||
export default {
|
||||
name: 'NewsletterForm',
|
||||
props: {},
|
||||
@@ -87,6 +90,10 @@ export default {
|
||||
computed: {
|
||||
...mapState('appState', ['latestWeeklyPost']),
|
||||
},
|
||||
methods: {},
|
||||
methods: {
|
||||
subscribeClick() {
|
||||
countly.trackEvent(countly.events.NEWSLETTER_SUBSCRIBE)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
import Author from '@theme/components/mixins/Author'
|
||||
import countly from '../../util/countly'
|
||||
|
||||
export default {
|
||||
name: 'PostAuthor',
|
||||
@@ -47,6 +48,10 @@ export default {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
parent: {
|
||||
type: String,
|
||||
default: 'card',
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
...mapState('appState', ['activeAuthor']),
|
||||
@@ -68,8 +73,15 @@ export default {
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleAuthorClick(piece) {
|
||||
this.$store.commit('appState/setActiveAuthor', piece)
|
||||
handleAuthorClick(authorName) {
|
||||
const authorTracking = {
|
||||
author: authorName,
|
||||
method: `${this.parent}-select`,
|
||||
}
|
||||
|
||||
countly.trackEvent(countly.events.FILTER, authorTracking)
|
||||
|
||||
this.$store.commit('appState/setActiveAuthor', authorName)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 pt-4">
|
||||
<div class="flex flex-col md:pr-8">
|
||||
<h1 class="type-h1">{{ title }}</h1>
|
||||
<PostAuthor v-bind="author" light />
|
||||
<PostAuthor v-bind="author" light parent="blog-post" />
|
||||
<time
|
||||
class="text-gray"
|
||||
pubdate
|
||||
@@ -34,7 +34,14 @@
|
||||
class="tags flex flex-wrap text-sm text-gray-dark"
|
||||
itemprop="keywords"
|
||||
>
|
||||
<PostTag v-for="tag in resolvedTags" :key="tag" :tag="tag" link dark />
|
||||
<PostTag
|
||||
v-for="tag in resolvedTags"
|
||||
:key="tag"
|
||||
:tag="tag"
|
||||
link
|
||||
dark
|
||||
parent="blog-post"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex my-1 text-sm text-gray-dark">
|
||||
Share this item:
|
||||
|
||||
@@ -68,6 +68,7 @@ import utc from 'dayjs/plugin/utc'
|
||||
import PostTag from '@theme/components/blog/PostTag'
|
||||
import PostAuthor from '@theme/components/blog/PostAuthor'
|
||||
import UnstyledLink from '@theme/components/UnstyledLink'
|
||||
import countly from '../../util/countly'
|
||||
|
||||
export default {
|
||||
name: 'PostMeta',
|
||||
@@ -132,6 +133,13 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
handleCatClick() {
|
||||
const categoryTracking = {
|
||||
category: this.category,
|
||||
method: 'card-select',
|
||||
}
|
||||
|
||||
countly.trackEvent(countly.events.FILTER, categoryTracking)
|
||||
|
||||
this.$store.commit('appState/setActiveCategory', this.category)
|
||||
},
|
||||
},
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
hashtags=""
|
||||
:twitter-user="social.twitterHandle"
|
||||
class="mr-1 last:mr-0"
|
||||
@open="shareClick(social)"
|
||||
>
|
||||
<SVGIcon
|
||||
class="w-6 h-6 opacity-50 fill-current text-blueGreen hover:opacity-100 transition transition-opacity duration-300 ease-in-out"
|
||||
@@ -23,6 +24,8 @@
|
||||
<script>
|
||||
import SVGIcon from '@theme/components/base/SVGIcon'
|
||||
|
||||
import countly from '../../util/countly'
|
||||
|
||||
export default {
|
||||
name: 'PostSocials',
|
||||
components: { SVGIcon },
|
||||
@@ -57,5 +60,13 @@ export default {
|
||||
this.currentUrl = window.location.href
|
||||
this.host = window.location.host
|
||||
},
|
||||
methods: {
|
||||
shareClick(social) {
|
||||
countly.trackEvent(countly.events.SOCIAL_MEDIA_SHARE, {
|
||||
view: this.$route.path,
|
||||
text: social.text,
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import countly from '../../util/countly'
|
||||
|
||||
export default {
|
||||
name: 'PostTag',
|
||||
props: {
|
||||
@@ -34,6 +36,10 @@ export default {
|
||||
type: Function,
|
||||
default: () => {},
|
||||
},
|
||||
parent: {
|
||||
type: String,
|
||||
default: 'card',
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
computedClass() {
|
||||
@@ -48,12 +54,22 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
handleTagClick() {
|
||||
this.trackTag()
|
||||
this.$store.commit('appState/setActiveTags', [this.tag])
|
||||
},
|
||||
addNewTag() {
|
||||
this.trackTag()
|
||||
this.$store.commit('appState/addNewTag', [this.tag])
|
||||
this.callback()
|
||||
},
|
||||
trackTag() {
|
||||
const tagTracking = {
|
||||
tag: this.tag,
|
||||
method: `${this.parent}-select`,
|
||||
}
|
||||
|
||||
countly.trackEvent(countly.events.FILTER, tagTracking)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -54,6 +54,8 @@
|
||||
import Multiselect from 'vue-multiselect'
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
import countly from '../../util/countly'
|
||||
|
||||
export default {
|
||||
name: 'SearchCategoriesAndTags',
|
||||
components: { Multiselect },
|
||||
@@ -94,9 +96,6 @@ export default {
|
||||
this.updateTagsWithQuery()
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.updateTagsWithQuery()
|
||||
},
|
||||
created() {
|
||||
this.calculateTagsLimit()
|
||||
if (typeof window !== 'undefined') {
|
||||
@@ -190,6 +189,13 @@ export default {
|
||||
this.selectedTags = newTags
|
||||
},
|
||||
setActiveCategory(category) {
|
||||
const categoryTracking = {
|
||||
category: category,
|
||||
method: 'filter-select',
|
||||
}
|
||||
|
||||
countly.trackEvent(countly.events.FILTER, categoryTracking)
|
||||
|
||||
this.$store.commit(
|
||||
'appState/setActiveCategory',
|
||||
this.categoriesList.includes(category) ? category : ''
|
||||
@@ -216,11 +222,26 @@ export default {
|
||||
name: text,
|
||||
value: text,
|
||||
}
|
||||
|
||||
const textTracking = {
|
||||
text: text,
|
||||
method: 'filter-select',
|
||||
}
|
||||
|
||||
countly.trackEvent(countly.events.FILTER, textTracking)
|
||||
|
||||
this.selectedTags.push(option)
|
||||
this.calculateTagsLimit([...this.selectedTags, option])
|
||||
this.$refs.select2.focus()
|
||||
},
|
||||
focusOnSubmit(option) {
|
||||
const tagTracking = {
|
||||
tag: option.value,
|
||||
method: 'filter-select',
|
||||
}
|
||||
|
||||
countly.trackEvent(countly.events.FILTER, tagTracking)
|
||||
|
||||
this.calculateTagsLimit()
|
||||
this.$refs.select2.focus()
|
||||
},
|
||||
@@ -256,6 +277,15 @@ export default {
|
||||
@apply bg-blueGreen;
|
||||
}
|
||||
|
||||
.multiselect__tag-icon::after {
|
||||
color: white;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.multiselect__tag-icon:hover::after {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.multiselect__option--highlight.multiselect__option--selected,
|
||||
.multiselect__option--highlight.multiselect__option--selected::after {
|
||||
@apply bg-aquaMuted;
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
:tag="tag"
|
||||
:callback="closeModal"
|
||||
class-name="text-sm"
|
||||
parent="video-modal"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -86,6 +87,8 @@ import UnstyledLink from '@theme/components/UnstyledLink'
|
||||
import PostSocials from '@theme/components/blog/PostSocials.vue'
|
||||
import PostTag from '@theme/components/blog/PostTag'
|
||||
|
||||
import countly from '../../util/countly'
|
||||
|
||||
export default {
|
||||
name: 'VideoModalContent',
|
||||
components: { UnstyledLink, PostSocials, PostTag },
|
||||
@@ -141,6 +144,13 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
handleCatClick() {
|
||||
const categoryTracking = {
|
||||
category: this.videoModalCard.frontmatter.type,
|
||||
method: 'video-modal-select',
|
||||
}
|
||||
|
||||
countly.trackEvent(countly.events.FILTER, categoryTracking)
|
||||
|
||||
this.$store.commit(
|
||||
'appState/setActiveCategory',
|
||||
this.videoModalCard.frontmatter.type
|
||||
|
||||
@@ -10,7 +10,7 @@ import Transition from '@theme/components/directives/Transition.js'
|
||||
|
||||
import 'vue-multiselect/dist/vue-multiselect.min.css'
|
||||
|
||||
export default ({ Vue, router, siteData }) => {
|
||||
export default ({ Vue, router, siteData, isServer }) => {
|
||||
const { breakpoints } = siteData.themeConfig
|
||||
|
||||
/**
|
||||
@@ -27,6 +27,14 @@ export default ({ Vue, router, siteData }) => {
|
||||
return originalPush.call(this, location)
|
||||
}
|
||||
|
||||
if (!isServer) {
|
||||
// track page view via Countly when route changes
|
||||
router.afterEach((to) => {
|
||||
if (!window.Countly) return
|
||||
window.Countly.q.push(['track_pageview', to.path])
|
||||
})
|
||||
}
|
||||
|
||||
Vue.use(Vuex)
|
||||
Vue.use(VScrollLock)
|
||||
Vue.use(VueMq, { breakpoints })
|
||||
|
||||
@@ -62,6 +62,7 @@ import { parseProtectedPost, checkItem } from '@theme/util/blogUtils'
|
||||
import uniq from 'lodash/uniq'
|
||||
import pick from 'lodash/pick'
|
||||
import isEqual from 'lodash/isEqual'
|
||||
import countly from '../util/countly'
|
||||
|
||||
const defaultCategory = 'Blog post'
|
||||
|
||||
@@ -257,6 +258,46 @@ export default {
|
||||
|
||||
const queryText = query.search
|
||||
|
||||
if (queryCategory !== '') {
|
||||
const categoryTracking = {
|
||||
category: queryCategory,
|
||||
method: 'urlQuery',
|
||||
}
|
||||
|
||||
countly.trackEvent(countly.events.FILTER, categoryTracking)
|
||||
}
|
||||
|
||||
if (queryTags.length > 0) {
|
||||
queryTags.forEach((tag) => {
|
||||
const tagTracking = {
|
||||
tag: tag,
|
||||
method: 'urlQuery',
|
||||
}
|
||||
|
||||
countly.trackEvent(countly.events.FILTER, tagTracking)
|
||||
})
|
||||
}
|
||||
|
||||
if (queryText) {
|
||||
queryText.split(',').forEach((text) => {
|
||||
const textTracking = {
|
||||
text: text,
|
||||
method: 'urlQuery',
|
||||
}
|
||||
|
||||
countly.trackEvent(countly.events.FILTER, textTracking)
|
||||
})
|
||||
}
|
||||
|
||||
if (queryAuthor) {
|
||||
const authorTracking = {
|
||||
author: queryAuthor,
|
||||
method: 'urlQuery',
|
||||
}
|
||||
|
||||
countly.trackEvent(countly.events.FILTER, authorTracking)
|
||||
}
|
||||
|
||||
this.$store.commit('appState/setActiveTags', queryTags)
|
||||
this.$store.commit('appState/setActiveCategory', queryCategory)
|
||||
this.$store.commit(
|
||||
@@ -304,6 +345,8 @@ export default {
|
||||
this.numberOfPagesToShow = this.numberOfPagesToShow + 24
|
||||
},
|
||||
handleLoadMoreClick() {
|
||||
countly.trackEvent(countly.events.LOAD_MORE_BUTTON)
|
||||
|
||||
this.infiniteScroll = true
|
||||
this.numberOfPagesToShow = this.numberOfPagesToShow + 24
|
||||
},
|
||||
|
||||
@@ -17,6 +17,8 @@ import Footer from '@theme/components/Footer.vue'
|
||||
import Nav from '@theme/components/Nav.vue'
|
||||
import MobileNav from '@theme/components/MobileNav.vue'
|
||||
|
||||
import countly from '../util/countly'
|
||||
|
||||
export default {
|
||||
name: 'GlobalLayout',
|
||||
|
||||
@@ -35,6 +37,10 @@ export default {
|
||||
},
|
||||
},
|
||||
|
||||
beforeMount() {
|
||||
countly.loadScript()
|
||||
},
|
||||
|
||||
methods: {
|
||||
leaveScroll() {
|
||||
// eslint-disable-next-line vue/custom-event-name-casing
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
export const events = {
|
||||
LINK_CLICK_NAV: 'linkClickNav',
|
||||
LINK_CLICK_FOOTER: 'linkClickFooter',
|
||||
LINK_CLICK_SUBMIT_ITEM: 'linkClickSubmitItem',
|
||||
LINK_CLICK_PRESS_KIT: 'linkClickPressKit',
|
||||
SOCIAL_MEDIA_SHARE: 'socialMediaShare',
|
||||
SOCIAL_MEDIA_OUTBOUNDS: 'socialMediaOutbounds',
|
||||
LOAD_MORE_BUTTON: 'loadMoreButton',
|
||||
NEWSLETTER_SUBSCRIBE: 'newsletterSubscribe',
|
||||
FILTER: 'filter',
|
||||
}
|
||||
/*
|
||||
Load Countly script.
|
||||
*/
|
||||
export function loadScript() {
|
||||
const countlyScript = document.createElement('script')
|
||||
countlyScript.innerHTML = `
|
||||
//some default pre init
|
||||
var Countly = Countly || {};
|
||||
Countly.q = Countly.q || [];
|
||||
//provide countly initialization parameters
|
||||
Countly.app_key = location.hostname === 'blog.ipfs.io' ? '9e8a52b6b06d84f50321c4c3b96ba03d4bab7717' : 'c68a0191d53e5d079372653d7d6158f0374c2172';
|
||||
Countly.url = 'https://countly.ipfs.io';
|
||||
Countly.q.push(['track_sessions']);
|
||||
Countly.q.push(['track_pageview']);
|
||||
Countly.q.push(['track_clicks']);
|
||||
Countly.q.push(['track_scrolls']);
|
||||
Countly.q.push(['track_links']);
|
||||
//load countly script asynchronously
|
||||
(function() {
|
||||
var cly = document.createElement('script'); cly.type = 'text/javascript';
|
||||
cly.async = true;
|
||||
//enter url of script here
|
||||
cly.src = 'https://countly.ipfs.io/sdk/web/countly.min.js';
|
||||
cly.onload = function(){Countly.init()};
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(cly, s);
|
||||
})();`
|
||||
|
||||
document.body.appendChild(countlyScript)
|
||||
}
|
||||
|
||||
/*
|
||||
Track an event to countly with the provided data
|
||||
*/
|
||||
export function trackEvent(event, data = {}) {
|
||||
// console.info('[countly]', 'trackEvent()', event, data)
|
||||
|
||||
window.Countly.q.push([
|
||||
'add_event',
|
||||
{
|
||||
key: event,
|
||||
segmentation: data,
|
||||
},
|
||||
])
|
||||
}
|
||||
|
||||
export default {
|
||||
events,
|
||||
trackEvent,
|
||||
loadScript,
|
||||
}
|
||||
@@ -73,7 +73,7 @@ data:
|
||||
- ProtoSchool
|
||||
- static publishing
|
||||
- js-ipfs
|
||||
- ' IPLD'
|
||||
- IPLD
|
||||
- DAG
|
||||
card_image: '/2020-09-11-tutorial-protoschool-blogging.png'
|
||||
- name: 'ProtoSchool: P2P Data Links with Content Addressing'
|
||||
|
||||
Reference in New Issue
Block a user