Skip to content

Commit

Permalink
upgrade to vite-plugin-press v1.0.6 + add whatsnew feature
Browse files Browse the repository at this point in the history
  • Loading branch information
mythz committed Feb 14, 2024
1 parent a44c6e9 commit 31c81dd
Show file tree
Hide file tree
Showing 18 changed files with 200 additions and 18 deletions.
2 changes: 1 addition & 1 deletion MyApp.Client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
"unplugin-vue-markdown": "^0.26.0",
"unplugin-vue-router": "^0.7.0",
"vite": "^5.0.11",
"vite-plugin-press": "^1.0.5",
"vite-plugin-press": "^1.0.6",
"vite-plugin-vue-layouts": "^0.11.0",
"vite-svg-loader": "^5.1.0",
"vue-tsc": "^1.8.27"
Expand Down
12 changes: 12 additions & 0 deletions MyApp.Client/public/img/whatsnew/animaginary.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions MyApp.Client/public/img/whatsnew/open-shuttle.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 24 additions & 0 deletions MyApp.Client/public/img/whatsnew/planetaria.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions MyApp.Client/src/_whatsnew/2023-03-08_Animaginary/feature1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
title: Animaginary
url: /blog
image: /img/whatsnew/animaginary.svg
---

Introducing Animaginary, the next generation web animation library that's taking the world by storm.
Animaginary is a high performance library that's hand-written in optimized WebAssembly (WASM),
making it one of the fastest and most efficient animation tools available today.

Built with performance in mind, Animaginary delivers stunning animations that are both smooth and seamless, even on lower-end devices.
The library is designed to provide developers with a powerful toolset that makes it easy to create
complex animations that would otherwise be time-consuming and challenging to build.
14 changes: 14 additions & 0 deletions MyApp.Client/src/_whatsnew/2023-03-18_OpenShuttle/feature1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
title: OpenShuttle
url: https://example.org
image: /img/whatsnew/open-shuttle.svg
---

Introducing OpenShuttle, the revolutionary new product that is set to change the space industry forever. OpenShuttle is a cutting-edge
platform that provides detailed schematics for the very first rocket designed by me, which successfully made it to orbit.
This incredible product is designed to give space enthusiasts and professionals alike access to the groundbreaking technology that
was used to achieve this monumental feat.

OpenShuttle is the result of years of hard work and dedication, and I am thrilled to finally be able to share it with the world.
With its detailed schematics, OpenShuttle provides an unprecedented level of insight into the inner workings of the rocket,
allowing users to explore the technology that made history.
15 changes: 15 additions & 0 deletions MyApp.Client/src/_whatsnew/2023-03-28_Planetaria/feature1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
title: Planetaria
url: http://planetaria.tech
image: /img/whatsnew/planetaria.svg
---

Welcome to the world of Planetaria, a groundbreaking new product that is poised to revolutionize the way we explore space.
At Planetaria, we believe that the wonders of space should be accessible to everyone, not just a privileged few.
That's why we've created technology that empowers civilians to explore space on their own terms, without needing to rely
on government agencies or billionaire entrepreneurs.

