mirror of
https://github.com/ipfs/ipfs-blog.git
synced 2026-03-28 17:32:37 +01:00
feat: video card
This commit is contained in:
13
package-lock.json
generated
13
package-lock.json
generated
@@ -15185,6 +15185,11 @@
|
||||
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
|
||||
"dev": true
|
||||
},
|
||||
"resize-observer-polyfill": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
|
||||
"integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.17.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
|
||||
@@ -18362,6 +18367,14 @@
|
||||
"integrity": "sha512-JNgiEJ5a8YPfk5y2lKyfOAGLmkpAVfhaUi+T4wGpSppRYZ3XSyawSDDketY5KV2CsAiBLAGEIO6jO+0l2hQubg==",
|
||||
"dev": true
|
||||
},
|
||||
"vue-js-modal": {
|
||||
"version": "2.0.0-rc.6",
|
||||
"resolved": "https://registry.npmjs.org/vue-js-modal/-/vue-js-modal-2.0.0-rc.6.tgz",
|
||||
"integrity": "sha512-bJOm7Yhrl0ur/QyXjoC3gMMmE7UxiVEcS2rl8v9iPXIe9QLvjiCSZElSOvvyps8LNuG1X0rPifZGxI/CWKCFaw==",
|
||||
"requires": {
|
||||
"resize-observer-polyfill": "^1.5.1"
|
||||
}
|
||||
},
|
||||
"vue-loader": {
|
||||
"version": "15.9.3",
|
||||
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.3.tgz",
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
@leave="leave"
|
||||
@after-leave="afterLeave"
|
||||
>
|
||||
<slot></slot>
|
||||
<main :key="withKey">
|
||||
<slot></slot>
|
||||
</main>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
@@ -34,6 +36,10 @@ export default {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
withKey: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
beforeEnter: Func,
|
||||
enter: Func,
|
||||
afterEnter: Func,
|
||||
|
||||
@@ -1,17 +1,23 @@
|
||||
<template>
|
||||
<div>
|
||||
<RegularCard v-if="!card.type" v-bind="card" class="card-post h-full" />
|
||||
<component :is="computedCard" v-bind="card" class="card-post h-full" />
|
||||
<component
|
||||
:is="computedCard"
|
||||
v-bind="card"
|
||||
:open-video-modal="openVideoModal"
|
||||
class="card-post h-full"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import RegularCard from '@theme/components/blog/RegularCard'
|
||||
import LinkCard from '@theme/components/blog/LinkCard'
|
||||
import VideoCard from '@theme/components/blog/VideoCard'
|
||||
|
||||
export default {
|
||||
name: 'BlogCard',
|
||||
components: { RegularCard, LinkCard },
|
||||
components: { RegularCard, LinkCard, VideoCard },
|
||||
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
@@ -19,6 +25,10 @@ export default {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
openVideoModal: {
|
||||
type: Function,
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
computedCard() {
|
||||
@@ -32,9 +42,11 @@ export default {
|
||||
case 'News coverage':
|
||||
case 'Release notes':
|
||||
case 'Tutorial':
|
||||
case 'Video':
|
||||
return LinkCard
|
||||
|
||||
case 'Video':
|
||||
return VideoCard
|
||||
|
||||
default:
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -4,11 +4,13 @@
|
||||
v-for="social in socialLinks"
|
||||
:key="social.text"
|
||||
:network="social.network"
|
||||
:url="url"
|
||||
title=""
|
||||
:url="url ? url : currentUrl"
|
||||
:title="title ? title : ''"
|
||||
description=""
|
||||
quote=""
|
||||
:quote="`${title} ${url ? url : currentUrl} via ${host}`"
|
||||
hashtags=""
|
||||
:twitter-user="social.twitterHandle"
|
||||
class="mr-1 last:mr-0"
|
||||
>
|
||||
<SVGIcon
|
||||
class="w-6 h-6 opacity-50 fill-current text-blueGreen hover:opacity-100 transition transition-opacity duration-300 ease-in-out"
|
||||
@@ -24,12 +26,23 @@ import SVGIcon from '@theme/components/base/SVGIcon'
|
||||
export default {
|
||||
name: 'PostSocials',
|
||||
components: { SVGIcon },
|
||||
props: {
|
||||
url: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
data: () => ({
|
||||
socialLinks: [
|
||||
{
|
||||
text: 'Twitter',
|
||||
network: 'twitter',
|
||||
icon: 'twitter-icon',
|
||||
twitterHandle: 'IPFS',
|
||||
},
|
||||
{
|
||||
text: 'Facebook',
|
||||
@@ -37,10 +50,12 @@ export default {
|
||||
icon: 'facebook-icon',
|
||||
},
|
||||
],
|
||||
url: '',
|
||||
currentUrl: '',
|
||||
host: '',
|
||||
}),
|
||||
mounted() {
|
||||
this.url = window.location.href
|
||||
this.currentUrl = window.location.href
|
||||
this.host = window.location.host
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
145
src/.vuepress/theme/components/blog/VideoCard.vue
Normal file
145
src/.vuepress/theme/components/blog/VideoCard.vue
Normal file
@@ -0,0 +1,145 @@
|
||||
<template>
|
||||
<div
|
||||
class="group bg-gray-pale rounded flex flex-col transform hover:scale-105 duration-300 ease-in-out"
|
||||
itemprop="mainEntityOfPage"
|
||||
>
|
||||
<article
|
||||
itemprop="blogPost"
|
||||
itemscope
|
||||
itemtype="https://schema.org/BlogPosting"
|
||||
>
|
||||
<div class="cover embed-responsive overflow-visible embed-responsive-og">
|
||||
<a
|
||||
target="_blank"
|
||||
:href="path"
|
||||
class="embed-responsive-item p-2"
|
||||
@click="handleVideoClick"
|
||||
>
|
||||
<div class="h-full w-full relative">
|
||||
<LazyImage
|
||||
class="h-full"
|
||||
img-class="w-full h-full object-cover"
|
||||
itemprop="image"
|
||||
:alt="title"
|
||||
:src="thumbnailPath"
|
||||
/>
|
||||
<div
|
||||
class="absolute top-0 flex justify-center items-center w-full h-full bg-black bg-opacity-25"
|
||||
>
|
||||
<SVGIcon
|
||||
name="play"
|
||||
title="Play"
|
||||
:class-list="['w-16', 'h-16', 'fill-current']"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="pt-1 pb-4 px-4 flex flex-grow flex-col">
|
||||
<a
|
||||
:href="path"
|
||||
target="_blank"
|
||||
class="text-left"
|
||||
@click="handleVideoClick"
|
||||
>
|
||||
<h1 class="type-h5 font-bold text-primary hover:underline clamp-3">
|
||||
{{ title }}
|
||||
</h1>
|
||||
</a>
|
||||
<div>
|
||||
<PostMeta
|
||||
:category="frontmatter.type"
|
||||
:author="frontmatter.author"
|
||||
:date="frontmatter.date"
|
||||
:tags="frontmatter.tags"
|
||||
class="type-p4 text-primary"
|
||||
/>
|
||||
</div>
|
||||
<footer class="flex-grow">
|
||||
<p
|
||||
v-if="frontmatter.description || frontmatter.description"
|
||||
class="type-p1-serif text-primary clamp-5"
|
||||
itemprop="description"
|
||||
>
|
||||
{{ frontmatter.description || frontmatter.description }}
|
||||
</p>
|
||||
</footer>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SVGIcon from '@theme/components/base/SVGIcon.vue'
|
||||
import PostMeta from '@theme/components/blog/PostMeta'
|
||||
import LazyImage from '@theme/components/base/LazyImage'
|
||||
|
||||
export default {
|
||||
name: 'VideoCard',
|
||||
components: { SVGIcon, PostMeta, LazyImage },
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
frontmatter: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
validator: function (frontmatter) {
|
||||
if (frontmatter.description && frontmatter.description.length > 200) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
},
|
||||
},
|
||||
path: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
openVideoModal: {
|
||||
type: Function,
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
thumbnailPath() {
|
||||
if (!this.path.includes('youtube')) {
|
||||
return ''
|
||||
}
|
||||
|
||||
const newPath = new URL(this.path)
|
||||
const id =
|
||||
newPath.searchParams.get('v') || newPath.searchParams.get('list')
|
||||
|
||||
return `http://img.youtube.com/vi/${id}/0.jpg`
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleVideoClick(event) {
|
||||
/* Only uses the anchor default behavior when it's a
|
||||
new tab click - ctrl/cmd + click or "open in a
|
||||
new tab" option */
|
||||
if (
|
||||
event.ctrlKey ||
|
||||
event.shiftKey ||
|
||||
event.metaKey ||
|
||||
(event.button && event.button === 1)
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
event.preventDefault()
|
||||
|
||||
this.$store.commit('appState/setVideoModalCard', {
|
||||
frontmatter: this.frontmatter,
|
||||
path: this.path,
|
||||
title: this.title,
|
||||
})
|
||||
|
||||
this.openVideoModal()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
63
src/.vuepress/theme/components/blog/VideoModal.vue
Normal file
63
src/.vuepress/theme/components/blog/VideoModal.vue
Normal file
@@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<transition name="fade">
|
||||
<div v-if="show" class="fixed top-0 right-0 bottom-0 left-0 z-50">
|
||||
<div
|
||||
class="fixed top-0 right-0 bottom-0 left-0 bg-black bg-opacity-25"
|
||||
@click="closeModal()"
|
||||
></div>
|
||||
<div
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
class="modal-content absolute bg-white rounded w-11/12 md:w-4/5 max-w-screen-lg max-h-screen overflow-y-auto p-4 lg:p-8"
|
||||
>
|
||||
<VideoModalContent v-if="videoModalCard" :close-modal="closeModal" />
|
||||
<button
|
||||
type="button"
|
||||
class="absolute top-0 right-0 mt-4 mr-4 text-blueGreen hover:underline font-bold text-xl"
|
||||
@click="closeModal()"
|
||||
>
|
||||
X
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
import VideoModalContent from '@theme/components/blog/VideoModalContent'
|
||||
|
||||
export default {
|
||||
name: 'VideoModal',
|
||||
components: {
|
||||
VideoModalContent,
|
||||
},
|
||||
props: {},
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
}
|
||||
},
|
||||
computed: { ...mapState('appState', ['videoModalCard']) },
|
||||
watch: {},
|
||||
methods: {
|
||||
closeModal() {
|
||||
this.show = false
|
||||
document.querySelector('body').classList.remove('overflow-hidden')
|
||||
},
|
||||
openModal() {
|
||||
this.show = true
|
||||
document.querySelector('body').classList.add('overflow-hidden')
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.modal-content {
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
</style>
|
||||
155
src/.vuepress/theme/components/blog/VideoModalContent.vue
Normal file
155
src/.vuepress/theme/components/blog/VideoModalContent.vue
Normal file
@@ -0,0 +1,155 @@
|
||||
<template>
|
||||
<div class="group rounded flex flex-col" itemprop="mainEntityOfPage">
|
||||
<article
|
||||
itemprop="blogPost"
|
||||
itemscope
|
||||
itemtype="https://schema.org/BlogPosting"
|
||||
>
|
||||
<h1 class="type-h5 font-bold text-primary mr-4">
|
||||
<UnstyledLink
|
||||
:to="videoModalCard.path"
|
||||
:item="{ target: '_blank' }"
|
||||
class="clamp-3 hover:underline"
|
||||
>
|
||||
{{ videoModalCard.title }}
|
||||
</UnstyledLink>
|
||||
</h1>
|
||||
<div class="cover embed-responsive embed-responsive-og my-4">
|
||||
<iframe
|
||||
class="h-full w-full"
|
||||
type="text/html"
|
||||
:src="resolvedPath"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowfullscreen
|
||||
frameborder="0"
|
||||
></iframe>
|
||||
</div>
|
||||
<div>
|
||||
<time
|
||||
class="italic opacity-50"
|
||||
pubdate
|
||||
itemprop="datePublished"
|
||||
:datetime="videoModalCard.frontmatter.date"
|
||||
>
|
||||
{{ resolvedDate }}
|
||||
</time>
|
||||
<div class="mt-3 flex flex-wrap" itemprop="keywords">
|
||||
<button
|
||||
v-if="videoModalCard.frontmatter.type"
|
||||
class="px-2 py-1 bg-gray-pale text-blueGreen hover:underline rounded-lg text-sm mr-1"
|
||||
@click="handleCatClick()"
|
||||
>
|
||||
{{ videoModalCard.frontmatter.type }}
|
||||
</button>
|
||||
<button
|
||||
v-for="tag in resolvedTags"
|
||||
:key="tag"
|
||||
:tag="tag"
|
||||
class="px-2 py-1 bg-gray-pale text-blueGreen hover:underline rounded-lg text-sm mr-1 last:mr-0"
|
||||
@click="handleTagClick(tag)"
|
||||
>
|
||||
#{{ tag }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="flex-grow">
|
||||
<p
|
||||
v-if="
|
||||
videoModalCard.frontmatter.description ||
|
||||
videoModalCard.frontmatter.description
|
||||
"
|
||||
class="type-p1-serif text-primary clamp-5"
|
||||
itemprop="description"
|
||||
>
|
||||
{{
|
||||
videoModalCard.frontmatter.description ||
|
||||
videoModalCard.frontmatter.description
|
||||
}}
|
||||
</p>
|
||||
</footer>
|
||||
<div class="flex items-end mt-4">
|
||||
<span class="text-sm opacity-50">Share this item:</span>
|
||||
<PostSocials
|
||||
class="flex ml-2"
|
||||
:url="videoModalCard.path"
|
||||
:title="videoModalCard.frontmatter.title"
|
||||
/>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
import dayjs from 'dayjs'
|
||||
import UnstyledLink from '@theme/components/UnstyledLink'
|
||||
import PostSocials from '@theme/components/blog/PostSocials.vue'
|
||||
|
||||
export default {
|
||||
name: 'VideoModalContent',
|
||||
components: { UnstyledLink, PostSocials },
|
||||
props: {
|
||||
closeModal: {
|
||||
type: Function,
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
...mapState('appState', ['videoModalCard']),
|
||||
resolvedPath() {
|
||||
if (
|
||||
!this.videoModalCard.path.includes('youtube') ||
|
||||
this.videoModalCard.path.includes('embed')
|
||||
) {
|
||||
return this.videoModalCard.path
|
||||
}
|
||||
|
||||
const newPath = new URL(this.videoModalCard.path)
|
||||
const originalStartTime = newPath.searchParams.get('t')
|
||||
const start =
|
||||
originalStartTime &&
|
||||
newPath.searchParams
|
||||
.get('t')
|
||||
.slice(0, newPath.searchParams.get('t').length - 1)
|
||||
const id =
|
||||
newPath.searchParams.get('v') || newPath.searchParams.get('list')
|
||||
const isAList = newPath.pathname.includes('list')
|
||||
|
||||
return isAList
|
||||
? `https://www.youtube.com/embed/videoseries?list=${id}`
|
||||
: `https://www.youtube.com/embed/${id}?${start ? `start=${start}` : ''}`
|
||||
},
|
||||
resolvedDate() {
|
||||
return dayjs(this.videoModalCard.date).format(
|
||||
this.$themeLocaleConfig.dateFormat || 'YYYY-MM-DD'
|
||||
)
|
||||
},
|
||||
resolvedTags() {
|
||||
if (
|
||||
!this.videoModalCard.frontmatter.tags ||
|
||||
Array.isArray(this.videoModalCard.frontmatter.tags)
|
||||
)
|
||||
return this.videoModalCard.frontmatter.tags
|
||||
|
||||
return this.videoModalCard.frontmatter.tags
|
||||
.replace(/, /g, ',')
|
||||
.split(',')
|
||||
.filter((tag) => tag)
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleCatClick() {
|
||||
this.$store.commit(
|
||||
'appState/setActiveCategory',
|
||||
this.videoModalCard.frontmatter.type
|
||||
)
|
||||
this.closeModal()
|
||||
},
|
||||
handleTagClick(tag) {
|
||||
this.$store.commit('appState/setActiveTags', [tag])
|
||||
this.closeModal()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -31,6 +31,7 @@
|
||||
:key="page.key"
|
||||
class="mb-4"
|
||||
:card="page"
|
||||
:open-video-modal="openVideoModal"
|
||||
all
|
||||
/>
|
||||
</div>
|
||||
@@ -55,6 +56,7 @@
|
||||
v-observe-visibility="handleBottomVisibilityChange"
|
||||
></div>
|
||||
</div>
|
||||
<VideoModal v-if="mountFinish" ref="videoModal" />
|
||||
</Layout>
|
||||
</template>
|
||||
|
||||
@@ -64,6 +66,7 @@ import { mapState } from 'vuex'
|
||||
import Layout from '@theme/layouts/Layout.vue'
|
||||
|
||||
import Card from '@theme/components/blog/Card'
|
||||
import VideoModal from '@theme/components/blog/VideoModal'
|
||||
import SortAndFilter from '@theme/components/blog/SortAndFilter'
|
||||
import Breadcrumbs from '@theme/components/Breadcrumbs'
|
||||
import LanguageSelector from '@theme/components/base/LanguageSelector'
|
||||
@@ -88,6 +91,7 @@ export default {
|
||||
Breadcrumbs,
|
||||
SortAndFilter,
|
||||
LanguageSelector,
|
||||
VideoModal,
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
@@ -108,6 +112,7 @@ export default {
|
||||
'activeTags',
|
||||
'searchedText',
|
||||
'activeAuthor',
|
||||
'videoModalCard',
|
||||
]),
|
||||
tags() {
|
||||
return getTags(this.publicPages)
|
||||
@@ -236,6 +241,9 @@ export default {
|
||||
this.current < this.delayValues.length - 1 ? this.current : -1
|
||||
return this.delayValues[++this.current]
|
||||
},
|
||||
openVideoModal: function () {
|
||||
this.$refs.videoModal.openModal()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="flex flex-col min-h-screen">
|
||||
<Nav v-if="shouldDisplay('nav')" ref="nav" />
|
||||
<MobileNav v-if="shouldDisplay('nav')" />
|
||||
<Transition appear :after-leave="leaveScroll">
|
||||
<Transition :with-key="$page.key" appear :after-leave="leaveScroll">
|
||||
<component :is="layout" />
|
||||
</Transition>
|
||||
<Footer v-if="shouldDisplay('footer')" />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<main>
|
||||
<div>
|
||||
<slot name="header"></slot>
|
||||
<DynamicContent
|
||||
v-if="$page.frontmatter.body"
|
||||
@@ -7,7 +7,7 @@
|
||||
/>
|
||||
<slot></slot>
|
||||
<slot name="footer"></slot>
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -11,6 +11,7 @@ const appState = {
|
||||
activeCategory: null,
|
||||
activeAuthor: null,
|
||||
latestWeeklyPost: null,
|
||||
videoModalCard: null,
|
||||
},
|
||||
mutations: {
|
||||
toggleMobileNav: (state, data) => {
|
||||
@@ -43,6 +44,9 @@ const appState = {
|
||||
Vue.set(state, 'activeCategory', null)
|
||||
Vue.set(state, 'activeAuthor', null)
|
||||
},
|
||||
setVideoModalCard: (state, card) => {
|
||||
Vue.set(state, 'videoModalCard', card)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
<svg data-v-5a8121a8="" xmlns="http://www.w3.org/2000/svg" width="24" viewBox="-2 -2 35 35" class="mr2"><path data-v-5a8121a8="" d="M22.675 0h-21.35c-.732 0-1.325.593-1.325 1.325v21.351c0 .731.593 1.324 1.325 1.324h11.495v-9.294h-3.128v-3.622h3.128v-2.671c0-3.1 1.893-4.788 4.659-4.788 1.325 0 2.463.099 2.795.143v3.24l-1.918.001c-1.504 0-1.795.715-1.795 1.763v2.313h3.587l-.467 3.622h-3.12v9.293h6.116c.73 0 1.323-.593 1.323-1.325v-21.35c0-.732-.593-1.325-1.325-1.325z"></path></svg>
|
||||
<svg data-v-5a8121a8="" xmlns="http://www.w3.org/2000/svg" width="24" viewBox="-3 -3 35 35" class="mr2"><path data-v-5a8121a8="" d="M22.675 0h-21.35c-.732 0-1.325.593-1.325 1.325v21.351c0 .731.593 1.324 1.325 1.324h11.495v-9.294h-3.128v-3.622h3.128v-2.671c0-3.1 1.893-4.788 4.659-4.788 1.325 0 2.463.099 2.795.143v3.24l-1.918.001c-1.504 0-1.795.715-1.795 1.763v2.313h3.587l-.467 3.622h-3.12v9.293h6.116c.73 0 1.323-.593 1.323-1.325v-21.35c0-.732-.593-1.325-1.325-1.325z"></path></svg>
|
||||
|
Before Width: | Height: | Size: 484 B After Width: | Height: | Size: 484 B |
@@ -1 +1 @@
|
||||
<svg fill="none" height="15" viewBox="0 0 12 15" width="12" xmlns="http://www.w3.org/2000/svg"><path d="m10.6432 6.652c.6267.39167.6267 1.30433 0 1.696l-9.1132 5.6958c-.666048.4162-1.52999966-.0626-1.52999962-.848l.00000049-11.39155c.00000004-.78544.86395213-1.264281 1.52999913-.848001z" fill="#fff"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 47.51 47.51"><circle fill="#231f20" opacity="0.8" cx="23.75" cy="23.75" r="23.75"/><polygon fill="#ffffff" points="37.16 23.75 16.05 11.57 16.05 35.94 37.16 23.75"/></svg>
|
||||
|
Before Width: | Height: | Size: 308 B After Width: | Height: | Size: 224 B |
Reference in New Issue
Block a user