Move some (all) files around

Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
This commit is contained in:
2024-07-08 20:01:55 +03:00
parent 9dfbe1203d
commit 7ab40e3493
103 changed files with 202 additions and 217 deletions

View File

@@ -0,0 +1,3 @@
node_modules
types
bun.lockb

View File

@@ -0,0 +1,7 @@
{
"arrowParens": "avoid",
"bracketSameLine": true,
"bracketSpacing": true,
"singleQuote": true,
"trailingComma": "all"
}

View File

@@ -0,0 +1,27 @@
{
pkgs ? import <nixpkgs> { },
...
}:
pkgs.stdenv.mkDerivation {
name = "ags-config";
src = ./.;
nativeBuildInputs = with pkgs; [ bun ];
phases = [
"buildPhase"
"installPhase"
];
buildPhase = ''
bun build $src/src/index.ts --outfile=index.js \
--external="file://$src/*" \
--external="gi://*"
'';
installPhase = ''
mkdir -p $out/share
cp index.js $out/share/config.js
'';
}

View File

@@ -0,0 +1,116 @@
/* eslint no-use-before-define: 0 */
import globals from 'globals';
import pluginJs from '@eslint/js';
import tseslint from 'typescript-eslint';
import typescriptEslint from '@typescript-eslint/eslint-plugin';
import unicorn from 'eslint-plugin-unicorn';
import prettier from 'eslint-plugin-prettier';
import tsParser from '@typescript-eslint/parser';
export default [
{ files: ['**/*.{js,mjs,cjs,ts}'] },
{ languageOptions: { globals: globals.browser } },
pluginJs.configs.recommended,
...tseslint.configs.recommended,
{
plugins: {
'@typescript-eslint': typescriptEslint,
unicorn,
prettier,
},
languageOptions: {
globals: {
...globals.browser,
},
parser: tsParser,
ecmaVersion: 5,
sourceType: 'script',
parserOptions: {
project: ['./tsconfig.json'],
},
},
settings: {
'import/resolver': {
node: {
extensions: ['.js', '.jsx', '.ts', '.tsx'],
},
},
},
rules: {
curly: ['error', 'multi-line'],
'eol-last': ['error', 'always'],
semi: ['error', 'always'],
quotes: ['error', 'single'],
'no-await-in-loop': 'warn',
'no-constructor-return': 'error',
'no-duplicate-imports': 'error',
'no-self-compare': 'error',
'no-unreachable-loop': 'error',
'no-trailing-spaces': 'error',
'no-console': 'warn',
'no-shadow': 'off',
'@typescript-eslint/no-shadow': ['error'],
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': ['error'],
'no-use-before-define': 'off',
'@typescript-eslint/no-use-before-define': ['error'],
'@typescript-eslint/require-await': 'warn',
'@typescript-eslint/no-misused-promises': ['error', {
checksVoidReturn: false,
}],
'@typescript-eslint/naming-convention': [
'error',
{
selector: 'default',
format: ['camelCase'],
leadingUnderscore: 'allowSingleOrDouble',
},
{
selector: 'variableLike',
format: ['camelCase', 'PascalCase'],
leadingUnderscore: 'allowSingleOrDouble',
},
{
selector: 'memberLike',
format: ['camelCase'],
},
{
selector: 'typeLike',
format: ['PascalCase'],
},
{
selector: 'property',
format: ['snake_case'],
},
{
selector: 'method',
format: ['camelCase'],
},
{
selector: ['enumMember', 'enum'],
format: ['UPPER_CASE'],
}
],
'unicorn/empty-brace-spaces': 'off',
'unicorn/expiring-todo-comments': 'off',
'unicorn/no-array-for-each': 'off',
'unicorn/filename-case': ['error', {
case: 'camelCase',
}],
'unicorn/numeric-separators-style': 'off',
'unicorn/prevent-abbreviations': 'off',
},
"ignores": ["*.config.js"]
}
];

View File

@@ -0,0 +1,23 @@
{
"name": "ags",
"module": "index.ts",
"type": "module",
"scripts": {
"lint": "eslint ."
},
"devDependencies": {
"@eslint/eslintrc": "^3.1.0",
"@eslint/js": "^9.6.0",
"@types/bun": "^1.1.6",
"@typescript-eslint/eslint-plugin": "^7.14.1",
"@typescript-eslint/parser": "^7.14.1",
"eslint": "9.x",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-unicorn": "^54.0.0",
"globals": "^15.6.0",
"typescript-eslint": "^7.14.1"
},
"peerDependencies": {
"typescript": "^5.0.0"
}
}

