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

Provider modules #32

Merged
merged 48 commits into from
Jun 15, 2023
Merged

Provider modules #32

merged 48 commits into from
Jun 15, 2023

Conversation

seanoliver
Copy link
Collaborator

@swyxio Not ready for a PR yet but wanted to share some direction in case I'm taking this too far haha. I refactored the provider-specific code into subclasses so that we can more easily swap one in out for another.

You probably already know this but since I'm new to Electron I found out that we need to keep JS in the render process to access the providers' DOMs. So we can't use Node.js imports/requires to organize the code in separate files. Argh.

If this directionally looks good my next steps will be to add another provider and a setting that saves you preferred providers to local disk. Also the grabby bars between panes aren't working on this version so I'll fix that before submitting.

@@ -0,0 +1,436 @@
console.log('interface.js loaded');
const Store = require('electron-store');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it looks like nodejs imports are fine here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed! Not sure what was going on the other day — imports are working fine so i split out each provider class to it's own file.

interface.js Outdated
Comment on lines 17 to 24
document.addEventListener('paste', (event) => {
event.preventDefault();
let text = event.clipboardData.getData('text');
let activeElement = document.activeElement;
let start = activeElement.selectionStart;
let end = activeElement.selectionEnd;
activeElement.value = activeElement.value.slice(0, start) + text + activeElement.value.slice(end);
activeElement.selectionStart = activeElement.selectionEnd = start + text.length;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i somewhat worry about overriding paste like this, lets make sure to check it works in the main chat apps

interface.js Outdated
activeElement.selectionStart = activeElement.selectionEnd = start + text.length;
});
`);
}.bind(this)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fun js trivia - how to rewrite your function so you dont have to .bind?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

() => !

interface.js Outdated
Comment on lines 50 to 53
class OpenAi extends Provider {
static webviewId = 'webviewOAI';
static webview = document.getElementById('webviewOAI');

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prob wanna give it a "display name" too since we'll probably be showing a dropdown

interface.js Outdated
Comment on lines 269 to 273
/* END Providers ------------------------------------------------------------ */

/* ========================================================================== */
/* Create Panes */
/* ========================================================================== */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good comments

interface.js Outdated
Comment on lines 277 to 285
let paneProviders = [Bard, OpenAi, Claude];

// Create the panes based on the mapping
paneProviders.forEach(provider => {

const providerPane = document.getElementById(`${provider.name.toLowerCase()}Pane`);
providerPane.classList.remove('hidden');

});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i wonder how this will look with a 4th provider.. (Bing)

interface.js Outdated Show resolved Hide resolved
interface.js Outdated Show resolved Hide resolved
interface.js Outdated
Comment on lines 352 to 360
// Adjust styling for enabled providers
Bard.handleCss();
OpenAi.handleCss();
Claude.handleCss(Claude.webview);

// fix double-pasting inside webviews
OpenAi.setupCustomPasteBehavior();
Bard.setupCustomPasteBehavior();
Claude.setupCustomPasteBehavior();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this feels like "setup code" that should belong higher up, because the other stuff directly above this is oninput and onsubmit code

Copy link
Contributor

@swyxio swyxio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking good so far!

@seanoliver
Copy link
Collaborator Author

@swyxio I think with these changes we're very close (assuming it's working on your end) — i noticed another PR open for smoltalk is started but not too much progress yet. This one feels like a significant enough refactor that you might want to merge it in sooner rather than later since modularizing the providers required touching so many parts of the app.

Once it's merged in, I can submit another PR for additional providers, without blocking your/others' work on other parts of the app.

Resizing and Keyboard Shortcuts:

  • Grabby bars and resizing are working again (added some subtle hover styling just to give more of a hint that they're interactive)
  • Cmd +/- are working but the Cmd 1/2/3 are not (I'm not sure what the desired behavior actually is for that one -- do we want it to disable all other panes and show only one or do we want it to be used in combination with +/- to zoom only a specific pane?)

Moved Preferences to Context Menu:

  • BIG CHANGE: Feel free to reject this if you don't like it but i put the preferences into the electron dropdown menu and got rid of the popup for two reasons: (1) the preferences window wouldn't stay on top after checking something on / off (2) having to "save" your preferences with an explicit button click seems a little less common now days vs. just toggling things off from the context menu. Also as we add more providers the window will need to keep getting taller for the button to stay in view — otherwise people are likely to miss it and think the checkboxes aren't working.
  • There's 4 providers in this version, so people could reasonably choose up to 4 and it would be tight but probably okay per your note above.
  • Once we add more providers, I was thinking we could just disable other providers once 4 are checked, so they'd need to uncheck one if they want to check more. (That's assuming we cap at 4 and don't stack two rows which is also a possibility with split.js!)

If you can clarify the Cmd 1/2/3 behavior I can push a final change to get this merged! This feels like a big update!

@zleman1593
Copy link

I'm getting an error after opening the built app for arm. This does not happen on the main branch.
Screenshot 2023-06-13 at 3 20 15 PM

@seanoliver
Copy link
Collaborator Author

@zleman1593 can you try running npm install or npm install electron-log? I added a logging package for development in this version so that's a new dependency.

@swyxio happy to remove this for the release, too, but having terminal logging for the render process has been super helpful so probably makes sense to at least keep in the dev environment!

@zleman1593
Copy link

I did both of those steps before publishing the above. Unfortunately, neither worked.

@seanoliver
Copy link
Collaborator Author

@zleman1593 thanks for flagging this -- I can reproduce this and will update here once we have a fix!

@seanoliver
Copy link
Collaborator Author

@zleman1593 when you have a second can you clone this latest version and see if it's working for you? it looks like it was that the package was missing from package.json

@zleman1593
Copy link

That worked.

@swyxio
Copy link
Contributor

swyxio commented Jun 15, 2023

@seanoliver amazing - grabby bars works!

i only see 3 windows, not 4. what is the default supposed to be?

image

smol bug with cmd+1/2/3/A - also refreshes the screen for some reason.

cmd+1/2/3 basically shrinks one window and maximizes one window to one specific chat, or cmd+A to restore equal width for all chats.

lastly, checking these disable buttons while they are actually enabled is unintuitive. would massage the wording or flip the checkbox state here
image

@seanoliver
Copy link
Collaborator Author

@swyxio Ah thanks I realize now I could have just run the last release version to confirm the behavior!

  • All 4 providers should be enabled by default now
  • Pressing Cmd/Ctrl + (pane number starting from 1) will minimize the other panes and expand the indicated pane to 100%
  • Pressing Cmd/Ctrl + 'a' or 'A' will distribute them evenly again (only among the enabled providers)
  • Removed the "enabled" or "disabled" language in the dropdown so the checkbox indicates if a provider is enabled
  • Fixed the bug where we were refreshing/redrawing the panes with the keyboard shortcuts.

smolmenubar

Lmk if this is working for you! If so I think we can ship Bing and I'll start a branch to add more providers. 🙌

@swyxio
Copy link
Contributor

swyxio commented Jun 15, 2023

wooohoo!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants