1
1
mirror of https://github.com/Eugeny/tabby.git synced 2024-07-14 15:50:31 +03:00

bootstrap 5 WIP (#7891)

New standard theme that follows your chosen terminal colors, Bootstrap 5 & Angular 15 upgrade
This commit is contained in:
Eugene 2023-02-26 20:42:31 +01:00 committed by GitHub
parent 7a8108b20d
commit 1e5cfd1d4b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
215 changed files with 2982 additions and 2447 deletions

View File

@ -1,15 +1,3 @@
parser: '@typescript-eslint/parser'
parserOptions:
project:
- tsconfig.json
- '*/tsconfig.typings.json'
extends:
- 'plugin:@typescript-eslint/all'
- plugin:import/recommended
- plugin:import/typescript
plugins:
- '@typescript-eslint'
- 'import'
settings:
import/resolver:
typescript: true
@ -19,126 +7,148 @@ env:
es6: true
node: true
commonjs: true
rules:
'@typescript-eslint/semi':
- error
- never
'@typescript-eslint/indent':
- error
- 4
'@typescript-eslint/explicit-member-accessibility':
- error
- accessibility: no-public
overrides:
parameterProperties: explicit
'@typescript-eslint/no-require-imports': off
'@typescript-eslint/no-parameter-properties': off
'@typescript-eslint/explicit-function-return-type': off
'@typescript-eslint/no-explicit-any': off
'@typescript-eslint/no-magic-numbers': off
'@typescript-eslint/member-delimiter-style': off
'@typescript-eslint/promise-function-async': off
'@typescript-eslint/require-array-sort-compare': off
'@typescript-eslint/no-floating-promises': off
'@typescript-eslint/prefer-readonly': off
'@typescript-eslint/require-await': off
'@typescript-eslint/strict-boolean-expressions': off
'@typescript-eslint/no-misused-promises':
- error
- checksVoidReturn: false
'@typescript-eslint/typedef': off
'@typescript-eslint/consistent-type-imports': off
'@typescript-eslint/sort-type-union-intersection-members': off
'@typescript-eslint/no-use-before-define':
- error
- classes: false
no-duplicate-imports: error
array-bracket-spacing:
- error
- never
block-scoped-var: error
brace-style: off
'@typescript-eslint/brace-style':
- error
- 1tbs
- allowSingleLine: true
computed-property-spacing:
- error
- never
comma-dangle: off
'@typescript-eslint/comma-dangle':
- error
- always-multiline
curly: error
eol-last: error
eqeqeq:
- error
- smart
max-depth:
- 1
- 5
max-statements:
- 1
- 80
no-multiple-empty-lines: error
no-mixed-spaces-and-tabs: error
no-trailing-spaces: error
'@typescript-eslint/no-unused-vars':
overrides:
- files: '*.mjs'
plugins:
- 'import'
parserOptions:
sourceType: module
ecmaVersion: latest
- files: '*.ts'
parser: '@typescript-eslint/parser'
parserOptions:
project:
- tsconfig.json
- '*/tsconfig.typings.json'
extends:
- 'plugin:@typescript-eslint/all'
- plugin:import/recommended
- plugin:import/typescript
plugins:
- '@typescript-eslint'
- 'import'
rules:
'@typescript-eslint/semi':
- error
- vars: all
args: after-used
argsIgnorePattern: ^_
no-undef: error
no-var: error
object-curly-spacing: off
'@typescript-eslint/object-curly-spacing':
- error
- always
quote-props:
- warn
- as-needed
- keywords: true
numbers: true
quotes: off
'@typescript-eslint/quotes':
- error
- single
- allowTemplateLiterals: true
'@typescript-eslint/no-confusing-void-expression':
- error
- ignoreArrowShorthand: true
'@typescript-eslint/no-non-null-assertion': off
'@typescript-eslint/no-unnecessary-condition':
- error
- allowConstantLoopConditions: true
'@typescript-eslint/restrict-template-expressions': off
'@typescript-eslint/prefer-readonly-parameter-types': off
'@typescript-eslint/no-unsafe-member-access': off
'@typescript-eslint/no-unsafe-call': off
'@typescript-eslint/no-unsafe-return': off
'@typescript-eslint/no-unsafe-assignment': off
'@typescript-eslint/naming-convention': off
'@typescript-eslint/lines-between-class-members':
- error
- exceptAfterSingleLine: true
'@typescript-eslint/dot-notation': off
'@typescript-eslint/no-implicit-any-catch': off
'@typescript-eslint/member-ordering': off
'@typescript-eslint/no-var-requires': off
'@typescript-eslint/no-unsafe-argument': off
'@typescript-eslint/restrict-plus-operands': off
'@typescript-eslint/space-infix-ops': off
'@typescript-eslint/no-type-alias':
- error
- allowAliases: in-unions-and-intersections
allowLiterals: always
allowCallbacks: always
'@typescript-eslint/sort-type-constituents': off
'@typescript-eslint/parameter-properties':
- error
- prefer: parameter-property
'import/no-named-as-default-member': off
'@typescript-eslint/consistent-type-exports': off
'@typescript-eslint/consistent-generic-constructors': off
'keyword-spacing': off
'@typescript-eslint/keyword-spacing': off
- never
'@typescript-eslint/indent':
- error
- 4
'@typescript-eslint/explicit-member-accessibility':
- error
- accessibility: no-public
overrides:
parameterProperties: explicit
'@typescript-eslint/no-require-imports': off
'@typescript-eslint/no-parameter-properties': off
'@typescript-eslint/explicit-function-return-type': off
'@typescript-eslint/no-explicit-any': off
'@typescript-eslint/no-magic-numbers': off
'@typescript-eslint/member-delimiter-style': off
'@typescript-eslint/promise-function-async': off
'@typescript-eslint/require-array-sort-compare': off
'@typescript-eslint/no-floating-promises': off
'@typescript-eslint/prefer-readonly': off
'@typescript-eslint/require-await': off
'@typescript-eslint/strict-boolean-expressions': off
'@typescript-eslint/no-misused-promises':
- error
- checksVoidReturn: false
'@typescript-eslint/typedef': off
'@typescript-eslint/consistent-type-imports': off
'@typescript-eslint/sort-type-union-intersection-members': off
'@typescript-eslint/no-use-before-define':
- error
- classes: false
no-duplicate-imports: error
array-bracket-spacing:
- error
- never
block-scoped-var: error
brace-style: off
'@typescript-eslint/brace-style':
- error
- 1tbs
- allowSingleLine: true
computed-property-spacing:
- error
- never
comma-dangle: off
'@typescript-eslint/comma-dangle':
- error
- always-multiline
curly: error
eol-last: error
eqeqeq:
- error
- smart
max-depth:
- 1
- 5
max-statements:
- 1
- 80
no-multiple-empty-lines: error
no-mixed-spaces-and-tabs: error
no-trailing-spaces: error
'@typescript-eslint/no-unused-vars':
- error
- vars: all
args: after-used
argsIgnorePattern: ^_
no-undef: error
no-var: error
object-curly-spacing: off
'@typescript-eslint/object-curly-spacing':
- error
- always
quote-props:
- warn
- as-needed
- keywords: true
numbers: true
quotes: off
'@typescript-eslint/quotes':
- error
- single
- allowTemplateLiterals: true
'@typescript-eslint/no-confusing-void-expression':
- error
- ignoreArrowShorthand: true
'@typescript-eslint/no-non-null-assertion': off
'@typescript-eslint/no-unnecessary-condition':
- error
- allowConstantLoopConditions: true
'@typescript-eslint/restrict-template-expressions': off
'@typescript-eslint/prefer-readonly-parameter-types': off
'@typescript-eslint/no-unsafe-member-access': off
'@typescript-eslint/no-unsafe-call': off
'@typescript-eslint/no-unsafe-return': off
'@typescript-eslint/no-unsafe-assignment': off
'@typescript-eslint/naming-convention': off
'@typescript-eslint/lines-between-class-members':
- error
- exceptAfterSingleLine: true
'@typescript-eslint/dot-notation': off
'@typescript-eslint/no-implicit-any-catch': off
'@typescript-eslint/member-ordering': off
'@typescript-eslint/no-var-requires': off
'@typescript-eslint/no-unsafe-argument': off
'@typescript-eslint/restrict-plus-operands': off
'@typescript-eslint/space-infix-ops': off
'@typescript-eslint/no-type-alias':
- error
- allowAliases: in-unions-and-intersections
allowLiterals: always
allowCallbacks: always
'@typescript-eslint/sort-type-constituents': off
'@typescript-eslint/parameter-properties':
- error
- prefer: parameter-property
'import/no-named-as-default-member': off
'@typescript-eslint/consistent-type-exports': off
'@typescript-eslint/consistent-generic-constructors': off
'keyword-spacing': off
'@typescript-eslint/keyword-spacing': off

View File

@ -68,7 +68,7 @@ jobs:
run: yarn run build
- name: Prepackage plugins
run: scripts/prepackage-plugins.js
run: scripts/prepackage-plugins.mjs
env:
ARCH: ${{matrix.arch}}
@ -78,7 +78,7 @@ jobs:
- run: ln -s ../../node_modules/electron app/node_modules
- name: Build and sign packages
run: scripts/build-macos.js
run: scripts/build-macos.mjs
if: github.repository == 'Eugeny/tabby' && github.event_name == 'push' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags'))
env:
ARCH: ${{matrix.arch}}
@ -92,7 +92,7 @@ jobs:
# DEBUG: electron-builder,electron-builder:*
- name: Build packages without signing
run: scripts/build-macos.js
run: scripts/build-macos.mjs
if: "! (github.repository == 'Eugeny/tabby' && github.event_name == 'push' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags')))"
env:
ARCH: ${{matrix.arch}}
@ -101,7 +101,7 @@ jobs:
- name: Upload symbols
run: |
sudo npm install -g @sentry/cli --unsafe-perm
./scripts/sentry-upload.js
./scripts/sentry-upload.mjs
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
@ -162,11 +162,11 @@ jobs:
if: matrix.build-arch == 'x64'
- name: Prepackage plugins (x64)
run: scripts/prepackage-plugins.js
run: scripts/prepackage-plugins.mjs
if: ${{matrix.build-arch == 'x64'}}
- name: Build packages (x64)
run: scripts/build-linux.js
run: scripts/build-linux.mjs
if: ${{matrix.build-arch == 'x64'}}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@ -193,8 +193,8 @@ jobs:
cd /github/workspace &&
yarn --network-timeout 1000000 &&
yarn run build &&
scripts/prepackage-plugins.js &&
USE_SYSTEM_FPM=true scripts/build-linux.js"
scripts/prepackage-plugins.mjs &&
USE_SYSTEM_FPM=true scripts/build-linux.mjs"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
KEYGEN_TOKEN: ${{ secrets.KEYGEN_TOKEN }}
@ -217,8 +217,8 @@ jobs:
sed -i '/ \"electron\":/c\ \"electron\": \"17.0.0\",' package.json &&
yarn --network-timeout 1000000 &&
yarn run build &&
scripts/prepackage-plugins.js &&
USE_SYSTEM_FPM=true scripts/build-linux.js"
scripts/prepackage-plugins.mjs &&
USE_SYSTEM_FPM=true scripts/build-linux.mjs"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
KEYGEN_TOKEN: ${{ secrets.KEYGEN_TOKEN }}
@ -228,7 +228,7 @@ jobs:
- name: Upload symbols
run: |
sudo npm install -g @sentry/cli --unsafe-perm
./scripts/sentry-upload.js
./scripts/sentry-upload.mjs
if: matrix.build-arch == 'x64'
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
@ -308,12 +308,12 @@ jobs:
npm i -g yarn@1.19.1
yarn --network-timeout 1000000
yarn run build
node scripts/prepackage-plugins.js
node scripts/prepackage-plugins.mjs
env:
ARCH: ${{matrix.arch}}
- name: Build and sign packages
run: node scripts/build-windows.js
run: node scripts/build-windows.mjs
if: github.repository == 'Eugeny/tabby' && github.event_name == 'push' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags'))
env:
ARCH: ${{matrix.arch}}
@ -324,7 +324,7 @@ jobs:
DEBUG: electron-builder,electron-builder:*
- name: Build packages without signing
run: node scripts/build-windows.js
run: node scripts/build-windows.mjs
if: "!(github.repository == 'Eugeny/tabby' && github.event_name == 'push' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags')))"
env:
ARCH: ${{matrix.arch}}
@ -332,7 +332,7 @@ jobs:
- name: Upload symbols
run: |
npm install @sentry/cli
node scripts/sentry-upload.js
node scripts/sentry-upload.mjs
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}

View File

@ -12,6 +12,7 @@ html.tabby
body { transition: 0.5s background; }
body
style#custom-css
root
app-root
.preload-logo
div

View File