View File

@@ -0,0 +1,19 @@
import gtk from 'gi://Gtk?version=3.0';
import gdk from 'gi://Gdk';
import { range } from 'lib';
import themeInit from 'theme';
import bar from 'widgets/bar/bar';
const forMonitors = (widget: (monitor: number) => gtk.Window) => {
const n = gdk.Display.get_default()?.get_n_monitors() || 1;
return range(n, 0).flatMap(widget);
};
App.config({
style: themeInit(),
windows: [
...forMonitors(bar),
]
});
Utils.execAsync('systemd-notify --ready')

View File

@@ -0,0 +1,3 @@
export const range = (length: number, start = 1) => {
return Array.from({ length }, (n, i) => i + start);
};

View File

@@ -0,0 +1,25 @@
export default () => {
const css = `${App.configDir}/theme.css`;
const scss = `${App.configDir}/theme.sass`;
let themeExists = true;
try {
Utils.readFile(scss);
Utils.exec(`sassc ${scss} ${css}`);
} catch (error) {
console.error(error);
themeExists = false;
}
Utils.monitorFile(
`${App.configDir}/theme.sass`,
function () {
Utils.exec(`sassc ${scss} ${css}`);
App.resetCss();
App.applyCss(css);
},
);
return themeExists ? css : undefined;
};

View File

@@ -0,0 +1,39 @@
import gap from './gap/gap';
import launcher from './launcher/launcher';
import workspace from './workspace/workspace';
import date from './date/date';
import systray from './systray/systray';
export default (monitor: number) => Widget.Window({
monitor,
class_name: 'bar',
name: `bar${monitor}`,
exclusivity: 'exclusive',
anchor: ['top', 'right', 'left'],
child: Widget.CenterBox({
class_name: 'widgets',
start_widget: Widget.Box({
hexpand: true,
hpack: 'start',
children: [
launcher(),
gap(),
workspace(),
],
}),
center_widget: Widget.Box({
hexpand: true,
hpack: 'center',
children: [
date(),
],
}),
end_widget: Widget.Box({
hexpand: true,
hpack: 'end',
children: [
systray(),
],
}),
}),
});

View File

@@ -0,0 +1,10 @@
const icon = () => Widget.Icon({
class_name: 'icon',
icon: 'edit-paste-symbolic',
});
export default () => Widget.EventBox({
class_name: 'clipboard',
child: icon(),
onPrimaryClick: () => Utils.execAsync('bash -c "cliphist list | rofi -cache-dir $XDG_CACHE_HOME/rofi -dmenu -display-columns 2 | cliphist decode | wl-copy"'),
});

View File

@@ -0,0 +1,18 @@
import glib from 'gi://GLib';
const clock = Variable(glib.DateTime.new_now_local(), {
poll: [1000, () => glib.DateTime.new_now_local()]
});
const time = Utils.derive([clock], (c) => c.format('%H:%M - %A, %d %B %Y') || '');
const label = () => Widget.Label({
class_name: 'label',
justification: 'center',
label: time.bind(),
});
export default () => Widget.EventBox({
class_name: 'date',
child: label(),
});

View File

@@ -0,0 +1,3 @@
export default () => Widget.Box({
class_name: 'gap',
});

View File

@@ -0,0 +1,10 @@
const icon = () => Widget.Icon({
class_name: 'icon',
icon: 'nix-snowflake-symbolic',
});
export default () => Widget.EventBox({
class_name: 'launcher',
child: icon(),
onPrimaryClick: () => Utils.execAsync('bash -c "rofi -cache-dir $XDG_CACHE_HOME/rofi -show drun"'),
});

View File

@@ -0,0 +1,16 @@
import gdk from 'gi://Gdk';
const systemtray = await Service.import('systemtray');
const systrayItem = item => Widget.EventBox({
class_name: 'item',
tooltip_markup: item.bind('tooltip_markup'),
child: Widget.Icon({ class_name: 'icon' }).bind('icon', item, 'icon'),
onPrimaryClick: (_, event: gdk.Event) => item.activate(event),
onSecondaryClick: (_, event: gdk.Event) => item.openMenu(event),
});
export default () => Widget.Box({
class_name: 'systray',
children: systemtray.bind('items').as(i => i.map(systrayItem))
});

View File

