Skip to content

Commit

Permalink
✨ Add signature banner in product page (#1853)
Browse files Browse the repository at this point in the history
* ✨ Add signature banner in product page

* 🔧 Update book with sign image list

* 📱 Optimize for mobile & tablet layout

* 💬 Update Chinese content

Co-authored-by: AuroraHuang22 <[email protected]>

* 📈 Track signature banner event

* 🥅 Guard scrollIntoView

* 💬 Update Chinese translation

* 🍱 Update assets

* 💄 Adjust CSS

* 🥅 Add fallback name for signature banner

---------

Co-authored-by: AuroraHuang22 <[email protected]>
  • Loading branch information
nwingt and AuroraHuang22 authored Oct 3, 2024
1 parent a588a4a commit 1f5e3f0
Show file tree
Hide file tree
Showing 10 changed files with 279 additions and 7 deletions.
201 changes: 201 additions & 0 deletions src/components/NFTBook/SignatureBanner/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
<template>
<component
:is="tag"
:class="[
'relative',
'rounded-[24px]',
{ 'cursor-pointer': $listeners.click },
]"
@click="$emit('click')"
>
<video
:class="[
'absolute',
'left-1/2',
'top-1/2',
'w-full',
'h-full',
'rounded-[inherit]',
'object-cover',
'object-center',
'-translate-x-1/2',
'-translate-y-1/2',
'pointer-events-none',
]"
autoplay
loop
muted
playsinline
:style="bgVideoStyle"
>
<source v-for="src in bgVideoSources" :key="src" :src="src" />
</video>

<div
:class="[
'relative',
'flex',
'flex-col-reverse desktop:flex-row',
'items-center',
'text-like-green',
'rounded-[inherit]',
'bg-gradient-to-t desktop:bg-gradient-to-r',
'from-[rgba(232,252,255,0.70)]',
'to-[rgba(232,252,255,0.90)]',
'to-60%',
'overflow-hidden desktop:overflow-visible',
]"
>
<img
class="w-full max-w-[450px] desktop:ml-[-56px] phone:scale-[1.2] phone:translate-x-[-20%]"
:src="signedBookImage"
/>

<div
:class="[
'px-[24px]',
'py-[32px]',
'desktop:pl-[32px]',
'desktop:p-[48px]',
]"
>
<i18n
:class="[
'text-[28px] desktop:text-[40px]',
'font-serif',
'font-bold',
'leading-1_25',
]"
path="nft_book_signature_banner_title"
tag="h2"
>
<span class="px-[8px] bg-white" place="name">
<Transition mode="out-in" name="author-with-signature">
<span
:key="activeName"
class="inline-block"
v-text="activeName"
/>
</Transition>
</span>
</i18n>

<p class="mt-[16px]" v-text="$t('nft_book_signature_banner_content')" />
</div>
</div>
<client-only>
<lazy-component @show.once="$emit('scroll-to-bottom')" />
</client-only>
</component>
</template>

<script>
const signedBookImage = require('./signed-book.png');
const videoThumbnail = require('./video-thumbnail.jpg');
export default {
name: 'NFTBookSignatureBanner',
props: {
tag: {
type: String,
default: 'div',
},
name: {
type: [String, Array],
default: '',
},
},
data() {
return {
activeNameIndex: 0,
};
},
computed: {
nameList() {
const { name } = this;
let names = [];
if (Array.isArray(name)) {
names = name.filter(n => typeof n === 'string');
} else if (typeof name === 'string') {
names = name.split(/[\s,,、/]/);
}
return names.map(n => n.trim()).filter(Boolean);
},
activeName() {
return (
this.nameList[this.activeNameIndex] ||
this.$t('nft_book_signature_banner_author')
);
},
signedBookImage() {
// TODO: Dynamically show the signed book image based on author
return signedBookImage;
},
bgVideoStyle() {
return {
backgroundImage: `url(${videoThumbnail})`,
};
},
bgVideoSources() {
return ['/videos/signature-banner.mp4'];
},
},
watch: {
name() {
this.activeNameIndex = 0;
},
},
mounted() {
if (this.nameList.length > 1) {
this.$nextTick(() => {
this.nameAnimationInterval = setInterval(() => {
this.activeNameIndex =
(this.activeNameIndex + 1) % this.nameList.length;
}, 3000);
});
}
},
beforeDestroy() {
if (this.nameAnimationInterval) {
clearInterval(this.nameAnimationInterval);
this.nameAnimationInterval = undefined;
}
},
};
</script>

