Skip to content

Commit

Permalink
Merge pull request #102 from Flow-Works/thinliquid/qol
Browse files Browse the repository at this point in the history
✨ feature: better git and theme support
  • Loading branch information
ThinLiquid authored Aug 12, 2023
2 parents 15b6331 + 926c49e commit 1e1b8af
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 50 deletions.
Binary file not shown.
97 changes: 69 additions & 28 deletions public/builtin/apps/scripts/terminal.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,45 +5,86 @@ import 'https://cdn.jsdelivr.net/npm/[email protected]/lib/xterm.min.js';

import FitAddon from 'https://cdn.jsdelivr.net/npm/[email protected]/+esm';
import WebLinksAddon from 'https://cdn.jsdelivr.net/npm/[email protected]/+esm';
import CanvasAddon from 'https://cdn.jsdelivr.net/npm/[email protected]/+esm';
import FontFaceObserver from 'https://cdn.jsdelivr.net/npm/[email protected]/+esm';

import { loadCSS } from '/scripts/utilities.js';
import { config } from '/scripts/managers.js';

import { CommandsAddon } from './terminal/handler.js';

import { _auth } from '../../../scripts/firebase.js';
import * as auth from 'https://www.gstatic.com/firebasejs/10.0.0/firebase-auth.js';

const commands = {
'cd': './terminal/commands/cd.js'
cd: './terminal/commands/cd.js',
};

const term = new Terminal({
cursorBlink: true,
fontFamily: 'JetBrains Mono Nerd Font, monospace',
letterSpacing: '1',
allowTransparency: true
});