@ -413,7 +413,9 @@ export class Window {
this.touchBarControl.selectedIndex = selectedIndex
})
this.window.webContents.on('new-window', event => event.preventDefault())
this.window.webContents.setWindowOpenHandler(() => {
return { action: 'deny' }
})
ipcMain.on('window-set-disable-vibrancy-while-dragging', (_event, value) => {
this.disableVibrancyWhileDragging = value && this.configStore.hacks?.disableVibrancyWhileDragging

View File

@ -37,17 +37,19 @@
"optionalDependencies": {
"@tabby-gang/windows-blurbehind": "^3.0.0",
"macos-native-processlist": "^2.1.0",
"patch-package": "^6.5.0",
"serialport": "10.5.0",
"serialport-binding-webserialapi": "^1.0.3",
"windows-native-registry": "^3.2.1",
"windows-process-tree": "^0.3.4",
"patch-package": "^6.5.0"
"windows-process-tree": "^0.3.4"
},
"devDependencies": {
"@ngx-translate/core": "^14.0.0",
"@types/mz": "2.7.4",
"@types/node": "18.7.23",
"@types/node": "18.11.19",
"atomically": "^1.7.0",
"ngx-filesize": "^2.0.16"
"filesize": "^9",
"ngx-filesize": "^3.0.1"
},
"peerDependencies": {
"tabby-community-color-schemes": "*",

View File

@ -1,14 +1,12 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { NgModule } from '@angular/core'
import { ApplicationRef, NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
import { ToastrModule } from 'ngx-toastr'
export function getRootModule (plugins: any[]) {
const imports = [
BrowserModule,
...plugins,
NgbModule,
ToastrModule.forRoot({
positionClass: 'toast-bottom-center',
toastClass: 'toast',
@ -27,10 +25,12 @@ export function getRootModule (plugins: any[]) {
@NgModule({
imports,
bootstrap,
}) class RootModule {
ngDoBootstrap () {
ngDoBootstrap (appRef: ApplicationRef) {
(window as any)['requestAnimationFrame'] = window[window['Zone'].__symbol__('requestAnimationFrame')]
const componentDef = bootstrap[0]
appRef.bootstrap(componentDef)
}
}

View File

@ -6,5 +6,4 @@ import '@fortawesome/fontawesome-free/css/solid.css'
import '@fortawesome/fontawesome-free/css/brands.css'
import '@fortawesome/fontawesome-free/css/regular.css'
import '@fortawesome/fontawesome-free/css/fontawesome.css'
import 'ngx-toastr/toastr.css'
import './preload.scss'

View File

@ -39,8 +39,10 @@ async function bootstrap (bootstrapData: BootstrapData, plugins: PluginInfo[], s
const pluginModules = await loadPlugins(plugins, (current, total) => {
(document.querySelector('.progress .bar') as HTMLElement).style.width = `${100 * current / total}%` // eslint-disable-line
})
window['pluginModules'] = pluginModules
const module = getRootModule(pluginModules)
window['rootModule'] = module
const moduleRef = await platformBrowserDynamic([
{ provide: BOOTSTRAP_DATA, useValue: bootstrapData },
]).bootstrapModule(module)

View File

@ -13,10 +13,6 @@ body {
user-select: text;
}
[ngbradiogroup] input[type="radio"] {
display: none;
}
a, button {
&.btn {
display: inline-flex;
@ -53,6 +49,10 @@ a, button {
&>.form-control, &>.input-group {
width: 33%;
}
&>.form-check {
display: flex;
}
}
input[type=range] {
@ -175,19 +175,19 @@ ngb-typeahead-window {
// Windows high contrast mode
@media screen and (forced-colors: active) {
.custom-switch .custom-control-label::before {
.form-switch .form-check-label::before {
background: buttonface;
}
.custom-switch .custom-control-label::after {
.form-switch .form-check-label::after {
background: buttontext;
}
.custom-switch .custom-control-input:checked ~ .custom-control-label::before {
.form-switch .form-check-input:checked ~ .form-check-label::before {
background: activetext;
}
.custom-switch .custom-control-input:checked ~ .custom-control-label::after {
.form-switch .form-check-input:checked ~ .form-check-label::after {
background: canvas;
}

View File

@ -1,6 +0,0 @@
import { Component } from '@angular/core'
@Component({
template: '<app-root></app-root>',
})
export class RootComponent { } // eslint-disable-line @typescript-eslint/no-extraneous-class

View File

@ -8,6 +8,8 @@
box-shadow: 0 1px 0 rgba(0,0,0,.25);
padding: 7px 12px;
background-image: none;
display: block !important;
border: none !important;
width: auto;
flex-basis: auto;
border-radius: 0.5rem;
@ -15,10 +17,12 @@
&.toast-error {
background-color: #BD362F;
color: white !important;
}
&.toast-info {
background-color: #555;
color: #eee !important;
}
}
}

View File

@ -1,8 +1,10 @@
const path = require('path')
const webpack = require('webpack')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
import * as path from 'path'
import wp from 'webpack'
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'
import * as url from 'url'
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
module.exports = {
const config = {
name: 'tabby-main',
target: 'electron-main',
entry: {
@ -55,13 +57,15 @@ module.exports = {
'yargs/yargs': 'commonjs yargs/yargs',
},
plugins: [
new webpack.optimize.ModuleConcatenationPlugin(),
new webpack.DefinePlugin({
new wp.optimize.ModuleConcatenationPlugin(),
new wp.DefinePlugin({
'process.type': '"main"',
}),
],
}
if (process.env.BUNDLE_ANALYZER) {
module.exports.plugins.push(new BundleAnalyzerPlugin())
config.plugins.push(new BundleAnalyzerPlugin())
}
export default () => config

View File

@ -1,7 +1,23 @@
const path = require('path')
const webpack = require('webpack')
import * as fs from 'fs'
import * as path from 'path'
import wp from 'webpack'
import * as url from 'url'
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
module.exports = {
import { AngularWebpackPlugin } from '@ngtools/webpack'
import { createEs2015LinkerPlugin } from '@angular/compiler-cli/linker/babel'
const linkerPlugin = createEs2015LinkerPlugin({
linkerJitMode: true,
fileSystem: {
resolve: path.resolve,
exists: fs.existsSync,
dirname: path.dirname,
relative: path.relative,
readFile: fs.readFileSync,
},
})
export default () => ({
name: 'tabby',
target: 'node',
entry: {
@ -28,13 +44,22 @@ module.exports = {
},
module: {
rules: [
{
test: /\.(m?)js$/,
loader: 'babel-loader',
options: {
plugins: [linkerPlugin],
compact: false,
cacheDirectory: true,
},
resolve: {
fullySpecified: false,
},
},
{
test: /\.ts$/,
use: {
loader: 'ts-loader',
options: {
configFile: path.resolve(__dirname, 'tsconfig.json'),
},
loader: '@ngtools/webpack',
},
},
{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] },
@ -56,9 +81,14 @@ module.exports = {
path: 'commonjs path',
},
plugins: [
new webpack.optimize.ModuleConcatenationPlugin(),
new webpack.DefinePlugin({
new wp.optimize.ModuleConcatenationPlugin(),
new wp.DefinePlugin({
'process.type': '"renderer"',
}),
new AngularWebpackPlugin({
tsconfig: path.resolve(__dirname, 'tsconfig.json'),
directTemplateLoading: false,
jitMode: true,
})
],
}
})

View File

@ -16,6 +16,13 @@
update-notifier "^2.2.0"
yargs "^8.0.2"
"@ngx-translate/core@^14.0.0":
version "14.0.0"
resolved "https://registry.yarnpkg.com/@ngx-translate/core/-/core-14.0.0.tgz#af421d0e1a28376843f0fed375cd2fae7630a5ff"
integrity sha512-UevdwNCXMRCdJv//0kC8h2eSfmi02r29xeE8E9gJ1Al4D4jEJ7eiLPdjslTMc21oJNGguqqWeEVjf64SFtvw2w==
dependencies:
tslib "^2.3.0"
"@serialport/binding-abstract@^9.0.2":
version "9.2.3"
resolved "https://registry.yarnpkg.com/@serialport/binding-abstract/-/binding-abstract-9.2.3.tgz#e7dd273357b6a698af7ad58db6f57f62443a0acb"
@ -140,11 +147,16 @@
dependencies:
"@types/node" "*"
"@types/node@*", "@types/node@18.7.23":
"@types/node@*":
version "18.7.23"
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.23.tgz#75c580983846181ebe5f4abc40fe9dfb2d65665f"
integrity sha512-DWNcCHolDq0ZKGizjx2DZjR/PqsYwAcYUJmfMWqtVU2MBMG5Mo+xFZrhGId5r/O5HOuMPyQEcM6KUBp5lBZZBg==
"@types/node@18.11.19":
version "18.11.19"
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.19.tgz#35e26df9ec441ab99d73e99e9aca82935eea216d"
integrity sha512-YUgMWAQBWLObABqrvx8qKO1enAvBUdjZOAWQ5grBAkp5LQv45jBvYKZ3oFS9iKRCQyFjqw6iuEa1vmFqtxYLZw==
"@types/node@^10.12.18":
version "10.17.60"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b"
@ -1094,10 +1106,10 @@ figgy-pudding@^3.4.1, figgy-pudding@^3.5.1:
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e"
integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==
"filesize@>= 4.0.0":
version "6.3.0"
resolved "https://registry.yarnpkg.com/filesize/-/filesize-6.3.0.tgz#dff53cfb3f104c9e422f346d53be8dbcc971bf11"
integrity sha512-ytx0ruGpDHKWVoiui6+BY/QMNngtDQ/pJaFwfBpQif0J63+E8DLdFyqS3NkKQn7vIruUEpoGD9JUJSg7Kp+I0g==
filesize@^9:
version "9.0.11"
resolved "https://registry.yarnpkg.com/filesize/-/filesize-9.0.11.tgz#4ac3a42c084232dd9b2a1da0107f32d42fcfa5e4"
integrity sha512-gTAiTtI0STpKa5xesyTA9hA3LX4ga8sm2nWRcffEa1L/5vQwb4mj2MdzMkoHoGv4QzfDshQZuYscQSf8c4TKOA==
fill-range@^7.0.1:
version "7.0.1"
@ -2261,13 +2273,12 @@ native-process-working-directory@^1.0.2:
dependencies:
node-addon-api "^3.1.0"
ngx-filesize@^2.0.16:
version "2.0.16"
resolved "https://registry.yarnpkg.com/ngx-filesize/-/ngx-filesize-2.0.16.tgz#fdaba04170edb6cfcdf7be932783cf913b03f016"
integrity sha512-VdaCirE7hSyfQh8ZEmhzNEhbddiTYUHF4V6OX+KyTmnQSVx4hp9kmzDX5YlkIlmClI6wI+LZmH9/q7XS3fsMPA==
ngx-filesize@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/ngx-filesize/-/ngx-filesize-3.0.1.tgz#620933ae181a1128905404e43b26abb99accba90"
integrity sha512-792I4fiG9EEPYjGib2+YTYAzfWIlccfy8uXNSXFFepuAntoS+eijLwnl0m7ajcQuNgbTtwEf9VmYIPN8mS3jqQ==
dependencies:
filesize ">= 4.0.0"
tslib "^2.0.0"
tslib "^2.3.0"
nice-try@^1.0.4:
version "1.0.5"
@ -3717,11 +3728,16 @@ tough-cookie@~2.5.0:
psl "^1.1.28"
punycode "^2.1.1"
tslib@^2.0.0, tslib@^2.1.0:
tslib@^2.1.0:
version "2.3.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01"
integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==
tslib@^2.3.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf"
integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==
tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz"

View File

@ -1,5 +1,5 @@
const fs = require('fs')
const signHook = require('./afterSignHook')
const signHook = require('./afterSignHook.cjs')
module.exports = async function (params) {
// notarize the app on Mac OS only.

View File

@ -3,8 +3,8 @@ appId: org.tabby
productName: Tabby
compression: normal
npmRebuild: false
afterSign: "./build/mac/afterSignHook.js"
afterAllArtifactBuild: "./build/mac/afterBuildHook.js"
afterSign: "./build/mac/afterSignHook.cjs"
afterAllArtifactBuild: "./build/mac/afterBuildHook.cjs"
files:
- '**/*'
- dist

File diff suppressed because it is too large Load Diff

View File

@ -1,17 +1,19 @@
{
"devDependencies": {
"@angular/animations": "^12.0.0",
"@angular/cdk": "^12.2.9",
"@angular/common": "^12.0.0",
"@angular/compiler": "^12.0.0",
"@angular/compiler-cli": "^12.0.0",
"@angular/core": "^12.0.0",
"@angular/forms": "^12.0.0",
"@angular/platform-browser": "^12.0.0",
"@angular/platform-browser-dynamic": "^12.0.0",
"@angular/animations": "^15.1.3",
"@angular/cdk": "^15.1.3",
"@angular/common": "^15.1.3",
"@angular/compiler": "^15.1.3",
"@angular/compiler-cli": "^15.1.3",
"@angular/core": "^15.1.3",
"@angular/forms": "^15.1.3",
"@angular/platform-browser": "^15.1.3",
"@angular/platform-browser-dynamic": "^15.1.3",
"@biesbjerg/ngx-translate-extract-marker": "^1.0.0",
"@fortawesome/fontawesome-free": "^6.2.0",
"@ng-bootstrap/ng-bootstrap": "^10.0.0",
"@ng-bootstrap/ng-bootstrap": "^14.0.1",
"@ngtools/webpack": "^15.1.4",
"@popperjs/core": "^2.11.6",
"@sentry/cli": "^1.74.3",
"@sentry/electron": "^2.5.4",
"@tabby-gang/to-string-loader": "^1.1.7-beta.2",
@ -21,21 +23,21 @@
"@types/fs-extra": "^9.0.13",
"@types/js-yaml": "^4.0.5",
"@types/node": "16.0.1",
"@types/sortablejs": "^1.15.0",
"@types/webpack-env": "^1.18.0",
"@typescript-eslint/eslint-plugin": "^5.45.0",
"@typescript-eslint/parser": "^5.45.0",
"apply-loader": "2.0.0",
"axios": "^0.27.2",
"babel-loader": "^9.1.2",
"browserify-sign": "^4.2.1",
"clone-deep": "^4.0.1",
"compare-versions": "^5",
"core-js": "^3.21.1",
"core-js-pure": "^3.21.1",
"cross-env": "7.0.3",
"css-loader": "^6.7.1",
"css-loader": "^6.7.3",
"deep-equal": "2.0.5",
"electron": "21.3.1",
"electron": "22.3.1",
"electron-builder": "^24.0.0-alpha.1",
"electron-download": "^4.1.1",
"electron-installer-snap": "^5.1.0",
@ -51,10 +53,8 @@
"json-loader": "^0.5.7",
"lru-cache": "^6.0.0",
"macos-release": "^3.1.0",
"ngx-sortablejs": "^11.1.0",
"ngx-toastr": "^14.0.0",
"node-abi": "^3.25.0",
"node-sass": "^7.0.3",
"ngx-toastr": "^16.0.2",
"node-abi": "^3.33.0",
"npmlog": "6.0.2",
"npx": "^10.2.2",
"patch-package": "^6.4.7",
@ -66,49 +66,52 @@
"pug-loader": "^2.4.0",
"pug-static-loader": "2.0.0",
"raw-loader": "4.0.2",
"sass-loader": "^12.6.0",
"rxjs": "^7.5.7",
"sass": "^1.58.0",
"sass-loader": "^13.2.0",
"shell-quote": "^1.7.4",
"shelljs": "0.8.5",
"slugify": "^1.6.5",
"sortablejs": "^1.15.0",
"source-code-pro": "^2.38.0",
"source-map-loader": "^3.0.1",
"source-map-loader": "^4.0.1",
"source-sans-pro": "3.6.0",
"ssh2": "Eugeny/ssh2#9de907d62907d6d45debdcc0ed8dda5b7b19dc7c",
"style-loader": "^3.3.1",
"svg-inline-loader": "^0.8.2",
"thenby": "^1.3.4",
"ts-loader": "^9.4.2",
"tslib": "^2.4.0",
"tsimportlib": "^0.0.3",
"tslib": "^2.5.0",
"typedoc": "^0.22.18",
"typescript": "^4.3.5",
"typescript": "^4.9.5",
"utils-decorators": "^1.10.4",
"val-loader": "4.0.0",
"val-loader": "5.0.1",
"webpack": "^5.75.0",
"webpack-bundle-analyzer": "^4.7.0",
"webpack-cli": "^5.0.0",
"yaml-loader": "0.6.0",
"webpack-cli": "^5.0.1",
"yaml-loader": "0.8.0",
"zone.js": "^0.11.5"
},
"resolutions": {
"*/pug": "^3",
"lzma-native": "^8.0.0",
"*/node-abi": "^3.25.0",
"*/node-abi": "^3.33.0",
"**/graceful-fs": "^4.2.4"
},
"scripts": {
"build": "npm run build:typings && node scripts/build-modules.js",
"build:typings": "node scripts/build-typings.js",
"build": "npm run build:typings && node scripts/build-modules.mjs",
"build:typings": "node scripts/build-typings.mjs",
"watch": "cross-env TABBY_DEV=1 webpack --progress --color --watch",
"start": "cross-env TABBY_DEV=1 electron app -d --inspect",
"start:prod": "electron app --debug",
"prod": "cross-env TABBY_DEV=1 electron app",
"docs": "node scripts/build-docs.js",
"docs": "node scripts/build-docs.mjs",
"lint": "eslint --ext ts */src */lib",
"postinstall": "patch-package && node ./scripts/install-deps.js && node ./scripts/build-native.js",
"postinstall": "patch-package && node ./scripts/install-deps.mjs && node ./scripts/build-native.mjs",
"i18n:pull": "crowdin pull --skip-untranslated-strings",
"i18n:extract": "node scripts/i18n-extract.js",
"i18n:extract": "node scripts/i18n-extract.mjs",
"i18n:push": "crowdin push"
},
"type": "module",
"private": true
}

View File

@ -1,7 +1,7 @@
#!/usr/bin/env node
const sh = require('shelljs')
const vars = require('./vars')
const log = require('npmlog')
import sh from 'shelljs'
import * as vars from './vars.mjs'
import log from 'npmlog'
vars.packagesWithDocs.forEach(([dest, src]) => {
log.info('docs', src)

View File

@ -1,7 +1,7 @@
#!/usr/bin/env node
/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */
const builder = require('electron-builder').build
const vars = require('./vars')
import { build as builder } from 'electron-builder'
import * as vars from './vars.mjs'
const isTag = (process.env.GITHUB_REF || '').startsWith('refs/tags/')

View File

@ -1,7 +1,7 @@
#!/usr/bin/env node
/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */
const builder = require('electron-builder').build
const vars = require('./vars')
import { build as builder } from 'electron-builder'
import * as vars from './vars.mjs'
const isTag = (process.env.GITHUB_REF || '').startsWith('refs/tags/')

View File

@ -1,22 +0,0 @@
#!/usr/bin/env node
const vars = require('./vars')
const log = require('npmlog')
const webpack = require('webpack')
const { promisify } = require('util')
const configs = [
'../app/webpack.main.config.js',
'../app/webpack.config.js',
...vars.allPackages.map(x => `../${x}/webpack.config.js`),
]
;(async () => {
for (const c of configs) {
log.info('build', c)
const stats = await promisify(webpack)(require(c))
console.log(stats.toString({ colors: true }))
if (stats.hasErrors()) {
process.exit(1)
}
}
})()

22
scripts/build-modules.mjs Executable file
View File

@ -0,0 +1,22 @@
#!/usr/bin/env node
import * as vars from './vars.mjs'
import log from 'npmlog'
import webpack from 'webpack'
import { promisify } from 'node:util'
const configs = [
'../app/webpack.config.main.mjs',
'../app/webpack.config.mjs',
...vars.allPackages.map(x => `../${x}/webpack.config.mjs`),
]
;(async () => {
for (const c of configs) {
log.info('build', c)
const stats = await promisify(webpack)((await import(c)).default())
console.log(stats.toString({ colors: true }))
if (stats.hasErrors()) {
process.exit(1)
}
}
})()

View File

@ -1,7 +1,11 @@
#!/usr/bin/env node
const rebuild = require('electron-rebuild').default
const path = require('path')
const vars = require('./vars')
import { rebuild } from 'electron-rebuild'
import * as path from 'path'
import * as vars from './vars.mjs'
import * as url from 'url'
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
if (process.platform === 'win32' || process.platform === 'linux') {
process.env.ARCH = ((process.env.ARCH || process.arch) === 'arm') ? 'armv7l' : process.env.ARCH || process.arch

View File

@ -1,7 +1,7 @@
#!/usr/bin/env node
const sh = require('shelljs')
const vars = require('./vars')
const log = require('npmlog')
import sh from 'shelljs'
import * as vars from './vars.mjs'
import log from 'npmlog'
vars.builtinPlugins.forEach(plugin => {
log.info('typings', plugin)

View File

@ -1,7 +1,7 @@
#!/usr/bin/env node
/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */
const builder = require('electron-builder').build
const vars = require('./vars')
import { build as builder } from 'electron-builder'
import * as vars from './vars.mjs'
const isTag = (process.env.GITHUB_REF || process.env.BUILD_SOURCEBRANCH || '').startsWith('refs/tags/')

View File

@ -1,7 +1,12 @@
#!/usr/bin/env node
const jsYaml = require('js-yaml')
const fs = require('fs')
const path = require('path')
import jsYaml from 'js-yaml'
import fs from 'node:fs'
import path from 'node:path'
import * as url from 'url'
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
const metadata = jsYaml.load(fs.readFileSync(path.resolve(__dirname, '../node_modules/@fortawesome/fontawesome-free/metadata/icons.yml')))
let result = {}

View File

@ -1,9 +1,9 @@
#!/usr/bin/env node
const sh = require('shelljs')
const fs = require('fs/promises')
const vars = require('./vars')
const log = require('npmlog')
const { GettextExtractor, JsExtractors, HtmlExtractors } = require('gettext-extractor')
import sh from 'shelljs'
import fs from 'node:fs/promises'
import * as vars from './vars.mjs'
import log from 'npmlog'
import { GettextExtractor, JsExtractors, HtmlExtractors } from 'gettext-extractor'
let extractor = new GettextExtractor()

View File

@ -1,7 +1,7 @@
#!/usr/bin/env node
const sh = require('shelljs')
const vars = require('./vars')
const log = require('npmlog')
import sh from 'shelljs'
import * as vars from './vars.mjs'
import log from 'npmlog'
log.info('patch')
sh.exec(`yarn patch-package`, { fatal: true })

View File

@ -1,10 +1,14 @@
#!/usr/bin/env node
const rebuild = require('electron-rebuild').default
const sh = require('shelljs')
const path = require('path')
const fs = require('fs')
const vars = require('./vars')
const log = require('npmlog')
import { rebuild } from 'electron-rebuild'
import sh from 'shelljs'
import path from 'node:path'
import fs from 'node:fs'
import * as vars from './vars.mjs'
import log from 'npmlog'
import * as url from 'url'
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
let target = path.resolve(__dirname, '../builtin-plugins')
sh.mkdir('-p', target)

View File

@ -1,8 +1,8 @@
#!/usr/bin/env node
const sh = require('shelljs')
const vars = require('./vars')
const log = require('npmlog')
const { execSync } = require('child_process')
import sh from 'shelljs'
import * as vars from './vars.mjs'
import log from 'npmlog'
import { execSync } from 'child_process'
vars.allPackages.forEach(plugin => {
log.info('bump', plugin)

View File

@ -1,6 +1,6 @@
#!/usr/bin/env node
const sh = require('shelljs')
const vars = require('./vars')
import sh from 'shelljs'
import * as vars from './vars.mjs'
const sentryCli = process.platform === 'win32' ? 'node_modules\\.bin\\sentry-cli.cmd' : 'sentry-cli'

View File

@ -1,19 +1,22 @@
const path = require('path')
const fs = require('fs')
const semver = require('semver')
const childProcess = require('child_process')
import * as path from 'path'
import * as fs from 'fs'
import * as semver from 'semver'
import * as childProcess from 'child_process'
import * as url from 'url'
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
const electronInfo = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../node_modules/electron/package.json')))
exports.version = childProcess.execSync('git describe --tags', { encoding:'utf-8' })
exports.version = exports.version.substring(1).trim()
exports.version = exports.version.replace('-', '-c')
export let version = childProcess.execSync('git describe --tags', { encoding:'utf-8' })
version = version.substring(1).trim()
version = version.replace('-', '-c')
if (exports.version.includes('-c')) {
exports.version = semver.inc(exports.version, 'prepatch').replace('-0', `-nightly.${process.env.REV ?? 0}`)
if (version.includes('-c')) {
version = semver.inc(version, 'prepatch').replace('-0', `-nightly.${process.env.REV ?? 0}`)
}
exports.builtinPlugins = [
export const builtinPlugins = [
'tabby-core',
'tabby-settings',
'tabby-terminal',
@ -28,26 +31,26 @@ exports.builtinPlugins = [
'tabby-linkifier',
]
exports.packagesWithDocs = [
export const packagesWithDocs = [
['.', 'tabby-core'],
['terminal', 'tabby-terminal'],
['local', 'tabby-local'],
['settings', 'tabby-settings'],
]
exports.allPackages = [
...exports.builtinPlugins,
export const allPackages = [
...builtinPlugins,
'web',
'tabby-web-demo',
]
exports.bundledModules = [
export const bundledModules = [
'@angular',
'@ng-bootstrap',
]
exports.electronVersion = electronInfo.version
export const electronVersion = electronInfo.version
exports.keygenConfig = {
export const keygenConfig = {
provider: 'keygen',
account: 'a06315f2-1031-47c6-9181-e92a20ec815e',
channel: 'stable',
@ -70,6 +73,6 @@ exports.keygenConfig = {
}[process.platform],
}
if (!exports.keygenConfig.product) {
if (!keygenConfig.product) {
throw new Error(`Unrecognized platform ${process.platform}/${process.env.ARCH ?? process.arch}`)
}

View File

@ -1,6 +0,0 @@
const config = require('../webpack.plugin.config')
module.exports = config({
name: 'community-color-schemes',
dirname: __dirname,
})
module.exports.module.rules.push({ test: /[\\\/]schemes[\\\/]/, use: 'raw-loader' })

View File

@ -0,0 +1,14 @@
import * as path from 'path'
import * as url from 'url'
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
import config from '../webpack.plugin.config.mjs'
export default () => {
const cfg = config({
name: 'community-color-schemes',
dirname: __dirname,
})
cfg.module.rules.push({ test: /[\\\/]schemes[\\\/]/, use: 'raw-loader' })
return cfg
}

View File

@ -1,6 +1,6 @@
{
"name": "tabby-core",
"version": "1.0.189-nightly.2",
"version": "1.0.189-nightly.0",
"description": "Tabby core",
"keywords": [
"tabby-builtin-plugin"
@ -17,15 +17,13 @@
"author": "Eugene Pankov",
"license": "MIT",
"devDependencies": {
"@ngx-translate/core": "^14.0.0",
"bootstrap": "^4.1.3",
"bootstrap": "^5.3.0-alpha.1",
"color": "^4.2.3",
"deepmerge": "^4.1.1",
"fuzzy-search": "^3.2.1",
"js-yaml": "^4.0.0",
"messageformat": "^2.3.0",
"mixpanel": "^0.17.0",
"ngx-filesize": "^2.0.16",
"ngx-perfect-scrollbar": "^10.1.0",
"ngx-translate-messageformat-compiler": "^4.11.0",
"readable-stream": "4.2.0",
"uuid": "^9.0.0"

View File

@ -36,6 +36,7 @@ export { TabsService, NewTabParameters, TabComponentType } from '../services/tab
export { UpdaterService } from '../services/updater.service'
export { VaultService, Vault, VaultSecret, VaultFileSecret, VAULT_SECRET_TYPE_FILE, StoredVault, VaultSecretKey } from '../services/vault.service'
export { FileProvidersService } from '../services/fileProviders.service'
export { LocaleService, TranslateServiceWrapper as TranslateService } from '../services/locale.service'
export { LocaleService } from '../services/locale.service'
export { TranslateService } from '@ngx-translate/core'
export * from '../utils'
export { UTF8Splitter } from '../utfSplitter'

View File

@ -13,4 +13,5 @@ export abstract class Theme {
macOSWindowButtonsInsetX?: number
macOSWindowButtonsInsetY?: number
followsColorScheme?: boolean
}

View File

@ -55,8 +55,8 @@ function makeTabAnimation (dimension: string, size: number) {
/** @hidden */
@Component({
selector: 'app-root',
template: require('./appRoot.component.pug'),
styles: [require('./appRoot.component.scss')],
templateUrl: './appRoot.component.pug',
styleUrls: ['./appRoot.component.scss'],
animations: [
trigger('animateTab', makeTabAnimation('width', 200)),
],
@ -90,6 +90,7 @@ export class AppRootComponent {
ngbModal: NgbModal,
_themes: ThemesService,
) {
// document.querySelector('app-root')?.remove()
this.logger = log.create('main')
this.logger.info('v', platform.getAppVersion())

View File

@ -19,6 +19,7 @@ export interface GetRecoveryTokenOptions {
/**
* Abstract base class for custom tab components
*/
// @Component({ template: '' })
export abstract class BaseTabComponent extends BaseComponent {
/**
* Parent tab (usually a SplitTabComponent)

View File

@ -6,9 +6,9 @@ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'
@Component({
selector: 'checkbox',
template: `
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" [(ngModel)]='model'>
<label class="custom-control-label">{{text}}</label>
<div class="form-check form-checkbox">
<input type="checkbox" class="form-check-input" [(ngModel)]='model'>
<label class="form-check-label">{{text}}</label>
</div>
`,
providers: [

View File

@ -5,5 +5,5 @@ i.icon(
)
.icon(
[fastHtmlBind]='icon',
*ngIf='isHTML'
*ngIf='isHTML && icon'
)

View File

@ -5,8 +5,8 @@ import { BaseComponent } from './base.component'
/** @hidden */
@Component({
selector: 'profile-icon',
template: require('./profileIcon.component.pug'),
styles: [require('./profileIcon.component.scss')],
templateUrl:'./profileIcon.component.pug',
styleUrls: ['./profileIcon.component.scss'],
})
export class ProfileIconComponent extends BaseComponent {
@Input() icon?: string

View File

@ -14,6 +14,6 @@
[(ngModel)]='remember',
text='Remember'
)
button.btn.btn-primary.ml-auto(
button.btn.btn-primary.ms-auto(
(click)='ok()',
) OK

View File

@ -3,10 +3,11 @@ import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
/** @hidden */
@Component({
template: require('./promptModal.component.pug'),
templateUrl:'./promptModal.component.pug',
})
export class PromptModalComponent {
@Input() value: string
@Input() prompt: string|undefined
@Input() password: boolean
@Input() remember: boolean
@Input() showRememberCheckbox: boolean

View File

@ -5,7 +5,7 @@ import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
/** @hidden */
@Component({
selector: 'rename-tab-modal',
template: require('./renameTabModal.component.pug'),
templateUrl:'./renameTabModal.component.pug',
})
export class RenameTabModalComponent {
@Input() value: string

View File

@ -3,7 +3,7 @@ import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
/** @hidden */
@Component({
template: require('./safeModeModal.component.pug'),
templateUrl:'./safeModeModal.component.pug',
})
export class SafeModeModalComponent {
@Input() error: Error

View File

@ -21,14 +21,14 @@
[icon]='option.icon',
[color]='option.color'
)
.title.mr-2 {{getOptionText(option)}}
.title.me-2 {{getOptionText(option)}}
.description.no-wrap.text-muted(
*ngIf='option.description !== getOptionText(option)'
) {{option.description}}
.ml-auto
.no-wrap.badge.badge-secondary.text-muted.ml-2(*ngIf='selectedIndex == i && canEditSelected()')
.ms-auto
.no-wrap.badge.text-bg-secondary.text-muted.ms-2(*ngIf='selectedIndex == i && canEditSelected()')
span Backspace
i.fas.fa-pencil.ml-1
.no-wrap.badge.badge-secondary.text-muted.ml-2(*ngIf='selectedIndex == i')
i.fas.fa-pencil.ms-1
.no-wrap.badge.text-bg-secondary.text-muted.ms-2(*ngIf='selectedIndex == i')
span Enter
i.fas.fa-arrow-right.ml-1
i.fas.fa-arrow-right.ms-1

View File

@ -7,8 +7,8 @@ import { SelectorOption } from '../api/selector'
/** @hidden */
@Component({
selector: 'selector-modal',
template: require('./selectorModal.component.pug'),
styles: [require('./selectorModal.component.scss')],
templateUrl:'./selectorModal.component.pug',
styleUrls: ['./selectorModal.component.scss'],
})
export class SelectorModalComponent<T> {
@Input() options: SelectorOption<T>[]

View File

@ -1,11 +1,12 @@
import { HostBinding, ElementRef } from '@angular/core'
import { HostBinding, ElementRef, Component } from '@angular/core'
import { BaseComponent } from './base.component'
@Component({})
export abstract class SelfPositioningComponent extends BaseComponent {
@HostBinding('style.left') cssLeft: string
@HostBinding('style.top') cssTop: string
@HostBinding('style.width') cssWidth: string | null
@HostBinding('style.height') cssHeight: string | null
@HostBinding('style.left') cssLeft = ''
@HostBinding('style.top') cssTop = ''
@HostBinding('style.width') cssWidth: string | null = null
@HostBinding('style.height') cssHeight: string | null = null
constructor (protected element: ElementRef) { super() }

View File

@ -186,7 +186,7 @@ export type SplitDropZoneInfo = {
>
</split-tab-pane-label>
`,
styles: [require('./splitTab.component.scss')],
styleUrls: ['./splitTab.component.scss'],
})
export class SplitTabComponent extends BaseTabComponent implements AfterViewInit, OnDestroy {
static DIRECTIONS: SplitDirection[] = ['t', 'r', 'b', 'l']

View File

@ -18,7 +18,7 @@ import { SplitDropZoneInfo, SplitTabComponent } from './splitTab.component'
>
</div>
`,
styles: [require('./splitTabDropZone.component.scss')],
styleUrls: ['./splitTabDropZone.component.scss'],
})
export class SplitTabDropZoneComponent extends SelfPositioningComponent {
@Input() dropZone: SplitDropZoneInfo

View File

@ -15,11 +15,11 @@ import { SelfPositioningComponent } from './selfPositioning.component'
(cdkDragStarted)='onTabDragStart(tab)'
(cdkDragEnded)='onTabDragEnd()'
>
<i class="fa fa-window-maximize mr-3"></i>
<i class="fa fa-window-maximize me-3"></i>
<label>{{tab.title}}</label>
</div>
`,
styles: [require('./splitTabPaneLabel.component.scss')],
styleUrls: ['./splitTabPaneLabel.component.scss'],
})
export class SplitTabPaneLabelComponent extends SelfPositioningComponent {
@Input() tab: BaseTabComponent

View File

@ -3,7 +3,6 @@
position: absolute;
z-index: 5;
transition: 0.125s background;
background: rgba(0, 0, 0, .2);
&.v {
cursor: ns-resize;
@ -16,8 +15,4 @@
width: 10px;
margin-left: -5px;
}
&:hover, &.active {
background: rgba(255, 255, 255, .125);
}
}

View File

@ -7,7 +7,7 @@ import { SplitContainer } from './splitTab.component'
@Component({
selector: 'split-tab-spanner',
template: '',
styles: [require('./splitTabSpanner.component.scss')],
styleUrls: ['./splitTabSpanner.component.scss'],
})
export class SplitTabSpannerComponent extends SelfPositioningComponent {
@Input() container: SplitContainer

View File

@ -1,10 +1,10 @@
div
.mt-5
.tabby-logo
h1.tabby-title Tabby
sup α
.list-group.mb-4
a.list-group-item.list-group-item-action.d-flex(
a.list-group-item.list-group-item-action.d-flex.pt-3.pb-3(
*ngFor='let command of commands; trackBy: buttonsTrackBy',
(click)='command.run()',
)
@ -12,11 +12,11 @@ div
span {{command.label}}
footer.d-flex.align-items-center
.btn-group.mr-auto
button.btn.btn-dark((click)='homeBase.openGitHub()')
.btn-group.me-auto
button.btn.btn-link((click)='homeBase.openGitHub()')
i.fab.fa-github
span GitHub
button.btn.btn-dark((click)='homeBase.reportBug()')
button.btn.btn-link((click)='homeBase.reportBug()')
i.fas.fa-bug
span(translate) Report a problem

View File

@ -7,8 +7,8 @@ import { Command, CommandLocation } from '../api/commands'
/** @hidden */
@Component({
selector: 'start-page',
template: require('./startPage.component.pug'),
styles: [require('./startPage.component.scss')],
templateUrl:'./startPage.component.pug',
styleUrls: ['./startPage.component.scss'],
})
export class StartPageComponent {
version: string
@ -28,7 +28,8 @@ export class StartPageComponent {
return this.domSanitizer.bypassSecurityTrustHtml(icon ?? '')
}
buttonsTrackBy (btn: Command): any {
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
buttonsTrackBy (_, btn: Command): any {
return btn.label + btn.icon
}
}

View File

@ -7,9 +7,4 @@
>* {
flex: auto;
}
> perfect-scrollbar {
width: auto;
height: auto;
}
}

View File

@ -8,9 +8,9 @@ import { BaseTabComponent } from '../components/baseTab.component'
template: `
<ng-template #placeholder></ng-template>
`,
styles: [
require('./tabBody.component.scss'),
require('./tabBody.deep.component.css'),
styleUrls: [
'./tabBody.component.scss',
'./tabBody.deep.component.css',
],
})
export class TabBodyComponent implements OnChanges {

View File

@ -8,7 +8,7 @@
profile-icon(
*ngIf='config.store.terminal.showTabProfileIcon && tab.icon',
[icon]='tab.icon',
[color]='tab.color'
[color]='tab.color ?? undefined'
)
.name(

View File

@ -144,6 +144,5 @@ $tabs-height: 38px;
right: 10px;
bottom: 4px;
height: 2px;
z-index: -1;
}
}

View File

@ -15,8 +15,8 @@ import { PlatformService } from '../api/platform'
/** @hidden */
@Component({
selector: 'tab-header',
template: require('./tabHeader.component.pug'),
styles: [require('./tabHeader.component.scss')],
templateUrl:'./tabHeader.component.pug',
styleUrls: ['./tabHeader.component.scss'],
})
export class TabHeaderComponent extends BaseComponent {
@Input() index: number

View File

@ -1,2 +1,2 @@
.title((dblclick)='hostApp.toggleMaximize()') Tabby
.title((dblclick)='hostWindow.toggleMaximize()') Tabby
window-controls

View File

@ -1,9 +1,12 @@
import { Component } from '@angular/core'
import { HostWindowService } from '../api'
/** @hidden */
@Component({
selector: 'title-bar',
template: require('./titleBar.component.pug'),
styles: [require('./titleBar.component.scss')],
templateUrl:'./titleBar.component.pug',
styleUrls: ['./titleBar.component.scss'],
})
export class TitleBarComponent { } // eslint-disable-line @typescript-eslint/no-extraneous-class
export class TitleBarComponent {
constructor (public hostWindow: HostWindowService) { }
}

View File

@ -4,17 +4,19 @@
$height: 30px;
$padding: 2px;
display: inline-flex;
overflow: visible;
border-radius: 3px;
line-height: $height;
height: $height;
transition: 0.25s opacity;
align-items: center;
overflow: hidden;
padding-right: 10px;
padding-left: 10px;
margin-left: -10px;
.form-check {
margin: 0;
}
&.disabled {
opacity: 0.5;
}
@ -22,4 +24,8 @@
* {
cursor: pointer;
}
label {
display: none;
}
}

View File

@ -6,12 +6,12 @@ import { CheckboxComponent } from './checkbox.component'
@Component({
selector: 'toggle',
template: `
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" [(ngModel)]='model'>
<label class="custom-control-label"></label>
<div class="form-check form-switch">
<input type="checkbox" class="form-check-input" [(ngModel)]='model'>
<label class="cform-check-label"></label>
</div>
`,
styles: [require('./toggle.component.scss')],
styleUrls: ['./toggle.component.scss'],
providers: [
{ provide: NG_VALUE_ACCESSOR, useExisting: ToggleComponent, multi: true },
],

View File

@ -1,6 +1,6 @@
.d-flex.align-items-center
.dropdown-header(translate) File transfers
button.btn.btn-link.ml-auto((click)='removeAll(); $event.stopPropagation()') !{require('../icons/times.svg')}
button.btn.btn-link.ms-auto((click)='removeAll(); $event.stopPropagation()') !{require('../icons/times.svg')}
.transfer(*ngFor='let transfer of transfers', (click)='showTransfer(transfer)')
.icon(*ngIf='isDownload(transfer)') !{require('../icons/download.svg')}
.icon(*ngIf='!isDownload(transfer)') !{require('../icons/upload.svg')}

View File

@ -5,8 +5,8 @@ import { FileDownload, FileTransfer, PlatformService } from '../api/platform'
/** @hidden */
@Component({
selector: 'transfers-menu',
template: require('./transfersMenu.component.pug'),
styles: [require('./transfersMenu.component.scss')],
templateUrl:'./transfersMenu.component.pug',
styleUrls: ['./transfersMenu.component.scss'],
})
export class TransfersMenuComponent {
@Input() transfers: FileTransfer[]

View File

@ -1,7 +1,7 @@
.modal-body
.d-flex.align-items-center.mb-3
h3.m-0(translate) Vault is locked
.ml-auto(ngbDropdown, placement='bottom-right')
.ms-auto(ngbDropdown, placement='bottom-right')
button.btn.btn-link(ngbDropdownToggle, (click)='$event.stopPropagation()')
span(
*ngIf='rememberFor',
@ -29,6 +29,5 @@
(keyup.enter)='ok()',
(keyup.esc)='cancel()',
)
.input-group-append
button.btn.btn-secondary((click)='ok()', *ngIf='passphrase')
i.fas.fa-check
button.btn.btn-secondary((click)='ok()', *ngIf='passphrase')
i.fas.fa-check

View File

@ -3,7 +3,7 @@ import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
/** @hidden */
@Component({
template: require('./unlockVaultModal.component.pug'),
templateUrl:'./unlockVaultModal.component.pug',
})
export class UnlockVaultModalComponent {
passphrase: string

View File

@ -8,8 +8,8 @@ import { LocaleService } from '../services/locale.service'
/** @hidden */
@Component({
selector: 'welcome-page',
template: require('./welcomeTab.component.pug'),
styles: [require('./welcomeTab.component.scss')],
templateUrl:'./welcomeTab.component.pug',
styleUrls: ['./welcomeTab.component.scss'],
})
export class WelcomeTabComponent extends BaseTabComponent {
enableGlobalHotkey = true

View File

@ -6,8 +6,8 @@ import { AppService } from '../services/app.service'
/** @hidden */
@Component({
selector: 'window-controls',
template: require('./windowControls.component.pug'),
styles: [require('./windowControls.component.scss')],
templateUrl:'./windowControls.component.pug',
styleUrls: ['./windowControls.component.scss'],
})
export class WindowControlsComponent {
constructor (public hostWindow: HostWindowService, public app: AppService) { }

View File

@ -4,10 +4,10 @@ import { Platform } from './api/hostApp'
/** @hidden */
export class CoreConfigProvider extends ConfigProvider {
platformDefaults = {
[Platform.macOS]: require('./configDefaults.macos.yaml'),
[Platform.Windows]: require('./configDefaults.windows.yaml'),
[Platform.Linux]: require('./configDefaults.linux.yaml'),
[Platform.Web]: require('./configDefaults.web.yaml'),
[Platform.macOS]: require('./configDefaults.macos.yaml').default,
[Platform.Windows]: require('./configDefaults.windows.yaml').default,
[Platform.Linux]: require('./configDefaults.linux.yaml').default,
[Platform.Web]: require('./configDefaults.web.yaml').default,
}
defaults = require('./configDefaults.yaml')
defaults = require('./configDefaults.yaml').default
}

View File

@ -36,8 +36,7 @@ hotkeys:
- '⌘-8'
tab-9:
- '⌘-9'
tab-10:
- '⌘-0'
tab-10: []
duplicate-tab: []
restart-tab: []
explode-tab:

File diff suppressed because one or more lines are too long

View File

@ -1,11 +1,9 @@
import { NgModule, ModuleWithProviders, LOCALE_ID } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'
import { CommonModule } from '@angular/common'
import { FormsModule } from '@angular/forms'
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
import { PerfectScrollbarModule, PERFECT_SCROLLBAR_CONFIG } from 'ngx-perfect-scrollbar'
import { NgxFilesizeModule } from 'ngx-filesize'
import { SortablejsModule } from 'ngx-sortablejs'
import { DragDropModule } from '@angular/cdk/drag-drop'
import { TranslateModule, TranslateCompiler, TranslateService } from '@ngx-translate/core'
import { TranslateMessageFormatCompiler, MESSAGE_FORMAT_CONFIG } from 'ngx-translate-messageformat-compiler'
@ -43,10 +41,10 @@ import { AppService } from './services/app.service'
import { ConfigService } from './services/config.service'
import { VaultFileProvider } from './services/vault.service'
import { HotkeysService } from './services/hotkeys.service'
import { LocaleService, TranslateServiceWrapper } from './services/locale.service'
import { LocaleService } from './services/locale.service'
import { CommandService } from './services/commands.service'
import { StandardTheme, StandardCompactTheme, PaperTheme } from './theme'
import { StandardTheme, StandardCompactTheme, PaperTheme, NewTheme } from './theme'
import { CoreConfigProvider } from './config'
import { AppHotkeyProvider } from './hotkeys'
import { TaskCompletionContextMenu, CommonOptionsContextMenu, TabManagementContextMenu, ProfilesContextMenu } from './tabContextMenu'
@ -54,8 +52,6 @@ import { LastCLIHandler, ProfileCLIHandler } from './cli'
import { SplitLayoutProfilesService } from './profiles'
import { CoreCommandProvider } from './commands'
import 'perfect-scrollbar/css/perfect-scrollbar.css'
export function TranslateMessageFormatCompilerFactory (): TranslateMessageFormatCompiler {
return new TranslateMessageFormatCompiler()
}
@ -65,6 +61,7 @@ const PROVIDERS = [
{ provide: Theme, useClass: StandardTheme, multi: true },
{ provide: Theme, useClass: StandardCompactTheme, multi: true },
{ provide: Theme, useClass: PaperTheme, multi: true },
{ provide: Theme, useClass: NewTheme, multi: true },
{ provide: ConfigProvider, useClass: CoreConfigProvider, multi: true },
{ provide: TabContextMenuItemProvider, useClass: CommonOptionsContextMenu, multi: true },
{ provide: TabContextMenuItemProvider, useClass: TabManagementContextMenu, multi: true },
@ -73,7 +70,6 @@ const PROVIDERS = [
{ provide: TabRecoveryProvider, useExisting: SplitTabRecoveryProvider, multi: true },
{ provide: CLIHandler, useClass: ProfileCLIHandler, multi: true },
{ provide: CLIHandler, useClass: LastCLIHandler, multi: true },
{ provide: PERFECT_SCROLLBAR_CONFIG, useValue: { suppressScrollX: true } },
{ provide: FileProvider, useClass: VaultFileProvider, multi: true },
{ provide: ProfileProvider, useExisting: SplitLayoutProfilesService, multi: true },
{ provide: CommandProvider, useExisting: CoreCommandProvider, multi: true },
@ -86,24 +82,24 @@ const PROVIDERS = [
provide: MESSAGE_FORMAT_CONFIG,
useValue: LocaleService.allLanguages.map(x => x.code),
},
{
provide: TranslateService,
useClass: TranslateServiceWrapper,
},
]
/** @hidden */
@NgModule({
imports: [
BrowserModule,
BrowserAnimationsModule,
CommonModule,
FormsModule,
NgbModule,
NgxFilesizeModule,
PerfectScrollbarModule,
DragDropModule,
SortablejsModule.forRoot({ animation: 150 }),
TranslateModule,
TranslateModule.forRoot({
defaultLanguage: 'en',
compiler: {
provide: TranslateCompiler,
useFactory: TranslateMessageFormatCompilerFactory,
},
}),
],
declarations: [
AppRootComponent,
@ -132,16 +128,8 @@ const PROVIDERS = [
CdkAutoDropGroup,
ProfileIconComponent,
],
entryComponents: [
PromptModalComponent,
RenameTabModalComponent,
SafeModeModalComponent,
SelectorModalComponent,
SplitTabComponent,
UnlockVaultModalComponent,
WelcomeTabComponent,
],
exports: [
AppRootComponent,
CheckboxComponent,
ToggleComponent,
PromptModalComponent,
@ -149,7 +137,6 @@ const PROVIDERS = [
DropZoneDirective,
FastHtmlBindDirective,
AlwaysVisibleTypeaheadDirective,
SortablejsModule,
DragDropModule,
TranslateModule,
CdkAutoDropGroup,
@ -239,18 +226,10 @@ export default class AppModule { // eslint-disable-line @typescript-eslint/no-ex
}
static forRoot (): ModuleWithProviders<AppModule> {
const translateModule = TranslateModule.forRoot({
defaultLanguage: 'en',
compiler: {
provide: TranslateCompiler,
useFactory: TranslateMessageFormatCompilerFactory,
},
})
return {
ngModule: AppModule,
providers: [
...PROVIDERS,
...translateModule.providers!.filter(x => x !== TranslateService),
],
}
}

View File

@ -12,7 +12,7 @@ export class CommandService {
private app: AppService,
private translate: TranslateService,
@Optional() @Inject(TabContextMenuItemProvider) protected contextMenuProviders: TabContextMenuItemProvider[],
@Inject(ToolbarButtonProvider) private toolbarButtonProviders: ToolbarButtonProvider[],
@Optional() @Inject(ToolbarButtonProvider) private toolbarButtonProviders: ToolbarButtonProvider[],
@Inject(CommandProvider) private commandProviders: CommandProvider[],
) {
this.contextMenuProviders.sort((a, b) => a.weight - b.weight)

View File

@ -236,11 +236,13 @@ export class ConfigService {
*
* @typeparam T Base provider type
*/
enabledServices<T extends object> (services: T[]): T[] { // eslint-disable-line @typescript-eslint/ban-types
enabledServices<T extends object> (services: T[]|undefined): T[] { // eslint-disable-line @typescript-eslint/ban-types
if (!services) {
return []
}
if (!this.servicesCache) {
this.servicesCache = {}
const ngModule = window['rootModule'].ɵinj
for (const imp of ngModule.imports) {
for (const imp of window['pluginModules']) {
const module = imp.ngModule || imp
if (module.ɵinj?.providers) {
this.servicesCache[module.pluginName] = module.ɵinj.providers.map(provider => {

View File

@ -55,24 +55,6 @@ function flattenMessageFormatTranslation (po: any) {
return translation
}
@Injectable({ providedIn: 'root' })
export class TranslateServiceWrapper extends TranslateService {
private _defaultTranslation: Record<string, string>|null
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
getParsedResult (translations: any, key: any, interpolateParams?: any): any {
if (!this._defaultTranslation) {
const po = require(`../../../locale/en-US.po`)
this._defaultTranslation = flattenMessageFormatTranslation(po)
}
this.translations[this.defaultLang][key] ??= this.compiler.compile(
this._defaultTranslation[key] || key,
this.defaultLang,
)
return super.getParsedResult(translations, key, interpolateParams ?? {})
}
}
@Injectable({ providedIn: 'root' })
export class LocaleService {
private logger: Logger
@ -176,6 +158,7 @@ export class LocaleService {
private translate: TranslateService,
log: LogService,
) {
this.patchTranslateService(translate)
this.logger = log.create('translate')
config.changed$.subscribe(() => {
this.refresh()
@ -191,6 +174,24 @@ export class LocaleService {
}
}
private patchTranslateService (translate: TranslateService) {
translate['_defaultTranslation'] = null
const oldGetParsedResult = translate.getParsedResult.bind(translate)
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
translate.getParsedResult = function (translations: any, key: any, interpolateParams?: any): any {
if (!this._defaultTranslation) {
const po = require(`../../../locale/en-US.po`)
this._defaultTranslation = flattenMessageFormatTranslation(po)
}
this.translations[this.defaultLang][key] ??= this.compiler.compile(
this._defaultTranslation[key] || key,
this.defaultLang,
)
return oldGetParsedResult(translations, key, interpolateParams ?? {})
}.bind(translate)
}
refresh (): void {
let lang = this.config.store.language
if (!lang) {

View File

@ -1,7 +1,9 @@
import { Inject, Injectable } from '@angular/core'
import { Subject, Observable } from 'rxjs'
import * as Color from 'color'
import { ConfigService } from '../services/config.service'
import { Theme } from '../api/theme'
import { NewTheme } from '../theme'
@Injectable({ providedIn: 'root' })
export class ThemesService {
@ -9,19 +11,120 @@ export class ThemesService {
private themeChanged = new Subject<Theme>()
private styleElement: HTMLElement|null = null
private rootElementStyleBackup = ''
/** @hidden */
private constructor (
private config: ConfigService,
private standardTheme: NewTheme,
@Inject(Theme) private themes: Theme[],
) {
this.applyTheme(this.findTheme('Standard')!)
this.rootElementStyleBackup = document.documentElement.style.cssText
this.applyTheme(standardTheme)
config.ready$.toPromise().then(() => {
this.applyCurrentTheme()
this.applyThemeVariables()
config.changed$.subscribe(() => {
this.applyCurrentTheme()
})
})
config.changed$.subscribe(() => this.applyThemeVariables())
}
private applyThemeVariables () {
if (!this.findCurrentTheme().followsColorScheme) {
document.documentElement.style.cssText = this.rootElementStyleBackup
return
}
const theme = this.config.store.terminal.colorScheme
const isDark = Color(theme.background).luminosity() < Color(theme.foreground).luminosity()
function more (some, factor) {
if (isDark) {
return Color(some).darken(factor)
}
return Color(some).lighten(factor)
}
function less (some, factor) {
if (!isDark) {
return Color(some).darken(factor)
}
return Color(some).lighten(factor)
}
let background = Color(theme.background)
if (this.config.store?.appearance.vibrancy) {
background = background.fade(0.6)
}
// const background = theme.background
const backgroundMore = more(background.string(), 0.25).string()
// const backgroundMore =more(theme.background, 0.25).string()
const accentIndex = 4
const vars: Record<string, string> = {}
vars['--bs-body-bg'] = background.string()
vars['--bs-body-color'] = theme.foreground
vars['--bs-black'] = theme.colors[0]
vars['--bs-red'] = theme.colors[1]
vars['--bs-green'] = theme.colors[2]
vars['--bs-yellow'] = theme.colors[3]
vars['--bs-blue'] = theme.colors[4]
vars['--bs-purple'] = theme.colors[5]
vars['--bs-cyan'] = theme.colors[6]
vars['--bs-gray'] = theme.colors[7]
vars['--bs-gray-dark'] = theme.colors[8]
// vars['--bs-red'] = theme.colors[9]
// vars['--bs-green'] = theme.colors[10]
// vars['--bs-yellow'] = theme.colors[11]
// vars['--bs-blue'] = theme.colors[12]
// vars['--bs-purple'] = theme.colors[13]
// vars['--bs-cyan'] = theme.colors[14]
vars['--theme-fg-more-2'] = more(theme.foreground, 0.5).string()
vars['--theme-fg-more'] = more(theme.foreground, 0.25).string()
vars['--theme-fg'] = theme.foreground
vars['--theme-fg-less'] = less(theme.foreground, 0.25).string()
vars['--theme-fg-less-2'] = less(theme.foreground, 0.5).string()
vars['--theme-bg-less-2'] = less(theme.background, 0.5).string()
vars['--theme-bg-less'] = less(theme.background, 0.25).string()
vars['--theme-bg'] = theme.background
vars['--theme-bg-more'] = backgroundMore
vars['--theme-bg-more-2'] = more(backgroundMore, 0.25).string()
const themeColors = {
primary: theme.colors[accentIndex],
secondary: theme.colors[8],
tertiary: theme.colors[8],
warning: theme.colors[3],
danger: theme.colors[1],
success: theme.colors[2],
info: theme.colors[4],
dark: more(theme.background, 0.5).string(),
light: more(theme.foreground, 0.5).string(),
link: theme.colors[8], // for .btn-link
}
for (const [key, color] of Object.entries(themeColors)) {
vars[`--bs-${key}-bg`] = more(color, 0.5).string()
vars[`--bs-${key}-color`] = less(color, 0.5).string()
vars[`--bs-${key}`] = color
vars[`--bs-${key}-rgb`] = Color(color).rgb().array().join(', ')
vars[`--theme-${key}-more-2`] = more(color, 1).string()
vars[`--theme-${key}-more`] = more(color, 0.5).string()
vars[`--theme-${key}`] = color
vars[`--theme-${key}-less`] = less(color, 0.25).string()
vars[`--theme-${key}-less-2`] = less(color, 0.75).string()
}
const switchBackground = less(theme.colors[accentIndex], 0.25).string()
vars['--bs-form-switch-bg'] = `url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27${switchBackground}%27/%3e%3c/svg%3e")`
for (const [key, value] of Object.entries(vars)) {
document.documentElement.style.setProperty(key, value)
}
}
findTheme (name: string): Theme|null {
@ -29,7 +132,7 @@ export class ThemesService {
}
findCurrentTheme (): Theme {
return this.findTheme(this.config.store.appearance.theme) ?? this.findTheme('Standard')!
return this.findTheme(this.config.store.appearance.theme) ?? this.standardTheme
}
applyTheme (theme: Theme): void {

View File

@ -0,0 +1,568 @@
$font-family-sans-serif: "Source Sans Pro";
$font-size-base: 14rem / 16;
app-root {
background: transparent;
&.vibrant {
background: rgba(var(--bs-dark-rgb),.65);
}
&> .content {
.tab-bar {
background: var(--theme-bg-more);
.btn-tab-bar {
background: transparent;
line-height: 42px;
align-items: center;
svg, path {
fill: var(--bs-body-color);
fill-opacity: 0.75;
}
&:hover { background: rgba(0, 0, 0, .125) !important; }
&:active { background: rgba(0, 0, 0, .25) !important; }
}
&>.tabs {
tab-header {
border-left: 1px solid transparent;
border-right: 1px solid transparent;
transition: 0.125s ease-out width;
.index {
color: var(--bs-body-color);
opacity: 0.4;
}
button {
color: var(--bs-body-color);
border: none;
transition: 0.25s all;
&:hover { background: var(--theme-bg-more-2) !important; }
&:active { background: var(--theme-bg-more-2) !important; }
}
.progressbar {
background: var(--bs-blue);
}
.activity-indicator {
background:var(--bs-body-color);
opacity: .2;
}
&.active {
// color: $black;
background: var(--bs-body-bg);
// border-left: 1px solid $border-color;
// border-right: 1px solid $border-color;
}
}
}
}
// &.tabs-on-top .tab-bar {
// &>.background {
// border-bottom: 1px solid $border-color;
// }
// tab-header {
// border-bottom: 1px solid $border-color;
// &.active {
// border-bottom-color: transparent;
// }
// }
// }
// &:not(.tabs-on-top) .tab-bar {
// &>.background {
// border-top: 1px solid $border-color;
// }
// tab-header {
// border-top: 1px solid $border-color;
// &.active {
// margin-top: -1px;
// }
// }
// }
}
// &.platform-win32, &.platform-linux {
// border: 1px solid #111;
// &>.content .tab-bar .tabs tab-header:first-child {
// border-left: none;
// }
// }
}
tab-body {
background: var(--bs-body-bg);
}
// $black: #002b36;
// $base02: #073642;
// $base01: #586e75;
// $base00: #657b83;
// $base0: #839496;
// $base1: #93a1a1;
// $base2: #eee8d5;
// $white: #fdf6e3;
// $yellow: #b58900;
// $orange: #cb4b16;
// $red: #dc322f;
// $pink: #d33682;
// $purple: #6c71c4;
// $blue: #268bd2;
// $teal: #2aa198;
// $green: #859900;
$tab-border-radius: 5px;
// $button-hover-bg: rgba(0, 0, 0, .125);
// $button-active-bg: rgba(0, 0, 0, .25);
// $btn-border-radius: 0;
// $input-bg: $base2;
// $input-disabled-bg: $base1;
// $input-color: $body-color;
// $input-color-placeholder: $base1;
// $input-border-color: $base1;
// //$input-box-shadow: inset 0 1px 1px rgba($black,.075);
// $input-border-radius: 0;
// $custom-select-border-radius: 0;
// $input-bg-focus: $input-bg;
// //$input-border-focus: lighten($brand-primary, 25%);
// //$input-box-shadow-focus: $input-box-shadow, rgba($input-border-focus, .6);
// $input-color-focus: $input-color;
// $input-group-addon-bg: $body-bg;
// $input-group-addon-border-color: $input-border-color;
// $modal-content-bg: $content-bg-solid;
// $modal-content-border-color: $body-bg;
$modal-header-border-color: transparent;
$modal-footer-border-color: transparent;
// $popover-bg: $body-bg;
// $dropdown-bg: $body-bg;
// $dropdown-link-color: $body-color;
// $dropdown-link-hover-color: #333;
// $dropdown-link-hover-bg: $body-bg2;
// //$dropdown-link-active-color: $component-active-color;
// //$dropdown-link-active-bg: $component-active-bg;
// $dropdown-link-disabled-color: #333;
// $dropdown-header-color: #333;
// $list-group-action-bg: rgba($black,.05);
// $list-group-action-active-bg: $list-group-link-active-bg;
// $pre-bg: $dropdown-bg;
// $pre-color: $dropdown-link-color;
// $headings-font-weight: lighter;
// $headings-color: $base0;
$form-check-input-width: 1.4em;
$form-switch-width: 2.5em;
@import '~bootstrap/scss/bootstrap.scss';
@import "./theme.vendor.scss";
body {
--bs-border-color: var(--theme-bg-more-2);
--bs-form-control-bg: var(--theme-bg-more);
--bs-emphasis-color: var(--theme-fg-less-2);
}
.list-group {
--bs-list-group-bg: var(--theme-bg-more);
--bs-list-group-border-color: var(--theme-bg-more-2);
--bs-list-group-border-width: 0;
// --bs-list-group-item-padding-x: 1rem;
// --bs-list-group-item-padding-y: 0.5rem;
--bs-list-group-action-color: var(--bs-body-color);
--bs-list-group-action-hover-color: var(--theme-fg);
--bs-list-group-action-hover-bg: var(--theme-bg-more-2);
--bs-list-group-action-active-color: var(--theme-fg);
--bs-list-group-action-active-bg: var(--theme-bg-more-2);
--bs-list-group-disabled-color: var(--bs-secondary-color);
--bs-list-group-disabled-bg: var(--bs-body-bg);
--bs-list-group-active-color: var(--bs-primary-color);
--bs-list-group-active-bg: var(--bs-primary-bg);
// --bs-list-group-active-border-color: #0d6efd;
}
.nav {
// scss-docs-start nav-css-vars
// --bs-nav-link-padding-x: #{$nav-link-padding-x};
// --bs-nav-link-padding-y: #{$nav-link-padding-y};
// @include rfs($nav-link-font-size, --bs-nav-link-font-size);
// --bs-nav-link-font-weight: #{$nav-link-font-weight};
--bs-nav-link-color: var(--bs-body-color);
--bs-nav-link-hover-color: var(--theme-fg-less-2);
--bs-nav-link-disabled-color: var(--bs-gray);
// scss-docs-end nav-css-vars
}
.nav-tabs {
// scss-docs-start nav-tabs-css-vars
--bs-nav-tabs-border-width: 2px;
--bs-nav-tabs-border-radius: 0;
--bs-nav-tabs-link-hover-border-color: var(--bs-body-bg);
--bs-nav-tabs-border-color: var(--theme-fg-less-2);
--bs-nav-tabs-link-active-color: var(--theme-fg-less-2);
--bs-nav-tabs-link-active-bg: transparent;
--bs-nav-tabs-link-active-border-color: transparent;
// scss-docs-end nav-tabs-css-vars
}
.nav-pills {
// scss-docs-start nav-pills-css-vars
--bs-nav-pills-border-radius: #{$nav-pills-border-radius};
--bs-nav-pills-link-active-color: var(--theme-bg-more);
--bs-nav-pills-link-active-bg: var(--bs-primary);
// scss-docs-end nav-pills-css-vars
}
.nav-tabs {
margin-bottom: 10px;
border: none;
&.nav-justified .nav-link {
margin-right: 5px;
}
.nav-link {
border: none;
border-bottom: var(--bs-nav-tabs-border-width) solid transparent;
text-transform: uppercase;
font-weight: bold;
padding: 5px 0;
margin-right: 20px;
uib-tab-heading > i {
font-size: 18px;
}
&.disabled {
color: var(--bs-nav-tabs-link-disabled-color);
border-color: transparent;
}
}
.nav-item:last-child .nav-link {
margin-right: 0;
}
.nav-link.active,
.nav-item.show .nav-link {
color: var(--bs-nav-tabs-link-active-color);
border-color: var(--bs-nav-tabs-border-color);
}
.nav-item {
outline: none !important;
}
}
tab-body {
terminal-toolbar {
background: var(--bs-body-bg);
.btn, .toolbar-pin-button {
font-weight: bold;
}
}
}
@each $color, $value in $theme-colors {
.btn-#{$color} {
// 6c757d
--bs-btn-bg: var(--theme-#{$color});
--bs-btn-border-color: var(--theme-#{$color});
--bs-btn-disabled-bg: var(--theme-#{$color});
--bs-btn-disabled-border-color: var(--theme-#{$color});
--bs-btn-hover-border-color: var(--theme-#{$color}-less);
--bs-btn-hover-bg: var(--theme-#{$color}-less);
--bs-btn-active-border-color: var(--theme-#{$color}-less-2);
--bs-btn-active-bg: var(--theme-#{$color}-less-2);
--bs-btn-focus-shadow-rgb: 130, 138, 145;
--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
--bs-btn-color: var(--theme-#{$color}-more-2);
--bs-btn-hover-color: var(--theme-#{$color}-more-2);
--bs-btn-active-color: var(--theme-#{$color}-more-2);
--bs-btn-disabled-color: var(--theme-#{$color}-more-2);
}
.alert-#{$color} {
--bs-alert-bg: var(--theme-#{$color}-more-2);
--bs-alert-border-color: var(--theme-#{$color}-more);
--bs-alert-color: var(--theme-#{$color});
}
}
multi-hotkey-input {
.item {
background: var(--theme-bg-more);
border: 1px solid var(--bs-primary);
border-radius: 3px;
margin-right: 5px;
.body {
padding: 3px 0 2px;
.stroke {
padding: 0 6px;
border-right: 1px solid var(--bs-body-bg);
}
}
.remove {
padding: 3px 8px 2px;
}
}
.item:has(.duplicate) {
background-color: var(--bs-danger);
border: 1px solid var(--bs-danger);
}
.add {
color: #777;
padding: 4px 10px 0;
}
.add, .item .body, .item .remove {
&:hover { background: var(--theme-bg-more); }
&:active { background: var(--theme-bg-more-2); }
}
.add:has(.duplicate), .item:has(.duplicate) .body, .item:has(.duplicate) .remove {
&:hover { background: var(--theme-danger-less); }
&:active { background: var(--theme-danger-less-2); }
}
}
hotkey-input-modal {
.input {
// background: $input-bg;
padding: 10px;
font-size: 24px;
line-height: 27px;
height: 55px;
.stroke {
background: var(--theme-bg-more);
border: 1px solid var(--bs-primary);
border-radius: 3px;
margin-right: 10px;
padding: 3px 10px;
}
}
.timeout {
background: $input-bg;
div {
background: $blue;
}
}
}
.mb-3 label {
margin-bottom: 2px;
}
.btn {
i + * {
margin-left: 5px;
}
&.btn-lg i + * {
margin-left: 10px;
}
}
.input-group-addon + .form-control {
border-left: none;
}
.input-group > select.form-control {
flex-direction: row;
}
.list-group-item {
// transition: 0.0625s background ease;
i + * {
margin-left: 10px;
}
}
.list-group.list-group-flush .list-group-item {
background: transparent;
border: none;
&:not(:last-child) {
border-bottom: none;
}
}
.list-group-light {
.list-group-item {
border: none !important;
outline: none !important;
background: transparent;
border-radius: $border-radius;
margin: 0 !important;
&.active {
background-color: var(--bs-list-group-active-bg);
}
}
}
// checkbox i.on {
// color: $blue;
// }
// .modal .modal-footer {
// background: rgba(0, 0, 0, .25);
// .btn {
// font-weight: bold;
// padding: 0.375rem 1.5rem;
// }
// }
.list-group-item svg {
fill: var(--bs-body-color);
fill-opacity: 0.75;
}
*::-webkit-scrollbar {
background: rgba(0, 0, 0, .125);
width: 10px;
margin: 5px;
}
*::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, .25);
}
*::-webkit-scrollbar-corner,
*::-webkit-resizer {
opacity: 0;
}
search-panel {
background: var(--theme-bg-more) !important;
input {
border-radius: 0 !important;
}
}
.btn {
cursor: pointer;
justify-content: flex-start;
overflow: hidden;
&.disabled,
&:disabled {
cursor: not-allowed;
}
}
.btn-link {
text-decoration: none;
// &:hover, &[aria-expanded=true], &:active, &.active {
// color: $link-hover-color;
// border-radius: $btn-border-radius;
// }
// &[aria-expanded=true], &:active, &.active {
// background: rgba(255, 255, 255, 0.1);
// }
}
// .btn-group .btn.active {
// border-color: transparent !important;
// }
// hr {
// border-color: $list-group-border-color;
// }
// .dropdown-menu {
// box-shadow: $dropdown-box-shadow;
// }
ngx-colors-panel .opened {
background: var(--bs-body-bg) !important;
button {
color: var(--bs-body-color) !important;
}
.button svg {
fill: white;
}
}
.text-muted {
// color: var(--bs-body-color) !important;
opacity: .5;
}
.form-switch .form-check-input {
--bs-form-switch-bg: inherit;
border-color: var(--theme-bg-more);
background-color: var(--theme-bg-more-2);
&:checked {
border-color: var(--theme-primary-more);
background-color: var(--theme-primary);
}
}
.form-control:focus {
border-color: var(--theme-fg-more-2);
}
.accordion {
--bs-accordion-bg: var(--theme-bg-more);
--bs-accordion-active-color: var(--theme-fg);
--bs-accordion-active-bg: var(--theme-bg-more-2);
}
start-page {
background: var(--theme-bg);
}
split-tab-spanner {
background: rgba(var(--bs-dark-rgb), .1);
&:hover, &.active {
background: rgba(var(--bs-dark-rgb), .2);
}
}

View File

@ -19,10 +19,9 @@ $tab-border-radius: 5px;
$button-hover-bg: rgba(0, 0, 0, .125);
$button-active-bg: rgba(0, 0, 0, .25);
$theme-colors: (
"primary": $orange,
"secondary": $base0
);
$primary: #fd7e14;
$secondary: #495057;
$content-bg: rgba($white, 0.65);
$content-bg-solid: $white;
@ -257,8 +256,8 @@ multi-hotkey-input {
}
.item:has(.duplicate) {
background-color: theme-color('danger');
border: 1px solid theme-color('danger');
background-color: map-get($theme-colors, 'danger');
border: 1px solid map-get($theme-colors, 'danger');
}
.add {
@ -272,8 +271,8 @@ multi-hotkey-input {
}
.add:has(.duplicate), .item:has(.duplicate) .body, .item:has(.duplicate) .remove {
&:hover { background: darken(theme-color('danger'), 5%); }
&:active { background: darken(theme-color('danger'), 15%); }
&:hover { background: darken(map-get($theme-colors, 'danger'), 5%); }
&:active { background: darken(map-get($theme-colors, 'danger'), 15%); }
}
}
@ -303,7 +302,7 @@ hotkey-input-modal {
}
}
.form-group label {
.mb-3 label {
margin-bottom: 2px;
}
@ -314,7 +313,7 @@ hotkey-input-modal {
}
}
[ngbradiogroup] > label.active {
.btn-check:checked + label {
background: $blue;
}
@ -370,7 +369,7 @@ toggle {
}
&.active .body .toggle {
background: theme-colors(primary) !important;
background: map-get($theme-colors, primary) !important;
}
}
@ -398,3 +397,11 @@ terminal-toolbar {
.bg-dark{
background-color: $base2 !important;
}
split-tab-spanner {
background: rgba(0, 0, 0, .2);
&:hover, &.active {
background: rgba(255, 255, 255, .125);
}
}

View File

@ -7,6 +7,7 @@ $button-hover-bg: rgba(0, 0, 0, .25);
$button-active-bg: rgba(0, 0, 0, .5);
@import '~bootstrap/scss/bootstrap.scss';
@import "./theme.vendor.scss";
window-controls {
svg {
@ -163,8 +164,8 @@ multi-hotkey-input {
}
.item:has(.duplicate) {
background-color: theme-color('danger');
border: 1px solid theme-color('danger');
background-color: map-get($theme-colors, 'danger');
border: 1px solid map-get($theme-colors, 'danger');
}
.add {
@ -178,8 +179,8 @@ multi-hotkey-input {
}
.add:has(.duplicate), .item:has(.duplicate) .body, .item:has(.duplicate) .remove {
&:hover { background: darken(theme-color('danger'), 5%); }
&:active { background: darken(theme-color('danger'), 15%); }
&:hover { background: darken(map-get($theme-colors, 'danger'), 5%); }
&:active { background: darken(map-get($theme-colors, 'danger'), 15%); }
}
}
@ -209,11 +210,11 @@ hotkey-input-modal {
}
}
.form-group label {
.mb-3 label {
margin-bottom: 2px;
}
[ngbradiogroup] > label.active {
.btn-check:checked + label {
background: $blue;
}
@ -342,6 +343,8 @@ search-panel {
}
.btn-link {
text-decoration: none;
&:hover, &[aria-expanded=true], &:active, &.active {
color: $link-hover-color;
border-radius: $btn-border-radius;
@ -375,9 +378,9 @@ search-panel {
font-size: 18px;
}
@include hover-focus {
color: $nav-tabs-link-active-color;
}
// @include hover-focus {
// color: $nav-tabs-link-active-color;
// }
&.disabled {
color: $nav-link-disabled-color;
@ -415,3 +418,11 @@ ngx-colors-panel .opened {
fill: white;
}
}
split-tab-spanner {
background: rgba(0, 0, 0, .2);
&:hover, &.active {
background: rgba(255, 255, 255, .125);
}
}

View File

@ -5,7 +5,7 @@ import { Theme } from './api'
/** @hidden */
@Injectable()
export class StandardTheme extends Theme {
name = this.translate.instant('Standard')
name = this.translate.instant('Standard (legacy)')
css = require('./theme.scss')
terminalBackground = '#222a33'
@ -17,7 +17,7 @@ export class StandardTheme extends Theme {
/** @hidden */
@Injectable()
export class StandardCompactTheme extends Theme {
name = this.translate.instant('Compact')
name = this.translate.instant('Compact (legacy)')
css = require('./theme.compact.scss')
terminalBackground = '#222a33'
macOSWindowButtonsInsetX = 8
@ -31,7 +31,20 @@ export class StandardCompactTheme extends Theme {
/** @hidden */
@Injectable()
export class PaperTheme extends Theme {
name = 'Paper'
name = 'Paper (legacy)'
css = require('./theme.paper.scss')
terminalBackground = '#f7f1e0'
}
/** @hidden */
@Injectable({ providedIn: 'root' })
export class NewTheme extends Theme {
name = this.translate.instant('Follow the color scheme')
css = require('./theme.new.scss')
terminalBackground = '#f7f1e0'
followsColorScheme = true
constructor (private translate: TranslateService) {
super()
}
}

View File

@ -175,13 +175,12 @@ $badge-padding-y: 4px;
$badge-padding-x: 6px;
$custom-control-indicator-size: 1.2rem;
$custom-control-indicator-bg: $body-bg;
$custom-control-indicator-border-color: lighten($body-bg, 25%);
$custom-control-indicator-checked-bg: theme-color("primary");
$custom-control-indicator-checked-color: $body-bg;
$custom-control-indicator-checked-border-color: transparent;
$custom-control-indicator-active-bg: rgba(255, 255, 0, 0.5);
$form-check-input-border: lighten($body-bg, 25%);
$form-check-input-width: 1.4em;
$form-switch-width: 2.5em;
$form-switch-color: lighten($body-bg, 25%);
$form-switch-focus-color: lighten($body-bg, 40%);
$form-switch-checked-color: map-get($theme-colors, "primary");
$modal-content-bg: $content-bg-solid;
@ -201,3 +200,13 @@ $alert-color-level: -5;
$text-muted: rgba(255, 255, 255, 0.5);
$card-bg: $list-group-bg;
$tooltip-color: rgba(255, 255, 255, .75);
$tooltip-bg: rgba(0, 0, 0, .75);
$accordion-border-color: $list-group-border-color;
$accordion-bg: $list-group-bg;
$accordion-button-active-bg: $list-group-active-bg;
$accordion-button-active-color: $list-group-active-color;
$btn-close-color: $body-color;

View File

@ -0,0 +1,3 @@
// $alert-border-radius: 0;
// @mixin border-radius ($r) {}
@import "../../node_modules/ngx-toastr/toastr-bs5-alert.scss";

View File

@ -1,5 +0,0 @@
const config = require('../webpack.plugin.config')
module.exports = config({
name: 'core',
dirname: __dirname,
})

View File

@ -0,0 +1,10 @@
import * as path from 'path'
import * as url from 'url'
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
import config from '../webpack.plugin.config.mjs'
export default () => config({
name: 'core',
dirname: __dirname,
})

View File

@ -2,13 +2,6 @@
# yarn lockfile v1
"@ngx-translate/core@^14.0.0":
version "14.0.0"
resolved "https://registry.yarnpkg.com/@ngx-translate/core/-/core-14.0.0.tgz#af421d0e1a28376843f0fed375cd2fae7630a5ff"
integrity sha512-UevdwNCXMRCdJv//0kC8h2eSfmi02r29xeE8E9gJ1Al4D4jEJ7eiLPdjslTMc21oJNGguqqWeEVjf64SFtvw2w==
dependencies:
tslib "^2.3.0"
abort-controller@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392"
@ -33,10 +26,10 @@ base64-js@^1.3.1:
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
bootstrap@^4.1.3:
version "4.5.3"
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.5.3.tgz#c6a72b355aaf323920be800246a6e4ef30997fe6"
integrity sha512-o9ppKQioXGqhw8Z7mah6KdTYpNQY//tipnkxppWhPbiSWdD+1raYsnhwEZjkTHYbGee4cVQ0Rx65EhOY/HNLcQ==
bootstrap@^5.3.0-alpha.1:
version "5.3.0-alpha1"
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.3.0-alpha1.tgz#380629c4367893f02f7879a01ea3ae0f94e2e70e"
integrity sha512-ABZpKK4ObS3kKlIqH+ZVDqoy5t/bhFG0oHTAzByUdon7YIom0lpCeTqRniDzJmbtcWkNe800VVPBiJgxSYTYew==
buffer@^6.0.3:
version "6.0.3"
@ -46,6 +39,34 @@ buffer@^6.0.3:
base64-js "^1.3.1"
ieee754 "^1.2.1"
color-convert@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
dependencies:
color-name "~1.1.4"
color-name@^1.0.0, color-name@~1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
color-string@^1.9.0:
version "1.9.1"
resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4"
integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==
dependencies:
color-name "^1.0.0"
simple-swizzle "^0.2.2"
color@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/color/-/color-4.2.3.tgz#d781ecb5e57224ee43ea9627560107c0e0c6463a"
integrity sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==
dependencies:
color-convert "^2.0.1"
color-string "^1.9.0"
debug@4:
version "4.3.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
@ -68,11 +89,6 @@ events@^3.3.0:
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
"filesize@>= 4.0.0":
version "6.3.0"
resolved "https://registry.yarnpkg.com/filesize/-/filesize-6.3.0.tgz#dff53cfb3f104c9e422f346d53be8dbcc971bf11"
integrity sha512-ytx0ruGpDHKWVoiui6+BY/QMNngtDQ/pJaFwfBpQif0J63+E8DLdFyqS3NkKQn7vIruUEpoGD9JUJSg7Kp+I0g==
fuzzy-search@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/fuzzy-search/-/fuzzy-search-3.2.1.tgz#65d5faad6bc633aee86f1898b7788dfe312ac6c9"
@ -91,6 +107,11 @@ ieee754@^1.2.1:
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
is-arrayish@^0.3.1:
version "0.3.2"
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03"
integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==
js-yaml@^4.0.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
@ -141,23 +162,6 @@ ms@2.1.2:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
ngx-filesize@^2.0.16:
version "2.0.16"
resolved "https://registry.yarnpkg.com/ngx-filesize/-/ngx-filesize-2.0.16.tgz#fdaba04170edb6cfcdf7be932783cf913b03f016"
integrity sha512-VdaCirE7hSyfQh8ZEmhzNEhbddiTYUHF4V6OX+KyTmnQSVx4hp9kmzDX5YlkIlmClI6wI+LZmH9/q7XS3fsMPA==
dependencies:
filesize ">= 4.0.0"
tslib "^2.0.0"
ngx-perfect-scrollbar@^10.1.0:
version "10.1.1"
resolved "https://registry.yarnpkg.com/ngx-perfect-scrollbar/-/ngx-perfect-scrollbar-10.1.1.tgz#f89832b9109e89bb59d516184638accd028e9735"
integrity sha512-f9IaDJGlBzSxnJ3Ki76n2JdzfQngUFyCf0E+CuVLaR5jL0IJDcTu7vOs8wexXunRMTd8xvIv0+sdIxf8hXAGWg==
dependencies:
perfect-scrollbar "1.5.0"
resize-observer-polyfill "^1.5.0"
tslib "^2.0.0"
ngx-translate-messageformat-compiler@^4.11.0:
version "4.11.0"
resolved "https://registry.yarnpkg.com/ngx-translate-messageformat-compiler/-/ngx-translate-messageformat-compiler-4.11.0.tgz#c9b71dd139ba5fcdcd809001e22622de589fd707"
@ -165,11 +169,6 @@ ngx-translate-messageformat-compiler@^4.11.0:
dependencies:
tslib "^1.10.0"
perfect-scrollbar@1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/perfect-scrollbar/-/perfect-scrollbar-1.5.0.tgz#821d224ed8ff61990c23f26db63048cdc75b6b83"
integrity sha512-NrNHJn5mUGupSiheBTy6x+6SXCFbLlm8fVZh9moIzw/LgqElN5q4ncR4pbCBCYuCJ8Kcl9mYM0NgDxvW+b4LxA==
process@^0.11.10:
version "0.11.10"
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
@ -185,26 +184,18 @@ readable-stream@4.2.0:
events "^3.3.0"
process "^0.11.10"
resize-observer-polyfill@^1.5.0:
version "1.5.1"
resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464"
integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==
simple-swizzle@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a"
integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==
dependencies:
is-arrayish "^0.3.1"
tslib@^1.10.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
tslib@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a"
integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==
tslib@^2.3.0:
version "2.3.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01"
integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==
uuid@^9.0.0:
version "9.0.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5"

View File

@ -1,5 +0,0 @@
const config = require('../webpack.plugin.config')
module.exports = config({
name: 'electron',
dirname: __dirname,
})

View File

@ -0,0 +1,10 @@
import * as path from 'path'
import * as url from 'url'
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
import config from '../webpack.plugin.config.mjs'
export default () => config({
name: 'electron',
dirname: __dirname,
})

View File

@ -1,5 +0,0 @@
const config = require('../webpack.plugin.config')
module.exports = config({
name: 'linkifier',
dirname: __dirname,
})

View File

@ -0,0 +1,10 @@
import * as path from 'path'
import * as url from 'url'
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
import config from '../webpack.plugin.config.mjs'
export default () => config({
name: 'linkifier',
dirname: __dirname,
})

View File

@ -1,36 +1,34 @@
ng-container(*ngIf='!argvMode')
.form-group
.mb-3
label(translate) Command line
.input-group
.input-group-prepend
a.input-group-text(
(click)='switchToArgv()',
ngbTooltip='Split into unescaped arguments',
href='#'
)
i.fas.fa-fw.fa-caret-right
a.input-group-text.text-decoration-none(
(click)='switchToArgv()',
ngbTooltip='Split into unescaped arguments',
href='#'
)
i.fas.fa-fw.fa-caret-right
input.form-control.text-monospace(
[(ngModel)]='command',
(ngModelChange)='parseCommand()'
)
ng-container(*ngIf='argvMode')
.form-group
.mb-3
label(translate) Program
.input-group
.input-group-prepend
a.input-group-text(
(click)='switchToCommand()',
ngbTooltip='Combine into a single escaped command',
href='#'
)
i.fas.fa-fw.fa-caret-down
a.input-group-text.text-decoration-none(
(click)='switchToCommand()',
ngbTooltip='Combine into a single escaped command',
href='#'
)
i.fas.fa-fw.fa-caret-down
input.form-control.text-monospace(
type='text',
[(ngModel)]='_model.command',
)
.form-group
.mb-3
label(translate) Arguments
.input-group(
*ngFor='let arg of _model.args; index as i; trackBy: trackByIndex',
@ -39,11 +37,10 @@ ng-container(*ngIf='argvMode')
type='text',
[(ngModel)]='_model.args[i]',
)
.input-group-append
button.btn.btn-secondary((click)='_model.args.splice(i, 1)')
i.fas.fa-fw.fa-trash
button.btn.btn-secondary((click)='_model.args.splice(i, 1)')
i.fas.fa-fw.fa-trash
.mt-2
button.btn.btn-secondary((click)='_model.args.push("")')
i.fas.fa-plus.mr-2
i.fas.fa-plus.me-2
span(translate) Add

View File

@ -6,7 +6,7 @@ import { SessionOptions } from '../api'
/** @hidden */
@Component({
selector: 'command-line-editor',
template: require('./commandLineEditor.component.pug'),
templateUrl:'./commandLineEditor.component.pug',
})
export class CommandLineEditorComponent {
@Input() argvMode = false

View File

@ -1,20 +1,18 @@
.mb-2.d-flex.align-items-center(*ngFor='let pair of vars')
.input-group
input.form-control.w-25.text-monospace([(ngModel)]='pair.key', (blur)='emitUpdate()', placeholder='Variable name')
.input-group-append
.input-group-text =
.input-group-text =
input.form-control.w-50.text-monospace([(ngModel)]='pair.value', (blur)='emitUpdate()', placeholder='Value')
.input-group-append
button.btn.btn-secondary((click)='removeEnvironmentVar(pair.key)')
i.fas.fa-fw.fa-trash
button.btn.btn-secondary((click)='removeEnvironmentVar(pair.key)')
i.fas.fa-fw.fa-trash
.d-flex
button.btn.btn-secondary((click)='addEnvironmentVar()')
i.fas.fa-plus.mr-2
i.fas.fa-plus.me-2
span(translate) Add
.ml-auto
.ms-auto
.text-muted(translate) Substitutions allowed.
.d-flex.ml-1(*ngIf='shouldShowExample()')
.d-flex.ms-1(*ngIf='shouldShowExample()')
.text-muted(translate) Example:
a.ml-1((click)='addExample()', href='#') extend PATH
a.ms-1((click)='addExample()', href='#') extend PATH

View File

@ -5,8 +5,8 @@ import { Subject } from 'rxjs'
/** @hidden */
@Component({
selector: 'environment-editor',
template: require('./environmentEditor.component.pug'),
styles: [require('./environmentEditor.component.scss')],
templateUrl:'./environmentEditor.component.pug',
styleUrls: ['./environmentEditor.component.scss'],
})
export class EnvironmentEditorComponent {
@Output() modelChange = new Subject<any>()

View File

@ -7,7 +7,7 @@ command-line-editor([model]='profile.options')
[(ngModel)]='profile.options.runAsAdministrator',
)
.form-group
.mb-3
label(translate) Working directory
.input-group
@ -16,11 +16,10 @@ command-line-editor([model]='profile.options')
placeholder='Home directory',
[(ngModel)]='profile.options.cwd'
)
.input-group-append
button.btn.btn-secondary((click)='pickWorkingDirectory()')
i.fas.fa-folder-open
button.btn.btn-secondary((click)='pickWorkingDirectory()')
i.fas.fa-folder-open
.form-group
.mb-3
label(translate) Environment
environment-editor(
type='text',

View File

@ -8,7 +8,7 @@ import { ProfileSettingsComponent } from 'tabby-core'
/** @hidden */
@Component({
template: require('./localProfileSettings.component.pug'),
templateUrl:'./localProfileSettings.component.pug',
})
export class LocalProfileSettingsComponent implements ProfileSettingsComponent<LocalProfile> {
profile: LocalProfile

Some files were not shown because too many files have changed in this diff Show More