remix-project mirror
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
remix-project/apps/remixdesktop
filip mertens 0ca6d0b410 add readme 6 months ago
..
assets icons 11 months ago
src test release 6 months ago
test add chanell 6 months ago
README.md add readme 6 months ago
afterbuild.js append dmgs 9 months ago
aftersign.js log 9 months ago
alpha.json test release 6 months ago
beta.json test release 6 months ago
entitlements.mac.plist harden 9 months ago
insiders.json test release 6 months ago
latest.json test release 6 months ago
nightwatch.conf.js windows tests 8 months ago
notarizedmg.sh xcrun 9 months ago
package.json 102 6 months ago
run_ci_test.sh test script 7 months ago
rundist.bash fix script 6 months ago
splice_tests.js fix test script 7 months ago
tsconfig.e2e.json desktop e2e 11 months ago
tsconfig.json desktop e2e 11 months ago
yarn.lock downgrade builder 6 months ago

README.md

REMIX DESKTOP

Development

Running the app locally

In the main repo yarn, then run yarn serve In this directory apps/remixdesktop, yarn, then run: yarn start:dev to boot the electron app

Then app will be started in live reload mode, anything you do in Remix IDE will be reloaded. It will not however reload electron code. You need to rerun yarn start:dev every time.

If you run into issues with yarn when native node modules are being rebuilt you need

  • Windows: install Visual Studio Tools with Desktop Development C++ enabled in the Workloads
  • MacOS: install Xcode or Xcode Command Line Tools
  • Linux: unknown, probably a C++ compiler

Electron Plugin

Electron has its own Plugin Engine, which holds plugins, these plugins have plugin clients attached to them. Each of those clients is created when an instance of Remix Desktop connects and activates a plugin. Follow all these steps to make that work.

  1. create a plugin file in apps/remixdesktop/src/plugins
  2. add imports:
import { Profile } from '@remixproject/plugin-utils'
import { ElectronBasePlugin, ElectronBasePluginClient } from '@remixproject/plugin-electron'
  1. add a base profile and a client profile:
const profile: Profile = {
  displayName: 'compilerLoader',
  name: 'compilerloader',
  description: 'Compiler Loader',
}
const clientProfile: Profile = {
  name: 'compilerloader',
  displayName: 'compilerloader',
  description: 'Compiler Loader',
  methods: ['downloadCompiler', 'listCompilers', 'getBaseUrls', 'getJsonBinData'],
}

As you can see in the clientProfile you define the methods which are exposed to the Remix plugin system.

  1. add a base plugin and a plugin client
export class CompilerLoaderPlugin extends ElectronBasePlugin {
  clients: CompilerLoaderPluginClient[] = []
  constructor() {
    super(profile, clientProfile, CompilerLoaderPluginClient)
    this.methods = [...super.methods]
  }
}

class CompilerLoaderPluginClient extends ElectronBasePluginClient {
  solJsonBinData: iSolJsonBinData
  constructor(webContentsId: number, profile: Profile) {
    super(webContentsId, profile)
  }

  async onActivation(): Promise<void> {
    this.onload(() => {
      this.emit('loaded')
    })
  }
}

The ElectronBasePluginClient is the specific instance which will be connected to the IDE. The BasePlugin is just holding all the clients for all the instances.

Any instance specific code is set as functions on the ElectronBasePluginClient class.

  1. If you need fs access you need to track the workingdir like we do here: This ensures you know where the user is working

class IsoGitPluginClient extends ElectronBasePluginClient {
  workingDir: string = ''

  constructor(webContentsId: number, profile: Profile) {
    super(webContentsId, profile)
    this.onload(async () => {
      this.on('fs' as any, 'workingDirChanged', async (path: string) => {
        this.workingDir = path
      })
      this.workingDir = await this.call('fs' as any, 'getWorkingDir')

    })
  }

  1. If you need to call methods on the BASE which holds all the clients you can add methods there, for example this iterates over clients and finds the one with the webContentsId. This ID passed on ie by menu items. Look at menu.ts to see how that works.
  openTemplate(webContentsId: any): void {
    const client = this.clients.find(c => c.webContentsId === webContentsId)
    if (client) {
      client.openTemplate()
    }
  }
  1. Add your plugin to engine.ts
const compilerLoaderPlugin = new CompilerLoaderPlugin()
  1. Register the plugin in engine.ts
engine.register(compilerLoaderPlugin)
  1. activation of plugins is done when the clients connect to the engine. No need to activate it.

  2. Add the plugin to the preload.ts. Add it to this list:

const exposedPLugins = ['fs', 'git', 'xterm', 'isogit', 'electronconfig', 'electronTemplates', 'ripgrep', 'compilerloader', 'appUpdater']

If you don't this, it won't work.

  1. In Remix IDE create a plugin in src/app/plugins/electron. If everything works correctly the methods will be loaded from the electron side, no need to specify them here. This plugin is only a passthrough.
const profile = {
  displayName: 'compilerLoader',
  name: 'compilerloader',
  description: 'Loads the compiler for offline use',
}

export class compilerLoaderPluginDesktop extends ElectronPlugin {
  constructor() {
    super(profile)
    this.methods = []
  }

  async onActivation(): Promise<void> {
  
   // something to do

  }
}
  1. if you need to activate that on load you need to add it to the app.js where other plugins are activated.

CI

CI will only run the builds is the branch is master or contains the word: desktop