jsonnull / electron-trpc

Build type-safe Electron inter-process communication using tRPC
https://electron-trpc.dev/
MIT License
267 stars 26 forks source link

send response back to the webcontents which send the request #108

Closed eslym closed 1 year ago

eslym commented 1 year ago

fix duplicated id problem (#106)

jsonnull commented 1 year ago

Hey, thanks so much for contributing!

I'm sorry for the delay getting back to you on this and the issue you opened, thanks for bearing with me on that.

eslym commented 1 year ago

here is a simple example usage of the context, it could be use for menu or custom modal dialog also.

// main/api.ts
import { initTRPC } from "@trpc/server";
import { type BrowserWindow, dialog } from "electron";
import { z } from "zod";

const trpc = initTRPC.context<{ window: BrowserWindow }>().create();

const { router, procedure } = trpc;
const { input } = procedure;

const MessageBoxTypes = z.union([
    z.literal("none"),
    z.literal("info"),
    z.literal("error"),
    z.literal("question"),
    z.literal("warning"),
]);

const MessageBoxOptionsSchema = z
    .object({
        message: z.string(),
        type: MessageBoxTypes.optional(),
        title: z.string().optional(),
        detail: z.string().optional(),
        buttons: z.string().array().min(1).optional(),
        defaultId: z.number().optional(),
        checkboxLabel: z.string().optional(),
        checkboxChecked: z.boolean().optional(),
        cancelId: z.number().optional(),
    });

const dialogApi = router({
    messageBox: input(MessageBoxOptionsSchema).query(({ctx, input})=>{
        return dialog.showMessageBox(ctx.window, input);
    }),
});

export const mainApi = router({
    dialog: dialogApi,
});
// somewhere in the main process
import { createIPCHandler } from 'electron-trpc/main';
import { BrowserWindow } from "electron";
import { mainApi } from './api.ts';

createIPCHandler({
    router: mainApi,
    windows: [],
    createContext: (({event}) => {
        return {
            window: BrowserWindow.fromWebContents(event.sender),
        };
    }),
});
// somewhere in the renderer process
import * as trpc from '@trpc/client';
import { ipcLink } from 'electron-trpc/renderer';
import type { mainApi } from '../main/api.ts';

export const mainApiClient = trpc.createTRPCClient<typeof mainApi>({
  links: [ipcLink()],
});
//---------------------
someRandomButton.addEventListener('click', async ()=>{
    let result = await mainApiClient.dialog.messageBox.query({
        message: 'Are you sure about that?',
        type: 'question',
        buttons: ['No', 'Yes'],
        defaultId: 1,
        cancelId: 0,
    });
    console.log(result);
});