Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix electron build issues, desktop UI updates #183

Merged
merged 15 commits into from
Sep 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion app/electron-builder.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
"extends": null,
"appId": "dev.flowser.app",
"electronVersion": "20.1.0",
"asar": true,
"afterSign": "./scripts/notarize.js",
"asarUnpack": [
"node_modules/sqlite3/lib/binding/**"
"node_modules/sqlite3/lib/binding/**",
"**/go-bindings/bin/*"
],
"files": [
"build/electron/**/*",
Expand Down
1 change: 1 addition & 0 deletions app/scripts/notarize.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const { notarize } = require("electron-notarize");

exports.default = async function notarizing(context) {
const { electronPlatformName, appOutDir } = context;

if (electronPlatformName !== "darwin") {
return;
}
Expand Down
2 changes: 1 addition & 1 deletion app/src/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "flowser",
"description": "",
"version": "2.0.13-beta",
"version": "3.0.0-beta",
"homepage": "https://flowser.dev",
"author": {
"email": "[email protected]",
Expand Down
9,584 changes: 4,408 additions & 5,176 deletions app/yarn.lock

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions backend/build-go-bindings.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
EXEC_PATH=dist/go-bindings/bin/internal
SOURCE_PATH=../internal/main.go

# Technically, only 64bit architectures are supported, since
# Cadence can't be built for 32bit arch due to constant overflows:

# This is the error you get when try building for 32bit arch:
# ../../../go/pkg/mod/github.com/onflow/[email protected]/runtime/interpreter/decode.go:37:21: cannot use math.MaxInt64 (untyped int constant 9223372036854775807) as int value in struct literal (overflows)

# https://freshman.tech/snippets/go/cross-compile-go-programs

# Windows
GOOS=windows GOARCH=amd64 go build -o "${EXEC_PATH}-amd64.exe" "${SOURCE_PATH}"

# MacOS
GOOS=darwin GOARCH=amd64 go build -o "${EXEC_PATH}-amd64-darwin" "${SOURCE_PATH}"

# Linux
GOOS=linux GOARCH=amd64 go build -o "${EXEC_PATH}-amd64-linux" "${SOURCE_PATH}"

2 changes: 1 addition & 1 deletion backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"copy-static-assets": "cp -r ./static ./dist",
"cleanup": "rm -rf node_modules && rm -rf dist",
"build": "nest build --path ./tsconfig.build.json && yarn run copy-static-assets && npm run build:bin",
"build:bin": "go build -o dist/go-bindings/bin/internal ../internal/main.go",
"build:bin": "sh build-go-bindings.sh",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"start": "rm -rf dist && mkdir -p dist && yarn run copy-static-assets && npm run build:bin && nest start --debug --watch --preserveWatchOutput",
"start:prod": "node dist/main",
Expand Down
32 changes: 30 additions & 2 deletions backend/src/go-bindings/go-bindings.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Injectable } from "@nestjs/common";
import { Injectable, InternalServerErrorException } from "@nestjs/common";
import {
GetParsedInteractionRequest,
GetParsedInteractionResponse,
Expand All @@ -7,6 +7,7 @@ import {
} from "@flowser/shared";
import { spawn } from "node:child_process";
import * as path from "path";
import * as os from "os";

type ExecuteGoBinRequest = {
command: string;
Expand Down Expand Up @@ -45,7 +46,7 @@ export class GoBindingsService {

private execute(request: ExecuteGoBinRequest): Promise<ExecuteGoBinResponse> {
return new Promise((resolve, reject) => {
const childProcess = spawn(path.join(__dirname, "bin/internal"), [
const childProcess = spawn(this.getExecutablePath(), [
request.command,
...request.arguments,
]);
Expand All @@ -70,4 +71,31 @@ export class GoBindingsService {
});
});
}

private getExecutablePath(): string {
// When running this within electron env,
// make sure to reference the executable in unpacked asar folder.
// This is a hacky solution, but it's also the simplest one for now.
// For more context, see:
// - https://github.com/epsitec-sa/hazardous#what-is-the-real-purpose-of-asarunpacked
// - https://github.com/electron/electron/issues/6262#issuecomment-273312942
return path
.join(__dirname, "bin", this.getExecutableName())
.replace("app.asar/", "app.asar.unpacked/");
}

private getExecutableName(): string {
switch (os.platform()) {
case "darwin":
return "internal-amd64-darwin";
case "linux":
return "internal-amd64-linux";
case "win32":
return "internal-amd64.exe";
default:
throw new InternalServerErrorException(
`Unsupported platform: ${os.platform()}`
);
}
}
}
2 changes: 0 additions & 2 deletions frontend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,3 @@ yarn-error.log*

# Do not track entry point, because it's generated dynamically
src/index.tsx

public/cadence-parser.wasm
Binary file modified frontend/public/favicon/android-chrome-192x192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/public/favicon/android-chrome-512x512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/public/favicon/apple-touch-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed frontend/public/favicon/error.png
Binary file not shown.
Binary file modified frontend/public/favicon/favicon-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/public/favicon/favicon-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/public/favicon/favicon.ico
Binary file not shown.
65 changes: 20 additions & 45 deletions frontend/public/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 16 additions & 5 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import React, { ReactElement, ReactNode, useEffect } from "react";
import {
createBrowserRouter,
createHashRouter,
Navigate,
Outlet,
RouteObject,
RouterProvider,
useLocation,
useParams,
Expand Down Expand Up @@ -67,11 +69,13 @@ const BrowserRouterEvents = (props: { children: ReactNode }): ReactElement => {
};

export type FlowserClientAppProps = {
useHashRouter?: boolean;
platformAdapter: PlatformAdapterState;
enableTimeoutPolling?: boolean;
};

export const FlowserClientApp = ({
useHashRouter,
platformAdapter,
enableTimeoutPolling = true,
}: FlowserClientAppProps): ReactElement => {
Expand All @@ -83,7 +87,9 @@ export const FlowserClientApp = ({
<InteractionRegistryProvider>
<ConsentAnalytics />
<ProjectRequirements />
<RouterProvider router={router} />
<RouterProvider
router={useHashRouter ? hashRouter : browserRouter}
/>
<Toaster
position="bottom-center"
gutter={8}
Expand All @@ -97,7 +103,7 @@ export const FlowserClientApp = ({
);
};

const router = createBrowserRouter([
const routes: RouteObject[] = [
{
index: true,
element: <Navigate to="projects" replace />,
Expand Down Expand Up @@ -241,14 +247,19 @@ const router = createBrowserRouter([
},
],
},
]);
];

const browserRouter = createBrowserRouter(routes);
const hashRouter = createHashRouter(routes);

function ConsentAnalytics() {
const { isConsented, setIsConsented } = useAnalyticsConsent();
if (isConsented) {
if (isConsented !== undefined) {
return null;
}
return <ConsentDialog consent={isConsented} setConsent={setIsConsented} />;
return (
<ConsentDialog consent={isConsented ?? true} setConsent={setIsConsented} />
);
}

function ProjectSettingsPage() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

.root {
padding: $spacing-xl;
color: white;

.header {
display: flex;
align-items: center;
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/dialogs/consent/ConsentDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export function ConsentDialog({
setConsent,
onClose = () => null,
}: ConsentDialogProps): ReactElement | null {
const [tempConsent, setTempConsent] = useState(consent);
const [tempConsent, setTempConsent] = useState<boolean>(consent);

return (
<BaseDialog onClose={onClose} className={classes.modal}>
Expand Down
5 changes: 2 additions & 3 deletions frontend/src/components/errors/ErrorMessage.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,22 @@
@import 'styles/animations';

.root {
@include fadeInAnimation(2s);
display: flex;
align-items: center;
justify-content: center;
padding: $spacing-l;

.innerWrapper {
display: flex;
flex-direction: column;
align-items: center;
row-gap: $spacing-base;

.title {
font-size: $font-size-large;
color: $gray-10;
}

.description {
margin-top: $spacing-l;
color: $gray-30;
}
}
Expand Down
10 changes: 9 additions & 1 deletion frontend/src/components/links/ExternalLink.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,15 @@
align-items: center;
column-gap: $spacing-s;
color: transparentize($blue, 0.1);
.icon {
width: 20px;
}
.icon * {
fill: $blue
fill: $blue;
}
.url {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
2 changes: 1 addition & 1 deletion frontend/src/components/links/ExternalLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export function ExternalLink({
style={{ display: inline ? "inline" : "flex" }}
>
{!inline && <FlowserIcon.Link className={classes.icon} />}
{children ?? prettifyUrl(href)}
{children ?? <span className={classes.url}>{prettifyUrl(href)}</span>}
</a>
);
}
Expand Down
49 changes: 29 additions & 20 deletions frontend/src/components/table/Table.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,37 @@
@import "styles/animations";
@import "styles/colors";

.headerRow {
margin-bottom: $spacing-base;
padding-bottom: $spacing-base;
padding-top: $spacing-base;
background: transparentize($violet-100, 0.5) !important;
}
.root {
height: 100%;

.message {
padding: $spacing-l;
}

.tableRow {
display: flex;
justify-content: space-between;
margin-bottom: $spacing-s;
padding-bottom: $spacing-base * 0.8;
padding-top: $spacing-base * 0.8;
background: transparentize($gray-80, 0.2);
column-gap: $spacing-base;
.headerRow {
margin-bottom: $spacing-base;
padding-bottom: $spacing-base;
padding-top: $spacing-base;
background: transparentize($violet-100, 0.5) !important;
}

& > div {
.tableRow {
display: flex;
flex: 1;
width: 100%;
justify-content: flex-start;
align-items: center;
overflow: hidden;
justify-content: space-between;
margin-bottom: $spacing-s;
padding-bottom: $spacing-base * 0.8;
padding-top: $spacing-base * 0.8;
background: transparentize($gray-80, 0.2);
column-gap: $spacing-base;

& > div {
display: flex;
flex: 1;
width: 100%;
justify-content: flex-start;
align-items: center;
overflow: hidden;
}
}

}
30 changes: 7 additions & 23 deletions frontend/src/components/table/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ import {
RowData,
} from "@tanstack/react-table";
import { CommonUtils } from "../../utils/common-utils";
import { ErrorMessage } from "../errors/ErrorMessage";
import FullScreenLoading from "../fullscreen-loading/FullScreenLoading";
import { DecoratedPollingEntity } from "../../contexts/timeout-polling.context";
import { Message } from "../errors/Message";

Expand All @@ -22,8 +20,6 @@ type CustomTableProps<TData> = {
renderCustomRow?: (row: Row<TableData<TData>>) => ReactElement;
headerRowClass?: string;
bodyRowClass?: string | ((row: Row<TableData<TData>>) => string);
isInitialLoading?: boolean;
error?: Error | string | null | undefined;
};

export type TableProps<TData> = Pick<
Expand All @@ -46,15 +42,13 @@ declare module "@tanstack/table-core" {
}

function Table<TData>({
isInitialLoading,
columns,
data,
renderCustomRow,
renderCustomHeader,
headerRowClass,
bodyRowClass,
className,
error,
enableIntroAnimations = true,
}: TableProps<TData>): ReactElement {
const table = useReactTable<TableData<TData>>({
Expand All @@ -63,23 +57,6 @@ function Table<TData>({
getCoreRowModel: getCoreRowModel(),
});

if (error) {
return <ErrorMessage error={error} />;
}

if (!isInitialLoading && data.length === 0) {
return (
<Message
title="No results"
description="It looks like there is nothing here."
/>
);
}

if (isInitialLoading) {
return <FullScreenLoading />;
}

return (
<div className={classNames(classes.root, className)}>
{table.getHeaderGroups().map((headerGroup) =>
Expand Down Expand Up @@ -108,6 +85,13 @@ function Table<TData>({
</Card>
)
)}
{table.getRowModel().rows.length === 0 && (
<Message
className={classes.message}
title="No results"
description="It looks like there is nothing here."
/>
)}
{table.getRowModel().rows.map((row) =>
renderCustomRow ? (
renderCustomRow(row)
Expand Down
1 change: 1 addition & 0 deletions frontend/src/components/tabs/StyledTabs.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
}

.tabWrapper {
overflow-x: scroll;
}

.tabWrapper, .inactiveTab {
Expand Down
Loading