diff --git a/src/services/deepLinks.ts b/src/services/deepLinks.ts index 8c8aa501..bff3346c 100644 --- a/src/services/deepLinks.ts +++ b/src/services/deepLinks.ts @@ -115,7 +115,7 @@ export class DeepLinkHandler { const [path, queryString] = parts[1].split("?"); const [routePath, ...pathParams] = path.split("/"); - // logger.log( + // logger.info( // "[DeepLink] Debug:", // "Route Path:", // routePath, @@ -150,37 +150,6 @@ export class DeepLinkHandler { return { path: routePath, params, query }; } - /** - * Processes incoming deep links and routes them appropriately. - * Handles validation, error handling, and routing to the correct view. - * - * @param url - The deep link URL to process - * @throws {DeepLinkError} If URL processing fails - */ - async handleDeepLink(url: string): Promise { - try { - logConsoleAndDb("[DeepLink] Processing URL: " + url, false); - const { path, params, query } = this.parseDeepLink(url); - // Ensure params is always a Record by converting undefined to empty string - const sanitizedParams = Object.fromEntries( - Object.entries(params).map(([key, value]) => [key, value ?? ""]), - ); - await this.validateAndRoute(path, sanitizedParams, query); - } catch (error) { - const deepLinkError = error as DeepLinkError; - logConsoleAndDb( - `[DeepLink] Error (${deepLinkError.code}): ${deepLinkError.message}`, - true, - ); - - throw { - code: deepLinkError.code || "UNKNOWN_ERROR", - message: deepLinkError.message, - details: deepLinkError.details, - }; - } - } - /** * Routes the deep link to appropriate view with validated parameters. * Validates route and parameters using Zod schemas before routing. @@ -256,4 +225,35 @@ export class DeepLinkHandler { }; } } + + /** + * Processes incoming deep links and routes them appropriately. + * Handles validation, error handling, and routing to the correct view. + * + * @param url - The deep link URL to process + * @throws {DeepLinkError} If URL processing fails + */ + async handleDeepLink(url: string): Promise { + try { + logConsoleAndDb("[DeepLink] Processing URL: " + url, false); + const { path, params, query } = this.parseDeepLink(url); + // Ensure params is always a Record by converting undefined to empty string + const sanitizedParams = Object.fromEntries( + Object.entries(params).map(([key, value]) => [key, value ?? ""]), + ); + await this.validateAndRoute(path, sanitizedParams, query); + } catch (error) { + const deepLinkError = error as DeepLinkError; + logConsoleAndDb( + `[DeepLink] Error (${deepLinkError.code}): ${deepLinkError.message}`, + true, + ); + + throw { + code: deepLinkError.code || "UNKNOWN_ERROR", + message: deepLinkError.message, + details: deepLinkError.details, + }; + } + } } diff --git a/src/views/DeepLinkRedirectView.vue b/src/views/DeepLinkRedirectView.vue index 1615cfd4..74ea25d7 100644 --- a/src/views/DeepLinkRedirectView.vue +++ b/src/views/DeepLinkRedirectView.vue @@ -122,17 +122,31 @@ export default class DeepLinkRedirectView extends Vue { // If pathParam is an array (catch-all parameter), join it const fullPath = Array.isArray(pathParam) ? pathParam.join("/") : pathParam; - this.destinationUrl = fullPath; - this.deepLinkUrl = `timesafari://${fullPath}`; - this.webUrl = `${APP_SERVER}/${fullPath}`; - - // Log for debugging - logger.info("Deep link processing:", { - fullPath, - deepLinkUrl: this.deepLinkUrl, - webUrl: this.webUrl, - userAgent: this.userAgent, - }); + + // Get query parameters from the route + const queryParams = this.$route.query; + + // Build query string if there are query parameters + let queryString = ""; + if (Object.keys(queryParams).length > 0) { + const searchParams = new URLSearchParams(); + Object.entries(queryParams).forEach(([key, value]) => { + if (value !== undefined && value !== null) { + const stringValue = Array.isArray(value) ? value[0] : value; + if (stringValue !== null && stringValue !== undefined) { + searchParams.append(key, stringValue); + } + } + }); + queryString = "?" + searchParams.toString(); + } + + // Combine path with query parameters + const fullPathWithQuery = fullPath + queryString; + + this.destinationUrl = fullPathWithQuery; + this.deepLinkUrl = `timesafari://${fullPathWithQuery}`; + this.webUrl = `${APP_SERVER}/${fullPathWithQuery}`; this.isDevelopment = process.env.NODE_ENV !== "production"; this.userAgent = navigator.userAgent; @@ -147,13 +161,6 @@ export default class DeepLinkRedirectView extends Vue { return; } - logger.info("Attempting deep link redirect:", { - deepLinkUrl: this.deepLinkUrl, - webUrl: this.webUrl, - isMobile: this.isMobile, - userAgent: this.userAgent, - }); - try { // For mobile, try the deep link URL; for desktop, use the web URL const redirectUrl = this.isMobile ? this.deepLinkUrl : this.webUrl; @@ -170,7 +177,6 @@ export default class DeepLinkRedirectView extends Vue { document.body.appendChild(link); link.click(); document.body.removeChild(link); - logger.info("Fallback link click completed"); } catch (error) { logger.error( "Fallback deep link failed: " + errorStringForLog(error),