<style lang="scss">
.author-with-signature- {
&enter {
opacity: 0;
transform: translateY(-50%);
}
&leave-to {
opacity: 0;
transform: translateY(50%);
}
&enter-active,
&leave-active {
transition-property: transform, opacity;
transition-duration: 200ms;
}
&enter-active {
transition-timing-function: ease-out;
}
&leave-active {
transition-timing-function: ease-in;
}
}
</style>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 32 additions & 0 deletions src/constant/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -337,3 +337,35 @@ export const AFFILIATION_CHANNEL_LEGACY_STRINGS = {
thewitness: '@thewitness',
victoriabooklit: '@victoriacitylit',
};

export const NFT_BOOK_WITH_SIGN_IMAGE_SET = new Set(
IS_TESTNET
? [
'likenft15zduda2nmhp0fycc5yp346ummdrq9fs4qm9q36sspxxmyqh9s3uqrhzcan',
'likenft16lzy2d7p7rvpn2jwntcvg3jekeryvnxjxtrlls3ggljgkl4mycmqafq6me',
'likenft17h0ka8jzag50jg3sd30mzs2zrkax9s46xdefdydzy7u72e3r0e6s9gm77q',
'likenft18vzfkzeq3jevlt8r54apqye6l35q0pm86rj9cx8l3cmmsgn64muqgwjmvm',
'likenft1atwyg8mznmaekeszfq0nryksh3qut4c3clhrq8ksje6p0l3wjlrstnkups',
'likenft1gmm4c4rqf4x4svspx66j27wary9kxhk43n9kwcrpg6zraj7cdveqppvr4j',
'likenft1kd8xglgepr2p8j8urewraa2ekvc7769unena0zjtc8psfzg23a7skwsnxz',
'likenft1nekez4y50uk0dmgxuxql7v2vnhy3wqa24ld46hk4frlwcvwpr88selunrr',
]
: [
'likenft138rp6lqc74clx4zz3l980lzjnusxwjpw2kwkln4t8kh08h2j6t5szwur6v',
'likenft154xhw0qyds5pgvsyc7379lnkyvwqkvv2zvmmh2gn5qrewljeqwys2sju6x',
'likenft15entdx6z5l2r7wqc93fz32g53ve6lfk4tgqqzl8ereg7tvs3t9nq82n5m3',
'likenft16guxp3ve3srczsarf5nlkz32cv097z6ceee02ekxt3cphpfv9n0qmcpvqa',
'likenft16jguhkfa6nnu224fwjke2zv5f99n8wl9m097h46zqxnyu33j7rgs7f0xg3',
'likenft19symzw3xmh42gukzts858wf6rsdkn6e4jtc9wp8jh4kphfmffy5s6acyxg',
'likenft19ul7dkwj2p8fs3m6t4gy77p7mlgnyy3ehcmran2f4us8ctn6yw5sk7fx2z',
'likenft1aa48m08ep06m2celycx9qdsyl0vaqje2jlzdnufe64czevg2ed3syk9g6v',
'likenft1eawzxut5zf9t9myyd6prquef7c2r7pe0z3rzlreup59wtxe9hplqcd4987',
'likenft1ekvx3en9l0640kv9fd5n5hvltwyfl443ymyu2cnhmalvjfy0cdcqqa3l6h',
'likenft1eypeyd844dpyljga8s0mez53hx5tkncttkzaxqevr4ckl8uv9q4qqy8qju',
'likenft1ku4ra0e7dgknhd0wckrkxspuultynl4mgkxa3j08xeshfr2l0ujqmmvy83',
'likenft1mppyvyuvvft62yc66saee28q8nyl6xuh8vg332d8y9fn6gz9qtssj4trzl',
'likenft1qqqezqjuxfkrsykex6r2cdtakpkndg2wnnlsx894gmwq4p84868se52g6z',
'likenft1tlnn2x6864q6l5ag4fd87lc8eel7xafxnahd0836sap9eqshtuesesavum',
'likenft1wrskn9a683stkje3wdmcwuvpuqrp5eevjsnn9y4f55wlystzxausuhj3em',
]
);
3 changes: 3 additions & 0 deletions src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,9 @@
"nft_book_hero_replay_animation_button": "Replay Animation",
"nft_book_hero_skip_animation_button": "Skip Animation",
"nft_book_shelf_multiple_nft_class_dialog_title": "Please select a version",
"nft_book_signature_banner_author": "Author",
"nft_book_signature_banner_content": "In addition to the author's handwritten signature on the flyleaf of the ebook, there's also a personalized message written specifically for the reader, making each book a unique keepsake.",
"nft_book_signature_banner_title": "An exclusive autograph edition by {name} is available",
"nft_claim_access_nft_book": "Proceed",
"nft_claim_author": "author",
"nft_claim_claim": "Proceed",
Expand Down
3 changes: 3 additions & 0 deletions src/locales/zh-Hant.json
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,9 @@
"nft_book_hero_replay_animation_button": "重播動畫",
"nft_book_hero_skip_animation_button": "略過動畫",
"nft_book_shelf_multiple_nft_class_dialog_title": "請選擇版本",
"nft_book_signature_banner_author": "作者",
"nft_book_signature_banner_content": "電子書扉頁除附上作者的親筆簽名外,更有專為讀者而寫的留言,使每一本書都成為獨一無二的珍藏品。",
"nft_book_signature_banner_title": "特設 {name} 的簽名寄語版",
"nft_claim_access_nft_book": "下一步",
"nft_claim_author": "作者",
"nft_claim_claim": "下一步",
Expand Down
5 changes: 4 additions & 1 deletion src/mixins/nft.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import {
LIKECOIN_BUTTON_BASE,
TX_STATUS,
LIKECOIN_NFT_API_WALLET,
LIKECOIN_NFT_CLASS_FREE_MINT,
NFT_DISPLAY_STATE,
NFT_BATCH_COLLECT_MESSSAGE,
NFT_LEGACY_DEFAULT_MESSSAGE,
NFT_AUTO_DELIVER_DEFAULT_MESSAGE,
USD_TO_HKD_RATIO,
NFT_BOOK_WITH_SIGN_IMAGE_SET,
} from '~/constant';

