Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

D frontend #8

Merged
merged 45 commits into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
de1c70c
Update environment and metadata
d0rich Nov 22, 2023
49043af
Delete template files
d0rich Nov 22, 2023
ba3b766
Update package.json scripts
d0rich Nov 22, 2023
d444fa1
Update build and prepare scripts
d0rich Nov 22, 2023
b0dd33f
Add TonConnect component to Home page
d0rich Nov 23, 2023
dcbe599
Add wallet functionality to useTonConnect
d0rich Nov 23, 2023
4804b6f
Move ton connections to Pinia store
d0rich Nov 23, 2023
1a141a2
Add @esbuild-plugins/node-globals-polyfill
d0rich Nov 23, 2023
de7cf73
Refactor TonConnectStore to use reactive
d0rich Nov 23, 2023
eed1a5e
Header draft
d0rich Nov 23, 2023
16e2491
Fix theme switch and ton connect UI
d0rich Nov 23, 2023
dcc78f7
Syncronyze tonConnect theme with website theme
d0rich Nov 23, 2023
d3eef0b
Update colors in App.vue
d0rich Nov 23, 2023
01375cd
Layout draft
d0rich Nov 23, 2023
5ef80ac
Remove unused DBtn import in DFooter.vue
d0rich Nov 23, 2023
aaeac53
lintfix
d0rich Nov 23, 2023
b6faf14
Refactor TonConnectStore and DSidebar components
d0rich Nov 23, 2023
c688f18
Polyfill buffer in build
d0rich Nov 23, 2023
3abf53a
Master contract store
d0rich Nov 24, 2023
1da7339
Make blogs NFT items
d0rich Nov 24, 2023
0d64c00
Fix fees in test fixtures and contracts
d0rich Nov 25, 2023
f092219
Refactor test setup in DSocialNetworkMaster and
d0rich Nov 25, 2023
5846291
Fix create post fee validation and restrict post
d0rich Nov 25, 2023
7ab9ae8
Add transfer tests
d0rich Nov 25, 2023
5e2a307
Group tests
d0rich Nov 25, 2023
851b247
Rename contracts hooks and handle royalty params on transfer
d0rich Nov 25, 2023
a2afb79
Optimize hooks
d0rich Nov 25, 2023
aa3c8d5
Move contracts to packages
d0rich Nov 25, 2023
9f8e404
Refactor masterContractStore to use dynamic master
d0rich Nov 25, 2023
99bebdd
Refactor DPost
d0rich Nov 25, 2023
273abc6
Create markdown converters
d0rich Nov 25, 2023
11e6352
Remove unused import and update link in
d0rich Nov 25, 2023
b59e4f6
Create text for the main page
d0rich Nov 25, 2023
a70e00f
Generate user avatar by wallet
d0rich Nov 25, 2023
e4f995c
Update UserAvatar.vue to use thumbs collection
d0rich Nov 25, 2023
583bd7d
Init sidebar navigation
d0rich Nov 25, 2023
c853236
Create blog form
d0rich Nov 25, 2023
60985d0
useOpenedContract
d0rich Nov 25, 2023
7a148ec
Replace deprecated ton packages
d0rich Nov 26, 2023
612ce60
Workaround for @ton/ton incompatibility with Vue
d0rich Nov 26, 2023
dd00e76
Fix @ton/core patch
d0rich Nov 26, 2023
8add2f6
Fix sidebar toggle in Layout.vue and DSidebar.vue
d0rich Nov 26, 2023
a1b40eb
Error: Unsupported item type: tvm.stackEntrySlice
d0rich Nov 26, 2023
b056948
My blogs draft
d0rich Nov 26, 2023
913cf59
Add redirect rule to netlify.toml
d0rich Nov 26, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
My blogs draft
  • Loading branch information
