Skip to content

Commit

Permalink
fix(katzencore): Added Device Type Addon
Browse files Browse the repository at this point in the history
  • Loading branch information
maxlkatze committed Aug 14, 2024
1 parent 1ceb62a commit 54da0f9
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 18 deletions.
28 changes: 10 additions & 18 deletions src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,7 @@ import {

import { useContentStorage } from './runtime/storage/StorageManagement'
import { updateCheck } from './runtime/update'

export interface CmsUser {
name: string
password: string
}

export interface ModuleOptions {
users: CmsUser[]
secret: string
projectLocation: string
storage: {
type: 'azure-app-configuration' | 'cloudflare-kv-binding' | 'fs' | 'github' | 'mongodb' | 'netlify-blobs' | 'planetscale' | 'redis' | 'vercel-kv'
options: object
}
storageKey: string
deployHookURL?: string
}
import type { ModuleOptions } from './runtime/types/ModuleTypes'

export default defineNuxtModule<ModuleOptions>({
meta: {
Expand All @@ -48,8 +32,13 @@ export default defineNuxtModule<ModuleOptions>({
},
},
storageKey: 'katze_content.json',
addons: {
deviceRecognition: {
defaultUserAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36',
},
},
},
async setup(_options, _nuxt) {
async setup(_options: ModuleOptions, _nuxt) {
const resolver = createResolver(import.meta.url)
updateCheck().then(
({ currentVersion, latestVersion }) => {
Expand Down Expand Up @@ -78,6 +67,9 @@ export default defineNuxtModule<ModuleOptions>({
_nuxt.options.runtimeConfig.projectLocation = _options.projectLocation + (_options.projectLocation.endsWith('/') ? '' : '/')
_nuxt.options.runtimeConfig.deployHookURL = _options.deployHookURL

// ADDONS
_nuxt.options.runtimeConfig.public.deviceRecognition = _options.addons.deviceRecognition

// LOAD CONTENT STORAGE
const contentStorage = await useContentStorage(_nuxt.options.runtimeConfig)
let content = await contentStorage.getItem(_options.storageKey)
Expand Down
46 changes: 46 additions & 0 deletions src/runtime/composables/useDeviceType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { onMounted, onUnmounted, ref, useNuxtApp, useRuntimeConfig } from '#imports'
import type { DeviceTypes } from '~/src/runtime/types/DeviceTypes'
import type { AddonDeviceRecognition } from '~/src/runtime/types/ModuleTypes'

export const useDeviceType = () => {
const deviceType = useNuxtApp().$device as DeviceTypes
const { isTablet, isDesktop } = deviceType

const runtimeConfig = useRuntimeConfig()
const deviceRecognition = runtimeConfig.public.deviceRecognition as AddonDeviceRecognition
const { responsiveContainerClass } = deviceRecognition

const isMobile = ref(deviceType.isMobile)
const resizeListener = (containerClass: string) => {
// get div @container width
const container = document.querySelector(containerClass)
if (container) {
const containerWidth = container.clientWidth
isMobile.value = containerWidth < 768
}
}

const addResizeListener = (containerClass: string) => {
// add resize listener to .page-size element
const resizeObserver = new ResizeObserver(() => resizeListener(containerClass))
const container = document.querySelector(containerClass)
if (container) {
resizeObserver.observe(container)
}
resizeListener(containerClass)
}
if (responsiveContainerClass) {
const resizeEvent = () => resizeListener(responsiveContainerClass)
onMounted(() => {
if (responsiveContainerClass) {
addResizeListener(responsiveContainerClass)
window.addEventListener('resize', resizeEvent)
}
})

onUnmounted(() => {
window.removeEventListener('resize', resizeEvent)
})
}
return { isMobile, isTablet, isDesktop }
}
66 changes: 66 additions & 0 deletions src/runtime/plugins/device.plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { reactive } from 'vue'
import type { AddonDeviceRecognition } from '../types/ModuleTypes'
import { defineNuxtPlugin, useRuntimeConfig, useRequestHeaders } from '#imports'
import type { DeviceTypes } from '~/src/runtime/types/DeviceTypes'

export default defineNuxtPlugin((nuxtApp) => {
const runtimeConfig = useRuntimeConfig()

const deviceRecognition = runtimeConfig.public.deviceRecognition as AddonDeviceRecognition
const { defaultUserAgent } = deviceRecognition

// Server Side
if (nuxtApp.ssrContext) {
const headers = useRequestHeaders()
const userAgent = headers['user-agent'] || defaultUserAgent

const types = reactive(getDeviceType(userAgent, headers))

return {
provide: {
device: types,
},
}
}

// Client Side
const userAgent = navigator.userAgent || defaultUserAgent
const types = reactive(getDeviceType(userAgent))

return {
provide: {
device: types,
},
}
})

const getDeviceType = (userAgent: string, headers?: Record<string, string>): DeviceTypes => {
let isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent)
let isTablet = /iPad/i.test(userAgent)
let isDesktop = !isMobile && !isTablet

if (!headers) {
return {
isMobile,
isTablet,
isDesktop,
}
}

if (userAgent === 'Amazon CloudFront') {
isMobile = headers['cloudfront-is-mobile-viewer'] === 'true'
isTablet = headers['cloudfront-is-tablet-viewer'] === 'true'
isDesktop = headers['cloudfront-is-desktop-viewer'] === 'true'
}
else if (headers['cf-device-type']) { // Cloudflare
isMobile = headers['cf-device-type'] === 'mobile'
isTablet = headers['cf-device-type'] === 'tablet'
isDesktop = headers['cf-device-type'] === 'desktop'
}

return {
isMobile,
isTablet,
isDesktop,
}
}
5 changes: 5 additions & 0 deletions src/runtime/types/DeviceTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface DeviceTypes {
isMobile: boolean
isTablet: boolean
isDesktop: boolean
}
24 changes: 24 additions & 0 deletions src/runtime/types/ModuleTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export interface CmsUser {
name: string
password: string
}

export interface ModuleOptions {
users: CmsUser[]
secret: string
projectLocation: string
storage: {
type: 'azure-app-configuration' | 'cloudflare-kv-binding' | 'fs' | 'github' | 'mongodb' | 'netlify-blobs' | 'planetscale' | 'redis' | 'vercel-kv'
options: object
}
storageKey: string
deployHookURL?: string
addons: {
deviceRecognition: AddonDeviceRecognition
}
}

export interface AddonDeviceRecognition {
defaultUserAgent: string
responsiveContainerClass?: string
}

0 comments on commit 54da0f9

Please sign in to comment.