Guide to utilizing the PWA file manager in conjunction with Vue 3

I am trying to create a custom file extension (.vc2d) that will open in my Vue and Typescript progressive web app. I have set up file_handlers in my web manifest file and used window.launchQueue in my PWA. However, when I double click on the file in File Explorer, it opens the PWA correctly but passes an empty array instead of the file data.

Web Manifest file

{
    "name": "MyApp",
    "scope": "/",
    "display": "standalone",
    "start_url": "https://www.myapp.com",
    "orientation": "any",
    "related_applications": [],
    "prefer_related_applications": false,
    "file_handlers": [
        {
            "action": "/",
            "accept": {
                "application/json": [
                    ".vc2d"
                ]
            },
            "icons": [
                {
                  "src": "assets/vc2d-icon.png",
                  "sizes": "256x256",
                  "type": "image/png"
                }
              ]
        },
        {
            "action": "/",
            "accept": {
                "image/svg+xml": [
                    ".svg"
                ]
            },
            "icons": [
                {
                  "src": "assets/svg-icon.png",
                  "sizes": "256x256",
                  "type": "image/png"
                }
              ]
        }
    ],
    "icons": []
}

Vue Component

<script lang="ts">
import { defineComponent } from "vue";

declare global {
    interface Window {
        launchQueue: {
            setConsumer: (launchParams) => void;
        };
    }
}

export default defineComponent({
    name: "Home",
    components: { },
    data: function () {
        return { 
            //...
        };
    },
    mounted: function () {
        if ('launchQueue' in window) {
            console.log('File Handling API is supported!');

            window.launchQueue.setConsumer(async launchParams => {
                console.log('handling file', launchParams); // -->> launchParams.files is an empty array

                for (const file of launchParams.files) {
                    const blob = await file.getFile();
                    blob.handle = file;
                    const text = await blob.text();
                    var fileType: SupportedImportTypes;
                    if (/\.vc2d$/.test(file.name)) fileType = "vc2d";
                    else if (/\.svg$/.test(file.name)) fileType = "svg";
                    else return console.log("file extension not supported", file.name);
                    this.importFile(fileType, text, file);
                }
            });
        }
    },
    methods: {
        importFile: function (type: SupportedImportTypes, fileData?: string, fileDetails?: File) {
             //...
        }
    }
});
</script>

Should I place the file handler in the mounted hook? Am I using async/await correctly? Is there an issue with the file_handlers API or something else?

Answer №1

After testing the code, it is functioning properly. However, a peculiar issue arises when the application is downloaded on Edge - there are two versions of the Progressive Web App (PWA) displayed in the "Open with..." menu. One version successfully opens the file, while the other does not. To resolve this confusion, I identified the functional version and set it as the default program for opening my file type. This resolved the issue and may potentially assist others encountering a similar challenge.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Updating reference value with a watcher using Vue 3 and the Composition API

I'm having trouble updating a ref within a watch function. My goal is to monitor changes in the length of an array, and if the new length is less than the old one, I want to update a specific ref called selectedTitle. setup() { const slots = useS ...

Is it possible to implement lazy loading for data in TypeScript classes?

Looking to optimize my Angular application's data structure when consuming a RESTful API. My goal is to only load necessary data from the server on demand. For instance, if I have a collection of Building objects each with a set of tenant IDs in an a ...

What is the correct way to write SVG markup within SVG tags in a React and NextJS environment?