d0rich committed Nov 26, 2023
commit b0569483aa1764557a4a5d80bd7c5d1a8f1d80e6
1 change: 1 addition & 0 deletions apps/d.d0rich.me/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"@tonconnect/ui": "^2.0.0-beta.6",
"@vueuse/core": "^10.6.1",
"consola": "^3.2.3",
"dateformat": "^5.0.3",
"pinia": "^2.1.7",
"rehype-stringify": "^10.0.0",
"remark-parse": "^11.0.0",
Expand Down
3 changes: 3 additions & 0 deletions apps/d.d0rich.me/src/entities/blog/model/Blog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import type { NftCollectionMetadata } from '@d0rich/ton-contracts/wrappers/DSocialNetworkBlog'

export interface Blog extends Omit<NftCollectionMetadata, '$$type'> {}
23 changes: 23 additions & 0 deletions apps/d.d0rich.me/src/entities/blog/ui/BlogAvatar.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<script setup lang="ts">
import { computed } from 'vue'
import { createAvatar } from '@dicebear/core'
import { shapes } from '@dicebear/collection'

const props = defineProps({
address: {
type: String,
required: true
}
})

const avatar = computed(() => {
return createAvatar(shapes, {
seed: props.address
}).toString()
})
</script>

<template>
<!-- eslint-disable-next-line vue/no-v-html -->
<figure v-html="avatar" />
</template>
61 changes: 61 additions & 0 deletions apps/d.d0rich.me/src/entities/blog/ui/BlogPreviewCard.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<script setup lang="ts">
import { RouterLink } from 'vue-router'
import { DWrapShape } from '@d0rich/esprit-design'
import type { Blog } from '../model/Blog'
import BlogAvatar from './BlogAvatar.vue'

defineProps<{
blog: Blog
address: string
}>()
</script>

<template>
<DWrapShape class="blog-preview-card" shape-class="blog-preview-card__shape">
<template #shape-content>
<div class="relative w-full h-full overflow-hidden">
<BlogAvatar
:address="address"
class="blog-preview-card__image"
:aria-label="`Cover for the blog ${blog.name} on D`"
/>
</div>
</template>
<RouterLink
:to="`/blog/${address}`"
class="block"
style="padding: var(--shape-card--dense__padding)"
>
<div class="p-2 prose dark:prose-invert">
<h2>{{ blog.name }}</h2>

<p>{{ blog.description }}</p>
</div>
</RouterLink>
</DWrapShape>
</template>

<style>
.blog-preview-card {
@apply scale-90 hover:scale-100 transition-transform;
}

.blog-preview-card__shape {
clip-path: var(--shape-card--dense);
@apply bg-black bg-opacity-70;
}

.blog-preview-card__image {
@apply absolute object-cover h-full
translate-x-2/3 translate-y-2/3 -rotate-45
transition-all;
}

.blog-preview-card:hover .blog-preview-card__image {
@apply translate-x-1/2 translate-y-1/2 opacity-10;
}

.blog-preview-card__link__tag {
@apply mx-1 text-lg font-bold bg-cyan-600;
}
</style>
91 changes: 90 additions & 1 deletion apps/d.d0rich.me/src/pages/MyBlogs.vue
Original file line number Diff line number Diff line change
@@ -1,3 +1,92 @@
<script setup lang="ts">
import { ref, type ComputedRef, onBeforeMount, watch } from 'vue'
import { consola } from 'consola'
import type { OpenedContract } from '@ton/ton'
import { DSocialNetworkBlog } from '@d0rich/ton-contracts/wrappers/DSocialNetworkBlog'
import { useTonConnectStore } from '../features/tonconnect/stores/tonConnectStore'
import { useOpenedContract } from '../features/tonconnect/composables/useOpenedContract'
import { useMasterContractStore } from '../features/master/stores/masterContractStore'
import BlogPreviewCard from '../entities/blog/ui/BlogPreviewCard.vue'
import type { Blog } from '../entities/blog/model/Blog'

const masterContractStore = useMasterContractStore()
const tonConnectStore = useTonConnectStore()
const masterContract = useOpenedContract(masterContractStore.latestContract)
const userBlogsContracts = ref<
ComputedRef<OpenedContract<DSocialNetworkBlog> | null>[]
>([])
const blogs = ref<{ address: string; blog: Blog }[]>([])