import {
Expand Down Expand Up @@ -725,6 +725,9 @@ export default {
nftTxErrorIsAlreadyCollected() {
return this.uiTxErrorMessage === 'ALREADY_MINTED';
},
nftHasSignImage() {
return NFT_BOOK_WITH_SIGN_IMAGE_SET.has(this.classId);
},
},
watch: {
getAddress(newAddress) {
Expand Down
2 changes: 1 addition & 1 deletion src/pages/gutenberg/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,7 @@ export default {
scrollToElement(hash) {
setTimeout(() => {
const currentRef = this.$refs[hash];
currentRef.scrollIntoView({
currentRef?.scrollIntoView({
behavior: 'smooth',
block: 'start',
});
Expand Down
40 changes: 35 additions & 5 deletions src/pages/nft/class/_classId/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
@click-collect="handleCollectFromEditionSelector"
@click-add-to-cart="handleClickAddToCart"
@click-gift="handleGiftFromEditionSelector"
@click-compare="handleClickCompareItemsButton"
@click-compare="handleClickEditionCompareButton"
@input-custom-price="handleInputCustomPrice"
/>
<div
Expand Down Expand Up @@ -140,6 +140,14 @@
</ul>
</section>
<NFTBookSignatureBanner
v-if="nftHasSignImage"
tag="section"
:name="iscnWorkAuthor || creatorDisplayNameFull"
@click="handleSignatureBannerClick"
@scroll-to-bottom="handleSignatureBannerScrollToBottom"
/>
<!-- recommend -->
<section>
<client-only>
Expand Down Expand Up @@ -172,7 +180,7 @@
(nftEditions.length > 1 ||
(nftEditions.length === 1 && nftEditions[0].description))
"
ref="compareSection"
ref="editionCompareSection"
class="flex flex-col items-center gap-[24px] w-full py-[24px]"
>
<h3
Expand Down Expand Up @@ -1407,10 +1415,13 @@ export default {
1
);
},
handleClickCompareItemsButton() {
scrollToEditionCompareSection() {
this.$nextTick(() =>
this.$refs.compareSection.scrollIntoView({ behavior: 'smooth' })
this.$refs.editionCompareSection?.scrollIntoView({ behavior: 'smooth' })
);
},
handleClickEditionCompareButton() {
this.scrollToEditionCompareSection();
logTrackerEvent(
this,
'NFT',
Expand All @@ -1428,7 +1439,7 @@ export default {
1
);
this.$nextTick(() =>
this.$refs.collectionSection.scrollIntoView({ behavior: 'smooth' })
this.$refs.collectionSection?.scrollIntoView({ behavior: 'smooth' })
);
},
handleSubmitTipping(price) {
Expand Down Expand Up @@ -1532,6 +1543,25 @@ export default {
this.handleCollectFromEdition();
}
},
handleSignatureBannerClick() {
this.scrollToEditionCompareSection();
logTrackerEvent(
this,
'NFT',
'nft_class_details_sign_banner_click',
this.classId,
1
);
},
handleSignatureBannerScrollToBottom() {
logTrackerEvent(
this,
'NFT',
'nft_class_details_sign_banner_scroll',
this.classId,
1
);
},
},
};
</script>
Binary file added src/static/videos/signature-banner.mp4
Binary file not shown.

0 comments on commit 1f5e3f0

Please sign in to comment.