auth.onAuthStateChanged(_auth, (user) => {
if (user) {
let dir = {
path: '/',
set: (str) => {
dir.path = str;
}
};
window.loadCSS = (FILE_URL, callback) => {
const styleEle = document.createElement('link');

let username;
if (_auth.currentUser.displayName !== null) username = _auth.currentUser.displayName.toLowerCase().replaceAll(' ', '-');
else username = 'guest';
const usr = { username };
styleEle.setAttribute('rel', 'stylesheet');
styleEle.setAttribute('type', 'text/css');
styleEle.setAttribute('href', FILE_URL);

document.head.appendChild(styleEle);

const fitAddon = new FitAddon.FitAddon();
styleEle.addEventListener('load', () => {
if (typeof callback == 'function')
callback();

term.loadAddon(fitAddon);
term.loadAddon(new WebLinksAddon.WebLinksAddon());
term.loadAddon(new CommandsAddon({ commands }, usr, dir));
});
};

window.addEventListener('load', () => {
window.loadCSS(config.settings.get('theme').url, () => {
const term = new Terminal({
cursorBlink: true,
fontFamily: 'JetBrains Mono Nerd Font, monospace',
fontSize: '15',
lineHeight: '1.1',
letterSpacing: '1.4',
allowTransparency: true,
theme: {
background: getComputedStyle(document.querySelector(':root')).getPropertyValue('--desktop-bg'),
foreground: getComputedStyle(document.querySelector(':root')).getPropertyValue('--text-color'),
}
});

term.open(document.getElementById('terminal'));
fitAddon.fit();
}
auth.onAuthStateChanged(_auth, (user) => {
if (user) {
let dir = {
path: '/',
set: (str) => {
dir.path = str;
},
};

let username;
if (_auth.currentUser.displayName !== null)
username = _auth.currentUser.displayName
.toLowerCase()
.replaceAll(' ', '-');
else username = 'guest';

const usr = { username };

const fitAddon = new FitAddon.FitAddon();

term.loadAddon(fitAddon);
term.loadAddon(new WebLinksAddon.WebLinksAddon());
term.loadAddon(new CanvasAddon.CanvasAddon());
term.loadAddon(new CommandsAddon({ commands }, usr, dir));

const font = new FontFaceObserver('JetBrains Mono Nerd Font');
font.load().then(() => {
term.open(document.getElementById('terminal'));
}, () => {
window.location.reload();
});

fitAddon.fit();
}
});
});
});
98 changes: 91 additions & 7 deletions public/builtin/apps/scripts/terminal/commands/git.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,104 @@ export const metadata = {
};

export const exec = async (fs, term, usr, dir, args) => {
const options = args.map(arg => {
if (arg.startsWith('--') && arg.includes('=') == false) return arg;
if (arg.startsWith('-') && arg.includes('=') == false) return arg;
}).filter((element) => element !== undefined);

const vars = {};

args.forEach((arg) => {
if (arg.startsWith('--') && arg.includes('=')) {
vars[arg.split('=')[0].replace('--', '')] = arg.split('=')[1];
};
});

args.shift();
const values = args.map(arg => {
if (!arg.startsWith('-')) return arg;
}).filter((element) => element !== undefined);

console.log(options, values, vars);

return new Promise(async (resolve) => {
if (args[1] == 'clone') {
term.writeln(`Cloning into '${args[2].split(/(\\|\/)/g).pop()}'...`);
if (values[0] == 'clone') {
let cfg = {
quiet: false,
depth: 1,
noCheckout: false,
noTags: false,
singleBranch: true,
};

if (options.includes('-q') || options.includes('--quiet')) cfg.quiet = true;
if (options.includes('-n') || options.includes('--no-checkout')) cfg.noCheckout = true;
if (options.includes('--no-tags')) cfg.noTags = true;
if (options.includes('--single-branch')) cfg.singleBranch = true;
if (options.includes('--no-single-branch')) cfg.singleBranch = false;

if (vars['depth']) cfg.depth = vars['depth'];
if (vars['shallow-since']) cfg.since = new Date(vars['shallow-since']);
if (vars['shallow-exclude']) cfg.exclude = vars['shallow-exclude'];

if (cfg.quiet !== true) term.writeln(`Cloning into '${values[1].split(/(\\|\/)/g).pop()}'...`);

await git.clone({
fs,
http,
dir: dir.path + '/' + args[2].split(/(\\|\/)/g).pop(),
dir: values[2] ?? dir.path + '/' + values[1].split(/(\\|\/)/g).pop(),
corsProxy: 'https://cors.isomorphic-git.org',
url: args[2],
singleBranch: true,
depth: 1,
onMessage: (e) => term.writeln(e),
url: values[1],
noCheckout: cfg.noCheckout,
singleBranch: cfg.singleBranch,
depth: cfg.depth,
noTags: cfg.noTags,
since: cfg.since,
exclude: cfg.exclude,
onMessage: (e) => {
if (cfg.quiet !== true) term.writeln(e);
},
});
resolve('');
} else if (values[0] == 'init') {
let cfg = {
quiet: false,
bare: false,
defaultBranch: 'master',
};

if (options.includes('-q') || options.includes('--quiet')) cfg.quiet = true;
if (options.includes('--bare')) cfg.bare = true;

if (vars['initial-branch']) cfg.defaultBranch = vars['initial-branch'];
if (vars['separate-git-dir']) cfg.gitdir = vars['separate-git-dir'];

await git.init({
fs,
http,
dir: values[1] ?? dir.path,
bare: cfg.bare,
defaultBranch: cfg.defaultBranch,
gitdir: cfg.gitdir
});

if (cfg.quiet !== true) term.writeln(`Initialized empty Git repository in ${fs.realpathSync(values[1]) ?? dir.path}/.git/`);

resolve('');
} else {
if (options[0] == '--version') {
resolve('git version ' + git.version());
} else if (options[0] == '--help') {
resolve([
`usage: git [--version] [--help] <command> [<args>]`,
``,
`These are common Git commands used in various situations:`,
``,
`start a working area`,
` clone Clone a repository into a new directory`,
` init Create an empty Git repository or reinitialize an existing one`
]);
}
}
});
};
34 changes: 20 additions & 14 deletions public/builtin/apps/scripts/terminal/handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ import sh from 'https://cdn.jsdelivr.net/npm/[email protected]/+esm';
export class CommandsAddon {
_disposables = [];

promptMSG = async () => `${c.blue('')}${c.bgBlue(` flow@${this.user.username}`)}${c.bgCyan(c.blue('') + ` ${this.dir.path}`)}${c.cyan('')} `;
promptMSG = async () => {
if (await this.fs.readdirSync(this.dir.path).includes('.git')) {
return `${c.green('')}${c.bgGreen(` flow@${this.user.username}`)}${c.bgCyan(c.green('') + ` ${this.fs.realpathSync(this.dir.path)}`)}${c.bgBlue(c.cyan(' '))}${c.bgBlue(`󰓁 ${this.fs.readFileSync(this.dir.path + '/.git/HEAD').toString().replaceAll('\n', '').split('ref: refs/heads/')[1]}`)}${c.blue('')} `;
} else {
return `${c.green('')}${c.bgGreen(` flow@${this.user.username}`)}${c.bgCyan(c.green('') + ` ${this.fs.realpathSync(this.dir.path)}`)}${c.cyan('')} `;
}
};

constructor(options, usr, dir) {
this.commandsMap = options.commands;
Expand All @@ -18,6 +24,11 @@ export class CommandsAddon {
this.current = '';

BrowserFS.install(window);
}

activate(term) {
this.terminal = term;

BrowserFS.configure({
fs: 'AsyncMirror',
options: {
Expand All @@ -32,20 +43,15 @@ export class CommandsAddon {
if (e) console.error(e);

this.fs = require('fs');
this.promptMSG = async () => `${c.blue('')}${c.bgBlue(` flow@${this.user.username}`)}${c.bgCyan(c.blue('') + ` ${this.fs.realpathSync(this.dir.path)}`)}${c.cyan('')} `;

this.terminal.prompt = async () => {
this.terminal.write('\r' + await this.promptMSG());
};

this.terminal.writeln('Welcome to FluSH!');
this.terminal.writeln('');
this.terminal.prompt();
});
}

activate(term) {
this.terminal = term;

this.terminal.prompt = async () => {
this.terminal.write('\r' + await this.promptMSG());
};

this.terminal.writeln('Welcome to FluSH!');
this.terminal.writeln('');
this.terminal.prompt();

this.terminal.attachCustomKeyEventHandler(async (key) => {
if (key.code === 'KeyV' && key.ctrlKey && key.type === 'keydown') {
Expand Down
2 changes: 1 addition & 1 deletion public/builtin/apps/terminal.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

<body>
<div id="terminal" style="height: 100vh;"></div>

<script src="/builtin/apps/scripts/terminal.js" type="module" defer></script>
<style>
@font-face {
Expand Down

0 comments on commit 1e1b8af

Please sign in to comment.