I currently have a Svg component set up like this interface SvgIconProps { children: React.ReactNode; strokeWidth?: number; width?: number; height?: number; className?: string; } export const SvgIcon = ({ children, strokeWidth = 1, width = ...

Is there a way to transform a string property into a custom type in a TypeScript array?

I am faced with a situation where I have an interface that is extending a MongoDB document, along with some sample data that is also extending that interface. Below is an outline of the interface: export default interface IModel extends Document { _id: Obj ...

Angular2: Going back a couple of steps

Is there a method to go back two steps when clicking on (click) goBack($event) instead of using just this.location.back()? I am looking for a way to access a list of locations in an array and cut out the last element. ...

"Angluar4 is throwing an error: it's unable to read the property 'iname' of

This is the code snippet from item.ts file:- export interface item{ $key?:string; available?:boolean; countable?:boolean; iname?:string; price?:string; desc?:string; image?:string; } The items component item.componenet.ts looks like this:- import { Com ...

Stop redux useSelector from causing unnecessary re-renders

I'm working on a component in React-Redux that utilizes the useSelector hook to retrieve a dictionary from the Redux store. This dictionary maps UUIDs to objects containing data that I need to display. interface IComponentProps { id: string } const ...

Having trouble accessing Vuex's getter property within a computed property

Can you help me troubleshoot an issue? When I call a getter inside a computed property, it is giving me the following error message: TS2339: Property 'dictionary' does not exist on type 'CreateComponentPublicInstance{}, {}, {}, {}, {}, Com ...

Strategies for setting the output value for a defined generic type

Is there a way to create a function that accepts optional properties common across different types, while also requiring specific properties based on the generic type passed in? type Diff<T, U> = T extends U ? never : T type DiffTypes<T, U> = ...

Exploring the synergy between radio buttons and the Next JS framework

To highlight an issue I encountered in a Next JS app, I decided to create a test app named radio-flash-test. Here are the commands I used to create the app: % npx create-next-app@latest ..... % cd radio-flash-test % heroku create radio-flash-test The ...

The view fails to update when the object is modified

Within the acceptRequest function in child.component, the commissioner.requestAccepted property is set to false, and then the updated commissioner object is returned. Ideally, I want the button to be automatically removed from the view once the object is ...

I am currently facing an issue related to the length property. It is showing an ERROR TypeError: Cannot read property 'length' of undefined

Is it recommended to set the length to be inherited from Angular right? If so, why am I getting this error: "MyPostsComponent.html: 7 ERROR TypeError: Cannot read the 'length' of undefined property" when fileList.length is greater than 0? onFile ...

Exploring multiple states within an interval function in React Native

I'm struggling to find the right words for this question. I've encountered an issue where I need to constantly check and update a complex state object within an interval loop in my program. To simplify, let's say it consists of just a counte ...

Retrieve an Array Containing a Mix of Objects and Functions in Typescript

Let's address the issue at hand: I spent several months working with a custom React Hook using plain JavaScript, and here is the code: import { useState } from 'react'; const useForm = (initialValues) => { const [state, setState] = ...

Structuring a project with React and backend for sharing code

The organization of folders outlined in the structure below for a React frontend and Express backend is really appealing to me: root ├── backend | ├── node_modules | ├── public | ├── src │ │ └── Server.ts | ...

The guidelines specified in the root `.eslintrc.json` file of an NX workspace do not carry over to the project-level `.eslintrc.json` file

In my main .eslintrc.json file, I have set up some rules. This file contains: { "root": true, "ignorePatterns": ["**/*"], "plugins": ["@nrwl/nx", "react", "@typescript-eslint", &qu ...

Configuring ordered imports in TSLint

Need help with configuring my TSLint rule ordered-imports. I want the import order to be like this: // React import React from 'react'; import { View } from 'react-native'; // Libs import * as _ from 'lodash'; import * as mo ...

Omit certain table columns when exporting to Excel using JavaScript

I am looking to export my HTML table data into Excel sheets. After conducting a thorough research, I was able to find a solution that works for me. However, I'm facing an issue with the presence of image fields in my table data which I want to exclude ...

If you have no need to directly interact with the object instance, you have the option to encapsulate it within a `reactive` container

As per the information provided in the documentation: For situations where accessing the actual object instance is not necessary, you can encapsulate it within a reactive: nested: reactive({ count, }) I am struggling to grasp this concept, could someo ...

Utilizing the Node.js `cluster` module in TypeScript/CommonJS with DT @types/[email protected]

I am currently managing a TypeScript application using Node's cluster API that was successfully built with Node 14.x and the cluster types from DT. Upon transitioning this application to Node 16.x, I updated the @types/node package from version 14.x ...