Our mission is to democratize space exploration and enable people from all walks of life to experience the thrill of
venturing beyond our planet. With Planetaria, you'll have the tools and resources you need to embark on your own space missions,
whether you're a hobbyist, a scientist, or an adventurer. From designing and building your own spacecraft to conducting experiments
in microgravity, the possibilities are endless.
6 changes: 3 additions & 3 deletions MyApp.Client/src/components/BlogPosts.vue
Original file line number Diff line number Diff line change
Expand Up @@ -53,18 +53,18 @@ defineProps<{
}>()
const press:VirtualPress = inject('press')!
useHead({ title: press.posts.config.blogTitle })
useHead({ title: press.blog.config.blogTitle })
function authorLink(name:any) {
return name && press.posts.authors.some((x:any) => x.name.toLowerCase() == name.toLowerCase())
return name && press.blog.authors.some((x:any) => x.name.toLowerCase() == name.toLowerCase())
? `/posts/author/${generateSlug(name)}`
: null
}
function postLink(post:Post) {
return `/posts/${post.slug}`
}
function author(name:string) : Author | undefined {
return name ? press.posts.authors.find((x:Author) => x.name.toLowerCase() == name.toLowerCase()) : undefined
return name ? press.blog.authors.find((x:Author) => x.name.toLowerCase() == name.toLowerCase()) : undefined
}
function authorProfileUrl(name:string) {
return author(name)?.profileUrl!
Expand Down
2 changes: 1 addition & 1 deletion MyApp.Client/src/components/BlogTitle.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ defineProps<{
}>()
const press:VirtualPress = inject('press')!
const blogTitle = press.posts.config.blogTitle
const blogTitle = press.blog.config.blogTitle
</script>

3 changes: 3 additions & 0 deletions MyApp.Client/src/components/NavHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
<li class="relative flex flex-wrap just-fu-start m-0">
<RouterLink to="/todomvc" class="p-4 flex items-center justify-start mw-full hover:text-sky-500 dark:hover:text-sky-400" ActiveClass="text-blue-700 dark:text-blue-300">Todos</RouterLink>
</li>
<li class="relative flex flex-wrap just-fu-start m-0">
<RouterLink to="/whatsnew" class="p-4 flex items-center justify-start mw-full hover:text-sky-500 dark:hover:text-sky-400" ActiveClass="text-blue-700 dark:text-blue-300">What's New</RouterLink>
</li>
<li class="relative flex flex-wrap just-fu-start m-0">
<RouterLink to="/blog" class="p-4 flex items-center justify-start mw-full hover:text-sky-500 dark:hover:text-sky-400" ActiveClass="text-blue-700 dark:text-blue-300">Blog</RouterLink>
</li>
Expand Down
7 changes: 7 additions & 0 deletions MyApp.Client/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const head = createHead()

export const router = configRouter(createRouter({
history: createWebHistory(),
// Scroll to top on navigation
scrollBehavior(to, _from, savedPosition) {
if (savedPosition) {
return savedPosition
Expand All @@ -46,6 +47,12 @@ export const router = configRouter(createRouter({
return setupLayouts(routes)
},
}))
// handle external links
router.beforeEach((to, _from, next) => {
if (to.path.startsWith('/http'))
location.href = to.path.substring(1)
else next()
})

const pinia = createPinia()

Expand Down
8 changes: 4 additions & 4 deletions MyApp.Client/src/pages/blog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -144,24 +144,24 @@ import { useHead } from "@unhead/vue"
import { generateSlug, dateLabel, dateTimestamp } from "@/utils"
const press:VirtualPress = inject('press')!
useHead({ title: press.posts.config.blogTitle })
useHead({ title: press.blog.config.blogTitle })
function authorLink(name:any) {
return name && press.posts.authors.some((x:any) => x.name.toLowerCase() == name.toLowerCase())
return name && press.blog.authors.some((x:any) => x.name.toLowerCase() == name.toLowerCase())
? `/posts/author/${generateSlug(name)}`
: null
}
function postLink(post:any) {
return `/posts/${post.slug}`
}
function author(name:string) {
return name ? press.posts.authors.filter((x:any) => x.name.toLowerCase() == name.toLowerCase())[0] : null
return name ? press.blog.authors.filter((x:any) => x.name.toLowerCase() == name.toLowerCase())[0] : null
}
function authorProfileUrl(name:string) {
return author(name)?.profileUrl ?? "/img/profiles/user1.svg"
}
const posts:Post[] = press.posts.posts
const posts:Post[] = press.blog.posts
const primaryPost:Post = posts[0]
const postAuthor = primaryPost.author
const gridPosts = posts.slice(1, 7)
Expand Down
8 changes: 4 additions & 4 deletions MyApp.Client/src/pages/posts/[slug].vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
</div>
<div class="max-w-3xl mx-auto">
<div id="post" class="prose lg:prose-xl max-w-none mb-32">
<MarkdownComponent type="posts" :doc="post" />
<MarkdownComponent type="blog" :doc="post" />
</div>
</div>
</article>
Expand Down Expand Up @@ -126,10 +126,10 @@ import { useRoute } from "vue-router"
const route = useRoute()
const press:VirtualPress = inject('press')!
const slug = computed(() => (route.params as any)?.slug)
const allPosts:Post[] = press.posts.posts
const allPosts:Post[] = press.blog.posts
const post = computed(() => allPosts.find((x:any) => x.slug == slug.value) as Post)
const author = computed(() => post.value ? press.posts.authors.find((x:any) => x.name.toLowerCase() == post.value.author?.toLowerCase()) : null)
const author = computed(() => post.value ? press.blog.authors.find((x:any) => x.name.toLowerCase() == post.value.author?.toLowerCase()) : null)
const authorPosts = computed<Post[]>(() => author.value ? allPosts.filter((x:any) => x.author?.toLowerCase() == author.value!.name.toLowerCase()).slice(0,4) : [])
const authorProfileUrl = computed(() => author.value?.profileUrl ?? "/img/profiles/user1.svg")
const authorHref = computed(() => author.value ? `/posts/author/${generateSlug(author.value.name)}` : null)
Expand All @@ -141,7 +141,7 @@ function tagLink(tag:string) {
return `/posts/tagged/${generateSlug(tag)}`
}
function authorLink(name:any) {
return name && press.posts.authors.some((x:any) => x.name.toLowerCase() == name.toLowerCase())
return name && press.blog.authors.some((x:any) => x.name.toLowerCase() == name.toLowerCase())
? `/posts/author/${generateSlug(name)}`
: null
}
Expand Down
4 changes: 2 additions & 2 deletions MyApp.Client/src/pages/posts/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ import { inject } from 'vue'
import {generateSlug} from "@/utils"
const press:VirtualPress = inject('press')!
const blogDescription = press.posts.config.blogDescription
const allPosts:Post[] = press.posts.posts
const blogDescription = press.blog.config.blogDescription
const allPosts:Post[] = press.blog.posts
const allYears = [...new Set(allPosts.map((x:any) => new Date(x.date).getFullYear()) as number[])]
const allTags = [...new Set(allPosts.flatMap((x:any) => x.tags) as string[])]
const tagCounts: {[tag:string]: number} = {}
Expand Down
4 changes: 2 additions & 2 deletions MyApp.Client/src/pages/posts/tagged/[tag].vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ const tag = computed(() => (route.params as any)?.tag)
const press:VirtualPress = inject('press')!
const selectedTag = computed(() => press.posts.tagSlugs[tag.value])
const allPosts:Post[] = press.posts.posts
const selectedTag = computed(() => press.blog.tagSlugs[tag.value])
const allPosts:Post[] = press.blog.posts
const taggedPosts = computed<Post[]>(() => selectedTag ? allPosts.filter((x:any) => x.tags.includes(selectedTag.value)) : [])
const allTags = [...new Set(allPosts.flatMap((x:any) => x.tags) as string[])]
const tagCounts: {[tag:string]: number} = {}
Expand Down
2 changes: 1 addition & 1 deletion MyApp.Client/src/pages/posts/year/[year].vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const route = useRoute()
const forYear = computed(() => parseInt((route.params as any)?.year ?? 0))
const press:VirtualPress = inject('press')!
const allPosts:Post[] = press.posts.posts
const allPosts:Post[] = press.blog.posts
const allYears = [...new Set(allPosts.map((x:any) => new Date(x.date).getFullYear()) as number[])]
allYears.sort((a:number, b:number) => b - a)
const yearPosts = computed<Post[]>(() => {
Expand Down
72 changes: 72 additions & 0 deletions MyApp.Client/src/pages/whatsnew.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<template>
<div class="container mx-auto px-5">
<section class="flex-col md:flex-row flex justify-center mt-16 mb-16 md:mb-12">
<h1 class="mx-auto max-w-4xl font-display text-5xl font-medium tracking-tight text-slate-900 sm:text-7xl">
Latest features & highlights
</h1>
</section>
</div>
<div class="relative px-6 pt-16 pb-20 lg:px-8 lg:pt-24 lg:pb-28">
<div v-for="(features, release) in releases" class="relative mx-auto max-w-7xl">
<h2 class="text-center mb-4 text-6xl md:text-7xl font-bold tracking-tighter leading-tight">{{ releaseVersion(release as string) }}</h2>
<div class="text-center text-lg font-normal text-gray-500 mb-8">{{ formatDate(releaseDate(release as string)) }}</div>
<div v-for="feature in features" class="flex flex-wrap my-24">
<div class="w-full sm:w-1/2 animated px-4">
<RouterLink :to="feature.url"><img :src="feature.image" alt="" loading="lazy"></RouterLink>
</div>
<div class="w-full sm:w-1/2 text-left wow fadeInLeft animated px-4">
<h3 class="m-0 mb-4">
<RouterLink class="text-2xl font-normal text-blue-500 hover:text-blue-600" :to="feature.url">{{ feature.title }}</RouterLink>
</h3>
<div class="prose max-w-none">
<MarkdownComponent type="whatsNew" :doc="feature" :group="(release as string)" />
</div>
<div class="text-center sm:text-left my-10">
<RouterLink :to="feature.url" class="text-white text-sm font-semibold py-2.5 px-3.5 rounded outline-none focus:outline-none mr-1 mb-1 bg-slate-700 active:bg-slate-600 shadow hover:shadow-lg ease-linear transition-all duration-150">
Learn more
</RouterLink>
</div>
</div>
</div>
</div>
</div>
</template>

<script setup lang="ts">
import type { VirtualPress } from "vite-plugin-press"
import { inject } from "vue"
import { leftPart, rightPart } from "@servicestack/client"
const press:VirtualPress = inject('press')!
const releases = press.whatsNew
function formatDate(date:string) {
return new Date(date).toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' })
}
function releaseDate(release:string) {
return leftPart(release, '_')
}
function releaseVersion(release:string) {
return rightPart(release, '_')
}
</script>

<style scoped>
.prose a {
--tw-text-opacity: 1;color: rgba(59, 130, 246, var(--tw-text-opacity)); /*text-blue-500*/
-webkit-transition: all ease 0.25s;
transition: all ease 0.25s;
text-decoration: none;
}
.prose a:hover {
--tw-text-opacity: 1;color: rgba(37, 99, 235, var(--tw-text-opacity)); /*text-blue-600*/
text-decoration: none;
}
.prose p {
color: rgb(55 65 81); /*text-gray-700*/
}
.dark .prose p {
color: rgb(229 231 235); /*text-gray-200*/
}
</style>
1 change: 1 addition & 0 deletions MyApp.Client/src/typed-router.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ declare module 'vue-router/auto/routes' {
'/todomvc': RouteRecordInfo<'/todomvc', '/todomvc', Record<never, never>, Record<never, never>>,
'/videos': RouteRecordInfo<'/videos', '/videos', Record<never, never>, Record<never, never>>,
'/weather': RouteRecordInfo<'/weather', '/weather', Record<never, never>, Record<never, never>>,
'/whatsnew': RouteRecordInfo<'/whatsnew', '/whatsnew', Record<never, never>, Record<never, never>>,
}
}

Expand Down

0 comments on commit 31c81dd

Please sign in to comment.