@@ -0,0 +1,23 @@
import { range } from 'lib';
const hyprland = await Service.import('hyprland');
const dispatch = ws => hyprland.messageAsync(`dispatch workspace ${ws}`);
const workspaceButton = (i: number) => Widget.Label({
class_name: 'button',
attribute: i,
vpack: 'center',
setup: self => self.hook(hyprland, () => {
self.toggleClassName('active', hyprland.active.workspace.id === i);
self.toggleClassName('occupied', (hyprland.getWorkspace(i)?.windows || 0) > 0);
}),
});
export default () => Widget.EventBox({
class_name: 'workspace',
onScrollUp: () => dispatch('e-1'),
onScrollDown: () => dispatch('e+1'),
child: Widget.Box({
children: range(10).map(workspaceButton),
}),
});

View File

@@ -0,0 +1,18 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "ES2022",
"lib": [
"ES2022"
],
"allowJs": true,
"checkJs": true,
"strict": true,
"noImplicitAny": false,
"baseUrl": "./src",
"typeRoots": [
"./types",
],
"skipLibCheck": true,
}
}

View File

@@ -0,0 +1,73 @@
{
user ? throw "user argument is required",
}:
{
config,
lib,
pkgs,
inputs,
...
}:
let
hmConfig = config.home-manager.users.${user.name};
agsConfig = import ./config { inherit pkgs; };
in
{
home-manager.users.${user.name} = {
imports = [ inputs.ags.homeManagerModules.default ];
programs.ags.enable = true;
xdg.configFile.ags = {
source = "${agsConfig}/share/config.js";
target = "ags/config.js";
};
programs.matugen.settings.templates.ags = {
input_path = ./theme.sass;
output_path = "${hmConfig.xdg.configHome}/ags/theme.sass";
};
systemd.user = {
targets.tray.Unit = {
BindsTo = [ "ags.service" ];
After = [
"graphical-session.target"
"ags.service"
];
};
services.ags = {
Unit = {
Description = "Desktop widget shell";
BindsTo = [ "graphical-session.target" ];
After = [ "graphical-session.target" ];
};
Service = {
Type = "notify";
NotifyAccess = "all";
ExecStart = lib.meta.getExe (
pkgs.writeShellApplication {
name = "init-ags";
runtimeInputs = with pkgs; [
inputs.ags.packages.${stdenv.hostPlatform.system}.default
sassc
hyprland
nixos-icons
rofi-wayland
wl-clipboard
cliphist
libdbusmenu-gtk3
];
text = "exec ags";
}
);
};
Install.WantedBy = [ "graphical-session.target" ];
};
};
};
}

View File

@@ -0,0 +1,74 @@
.bar
background-color: {{colors.surface.default.hex}}
@mixin interactive
min-height: {{custom.font_size}}pt
border-radius: .5 * {{custom.font_size}}pt
transition: .25s
&:hover
background-color: {{colors.surface_container_high.default.hex}}
&:active
background-color: {{colors.surface_container_highest.default.hex}}
.widgets
padding: .2 * {{custom.padding}}pt
.gap
min-height: {{custom.font_size}}pt
min-width: .5 * {{custom.padding}}pt
.launcher
.clipboard
@include interactive
min-width: {{custom.font_size}}pt
.icon
font-size: {{custom.font_size}}pt
padding: 0 .3 * {{custom.padding}}pt
color: {{colors.on_surface.default.hex}}
.workspace
@include interactive
.button
font-size: 0
transition: .5s
margin: 0 .3 * {{custom.padding}}pt
background-color: {{colors.outline_variant.default.hex}}
min-width: .4 * {{custom.font_size}}pt
min-height: .4 * {{custom.font_size}}pt
border-radius: .5 * {{custom.font_size}}pt
&.occupied
background-color: {{colors.on_surface.default.hex}}
min-width: .6 * {{custom.font_size}}pt
min-height: .6 * {{custom.font_size}}pt
border-radius: .5 * {{custom.font_size}}pt
&.active
background-color: {{colors.primary.default.hex}}
min-width: 1.67 * {{custom.font_size}}pt
min-height: {{custom.font_size}}pt
border-radius: .4 * {{custom.font_size}}pt
.date
@include interactive
.label
color: {{colors.on_surface.default.hex}}
font-size: {{custom.font_size}}pt
font-family: {{custom.font_sans_serif_all}}
font-weight: 500
margin: 0 .5 * {{custom.padding}}pt
.systray
.item
@include interactive
.icon
font-size: {{custom.font_size}}pt
padding: 0 .3 * {{custom.padding}}pt
color: {{colors.on_surface.default.hex}}