watch(userBlogsContracts, async () => {
console.log('Generating blogs')
const userBlogs = userBlogsContracts.value
const dataPromises = userBlogs.map(async (blog) => {
if (!blog.value) {
consola.error('Failed to open Blog contract')
return {
address: '',
blog: {
name: 'Failed to fetch',
description: '',
image: ''
}
}
}
const data = await blog.value?.getGetBlogInfo()
return {
address: blog.value.address.toString(),
blog: data.collection_content
}
})
blogs.value = await Promise.all(dataPromises)
})

async function fetchUserBlogs() {
if (!tonConnectStore.isConnected) {
consola.error('User is not authorized')
return []
}
const dMaster = masterContract.value
if (!dMaster) {
consola.error('TON client is not initialized')
return []
}
const blogsCount = await dMaster.getGetBlogsCount()
const getUserBlogsPromises = Array.from(Array(Number(blogsCount)).keys()).map(
async (index) => {
const blogAddress = await dMaster.getGetBlogAddressByIndex(BigInt(index))
if (!blogAddress) return null
const blogContract = useOpenedContract(
DSocialNetworkBlog.fromAddress(blogAddress)
)
if (!blogContract.value) {
consola.error(`Failed to open Blog contract ${blogAddress.toString()}`)
return null
}
const owner = await blogContract.value.getOwner()
if (owner.toRawString() !== tonConnectStore.wallet) return null
return blogContract
}
)
const userBlogs = (await Promise.all(getUserBlogsPromises)).filter(
(blog) => blog !== null
)
return userBlogs as ComputedRef<OpenedContract<DSocialNetworkBlog> | null>[]
}

onBeforeMount(async () => {
userBlogsContracts.value = await fetchUserBlogs()
})
</script>

<template>
<h1>My blogs</h1>
<h1 class="prose dark:prose-invert">My blogs</h1>
<nav class="grid md:grid-cols-2 lg:grid-cols-3 gap-4">
<BlogPreviewCard
v-for="blog in blogs"
:key="blog.address"
:blog="blog.blog"
:address="blog.address"
/>
</nav>
</template>
27 changes: 27 additions & 0 deletions apps/d.d0rich.me/src/shared/utils/dateformat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import dateFormat from 'dateformat'

export function dateToMonthYear(date: Date | string = new Date()) {
return dateFormat(date, 'mmm yyyy')
}

export function dateToDayMonthYear(date: Date | string = new Date()) {
return dateFormat(date, 'dd mmm yyyy')
}

export function monthDiff(d1: Date, d2: Date) {
let months
months = (d2.getFullYear() - d1.getFullYear()) * 12
months -= d1.getMonth()
months += d2.getMonth()
return months <= 0 ? 0 : months
}

export function formatYearMonthDateDiff(d1: Date, d2: Date) {
const allMonths = monthDiff(d1, d2) + 1
const months = allMonths % 12
const fullYears = (allMonths - months) / 12
const yearsPart =
fullYears > 0 ? `${fullYears} year${fullYears > 1 ? 's' : ''}` : ''
const monthPart = months > 0 ? `${months} month${months > 1 ? 's' : ''}` : ''
return (yearsPart + ' ' + monthPart).trim()
}
2 changes: 1 addition & 1 deletion apps/d.d0rich.me/src/widgets/SidebarMenu.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<script setup lang="ts">
import { ref } from 'vue'
import { DBtn } from '@d0rich/esprit-design'
import UserAvatar from '../entities/user/ui/UserAvatar.vue'
import TonConnect from '../features/tonconnect/ui/TonConnect.vue'
import UserAvatar from '../features/user/ui/UserAvatar.vue'
import { useTonConnectStore } from '@/features/tonconnect/stores/tonConnectStore'

const tonConnectStore = useTonConnectStore()
Expand Down
3 changes: 3 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.