enriching of file urls

This commit is contained in:
Peter Clement 2025-03-13 16:11:22 +00:00
parent a9e63338ed
commit 5181ac1be5
7 changed files with 64 additions and 48 deletions

View File

@ -3,6 +3,7 @@ import * as objectStore from "../objectStore"
import * as cloudfront from "../cloudfront"
import qs from "querystring"
import { DEFAULT_TENANT_ID, getTenantId } from "../../context"
import { PWAManifestIcon } from "@budibase/types"
export function clientLibraryPath(appId: string) {
return `${objectStore.sanitizeKey(appId)}/budibase-client.js`
@ -51,3 +52,28 @@ export async function getAppFileUrl(s3Key: string) {
return await objectStore.getPresignedUrl(env.APPS_BUCKET_NAME, s3Key)
}
}
export async function enrichPWAIcons(
icons: PWAManifestIcon[]
): Promise<PWAManifestIcon[]> {
if (!icons || icons.length === 0) {
return []
}
try {
return await Promise.all(
icons.map(async icon => {
let src = icon.src
src = await getAppFileUrl(src)
return {
...icon,
src,
type: icon.type || "image/png",
}
})
)
} catch (error) {
console.error("Error enriching PWA icons:", error)
return icons
}
}

View File

@ -5,7 +5,6 @@
Heading,
Body,
Input,
TextArea,
ColorPicker,
Button,
Label,
@ -27,8 +26,6 @@
background_color: "#FFFFFF",
theme_color: "#FFFFFF",
display: "standalone",
start_url: "",
scope: "",
}
let saving = false
@ -40,7 +37,6 @@
{ label: "Standalone", value: "standalone" },
{ label: "Fullscreen", value: "fullscreen" },
{ label: "Minimal UI", value: "minimal-ui" },
{ label: "Browser", value: "browser" },
]
// Get existing icon if available
@ -92,20 +88,16 @@
async function saveFiles() {
if (iconFile) {
const iconResp = await uploadIcon(iconFile)
if (iconResp[0]?.url) {
// Get the full absolute URL
let iconUrl = iconResp[0].url
// Ensure the URL is absolute
if (iconUrl.startsWith("/")) {
iconUrl = window.location.origin + iconUrl
}
if (iconResp[0]?.key) {
// Store the S3 key directly in the src field
const iconKey = iconResp[0].key
// Update the PWA config with the new icon URL
// Update the PWA config with the icon key as the src
pwaConfig = {
...pwaConfig,
icons: [
{
src: iconUrl,
src: iconKey, // Store the S3 key directly in src
sizes: "192x192",
type: "image/png",
},
@ -357,27 +349,16 @@
<Heading size="S">Manifest settings</Heading>
<Body size="S">
The manifest settings control how your app behaves once installed.
These settings define the app's entry point, navigation boundaries,
and how it appears on the user's device. Configuring these fields
ensures your app is treated as a native-like application.
These settings define how it appears on the user's device. Configuring
these fields ensures your app is treated as a native-like application.
</Body>
</div>
<div class="field">
<Label size="L">Start URL</Label>
<Input bind:value={pwaConfig.start_url} placeholder="/" />
</div>
<div class="field">
<Label size="L">Display mode</Label>
<Select bind:value={pwaConfig.display} options={displayOptions} />
</div>
<div class="field">
<Label size="L">Scope</Label>
<Input bind:value={pwaConfig.scope} placeholder="/" />
</div>
<div class="actions">
<Button cta on:click={handleSubmit} disabled={saving}>
{saving ? "Saving..." : "Save"}

View File

@ -159,7 +159,6 @@ export class AppMetaStore extends BudiStore<AppMetaState> {
// Returned from socket
syncMetadata(metadata: { name: string; url: string; icon?: AppIcon }) {
const { name, url, icon } = metadata
console.log(name)
this.update(state => ({
...state,
name,

View File

@ -101,7 +101,6 @@ export const createBuilderWebsocket = (appId: string) => {
socket.onOther(
BuilderSocketEvent.AppMetadataChange,
({ metadata }: { metadata: any }) => {
console.log("hello?")
appStore.syncMetadata(metadata)
themeStore.syncMetadata(metadata)
navigationStore.syncMetadata(metadata)

View File

@ -232,6 +232,13 @@ export async function fetchAppPackage(
application.usedPlugins
)
// Enrich PWA icon URLs if they exist
if (application.pwa?.icons && application.pwa.icons.length > 0) {
application.pwa.icons = await objectStore.enrichPWAIcons(
application.pwa.icons
)
}
// Only filter screens if the user is not a builder
if (!users.isBuilder(ctx.user, appId)) {
const userRoleId = getUserRoleId(ctx)

View File

@ -235,10 +235,18 @@ export const serveApp = async function (ctx: UserCtx<void, ServeAppResponse>) {
<meta name="apple-mobile-web-app-title" content="${
appInfo.pwa.short_name || appInfo.name
}">`
if (appInfo.pwa.icons && appInfo.pwa.icons.length > 0) {
let appleIconUrl = appInfo.pwa.icons[0].src
console.log(appleIconUrl)
extraHead += `<link rel="apple-touch-icon" sizes="180x180" href="${appleIconUrl}">`
try {
const enrichedIcons = await objectStore.enrichPWAIcons([
appInfo.pwa.icons[0],
])
if (enrichedIcons.length > 0) {
extraHead += `<link rel="apple-touch-icon" sizes="180x180" href="${enrichedIcons[0].src}">`
}
} catch (error) {
console.error("Error processing apple-touch-icon:", error)
}
}
}
@ -407,8 +415,7 @@ export const serveManifest = async function (ctx: UserCtx<void, any>) {
name: appInfo.pwa.name || appInfo.name,
short_name: appInfo.pwa.short_name || appInfo.name,
description: appInfo.pwa.description || "",
start_url:
`/app${appInfo.url}#${appInfo.pwa.start_url}` || `/app/${appInfo.url}`,
start_url: `/app${appInfo.url}`,
display: appInfo.pwa.display || "standalone",
background_color: appInfo.pwa.background_color || "#FFFFFF",
theme_color: appInfo.pwa.theme_color || "#FFFFFF",
@ -416,20 +423,11 @@ export const serveManifest = async function (ctx: UserCtx<void, any>) {
}
if (appInfo.pwa.icons && appInfo.pwa.icons.length > 0) {
manifest.icons = appInfo.pwa.icons.map(icon => {
let src = icon.src
if (src && src.startsWith("/") && !src.startsWith("//")) {
const origin = ctx.request.origin
src = `${origin}${src}`
}
return {
...icon,
src,
type: icon.type || "image/png",
}
})
try {
manifest.icons = await objectStore.enrichPWAIcons(appInfo.pwa.icons)
} catch (error) {
console.error("Error processing manifest icons:", error)
}
}
ctx.set("Content-Type", "application/json")

View File

@ -88,10 +88,16 @@ export interface PWAManifest {
name: string
short_name: string
description: string
icons: { src: string; sizes: string; type: string }[]
icons: PWAManifestIcon[]
background_color: string
theme_color: string
display?: string
start_url?: string
scope?: string
}
export interface PWAManifestIcon {
src: string
sizes: string
type: string
}