From 3e107a922c92f6d43235f28f6cf52ebcf4e1b1b6 Mon Sep 17 00:00:00 2001 From: myamusashi Date: Tue, 24 Dec 2024 12:42:46 +0700 Subject: [PATCH 1/2] feat: cloudflare warp custom modules --- src/components/bar/exports.ts | 2 + src/components/bar/index.tsx | 2 + .../bar/modules/warp/helpers/index.ts | 17 +++++ src/components/bar/modules/warp/index.tsx | 73 +++++++++++++++++++ src/lib/types/options.d.ts | 3 +- src/options.ts | 20 +++++ src/scss/style/bar/style.scss | 22 ++++++ 7 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 src/components/bar/modules/warp/helpers/index.ts create mode 100644 src/components/bar/modules/warp/index.tsx diff --git a/src/components/bar/exports.ts b/src/components/bar/exports.ts index 13da91325..109c5dd72 100644 --- a/src/components/bar/exports.ts +++ b/src/components/bar/exports.ts @@ -23,6 +23,7 @@ import { Weather } from '../../components/bar/modules/weather/index'; import { Power } from '../../components/bar/modules/power/index'; import { Hyprsunset } from '../../components/bar/modules/hyprsunset/index'; import { Hypridle } from '../../components/bar/modules/hypridle/index'; +import { Warp } from '../../components/bar/modules/warp/index'; export { Menu, @@ -50,4 +51,5 @@ export { Power, Hyprsunset, Hypridle, + Warp, }; diff --git a/src/components/bar/index.tsx b/src/components/bar/index.tsx index 9439727db..82a97effb 100644 --- a/src/components/bar/index.tsx +++ b/src/components/bar/index.tsx @@ -24,6 +24,7 @@ import { Power, Hyprsunset, Hypridle, + Warp } from './exports'; import { WidgetContainer } from './shared/WidgetContainer'; @@ -62,6 +63,7 @@ const widget = { power: (): JSX.Element => WidgetContainer(Power()), hyprsunset: (): JSX.Element => WidgetContainer(Hyprsunset()), hypridle: (): JSX.Element => WidgetContainer(Hypridle()), + warp: (): JSX.Element => WidgetContainer(Warp()), }; export const Bar = (() => { diff --git a/src/components/bar/modules/warp/helpers/index.ts b/src/components/bar/modules/warp/helpers/index.ts new file mode 100644 index 000000000..235a1b769 --- /dev/null +++ b/src/components/bar/modules/warp/helpers/index.ts @@ -0,0 +1,17 @@ +import { execAsync, Variable } from "astal"; + +export const isWarpConnectCommand = `bash -c "warp-cli status | awk {'print $3'}"` +export const isWarpDisconnectCommand = `bash -c "warp-cli status | head -1 | awk {'print $3'}"` + +export const isWarpConnect = Variable(false); + +export const toggleWarp = async (isWarpConnect: Variable): Promise => { + try { + await execAsync(`bash -c "warp-cli ${isWarpConnect.get() ? 'disconnect' : 'connect'}"`); + + const res = await execAsync(isWarpConnect.get() ? isWarpConnectCommand : isWarpDisconnectCommand); + isWarpConnect.set(isWarpConnect.get() ? res === 'Disconnected' : res === 'Connected'); + } catch (err) { + await execAsync(`bash -c "notify-send -a 'hyprpanel' 'Warp service not active!' 'Error: ${err}'"`); + } +}; diff --git a/src/components/bar/modules/warp/index.tsx b/src/components/bar/modules/warp/index.tsx new file mode 100644 index 000000000..3eeeb3840 --- /dev/null +++ b/src/components/bar/modules/warp/index.tsx @@ -0,0 +1,73 @@ +import options from "src/options"; +import { Module } from "../../shared/Module"; +import { inputHandler, throttleInput } from "../../utils/helpers"; +import { BarBoxChild } from "src/lib/types/bar"; +import { isWarpConnect, toggleWarp } from "./helpers"; +import { bind, Variable } from "astal"; +import { Astal } from "astal/gtk3"; + +const { + label, + onIcon, + offIcon, + onLabel, + offLabel, + rightClick, + middleClick, + scrollUp, + scrollDown, +} = options.bar.customModules.warp; + +const thorttledToggleWarp = throttleInput(() => toggleWarp(isWarpConnect), 1000); + +export const Warp = (): BarBoxChild => { + const iconBinding = Variable.derive([bind(isWarpConnect), bind(onIcon), bind(offIcon)], (active, onIcn, offIcn) => { + return active ? onIcn : offIcn; + }) + + const tooltipBinding = Variable.derive([isWarpConnect], (active) => { + return active ? 'Connect' : "Disconnect"; + }); + + const labelBinding = Variable.derive([bind(isWarpConnect), bind(onLabel), bind(offLabel)], (active, onLbl, offLbl) => { + return active ? onLbl : offLbl; + }); + + const warpModule = Module({ + textIcon: iconBinding(), + tooltipText: tooltipBinding(), + boxClass: 'warp', + label: labelBinding(), + showLabelBinding: bind(label), + props: { + setup: (self: Astal.Button) => { + inputHandler(self, { + onPrimaryClick: { + fn: () => { + thorttledToggleWarp(); + }, + }, + onSecondaryClick: { + cmd: rightClick, + }, + onMiddleClick: { + cmd: middleClick, + }, + onScrollUp: { + cmd: scrollUp, + }, + onScrollDown: { + cmd: scrollDown, + }, + }); + }, + onDestroy: () => { + iconBinding.drop(); + tooltipBinding.drop(); + labelBinding.drop(); + }, + }, + }); + + return warpModule; +}; diff --git a/src/lib/types/options.d.ts b/src/lib/types/options.d.ts index a7b639c4a..8f118ff08 100644 --- a/src/lib/types/options.d.ts +++ b/src/lib/types/options.d.ts @@ -47,7 +47,8 @@ export type BarModule = | 'power' | 'systray' | 'hypridle' - | 'hyprsunset'; + | 'hyprsunset' + 'warp'; export type BarLayout = { left: BarModule[]; diff --git a/src/options.ts b/src/options.ts index d6f45a644..1b2691811 100644 --- a/src/options.ts +++ b/src/options.ts @@ -395,6 +395,15 @@ const options = mkOptions(CONFIG, { icon_background: opt(colors.base2), spacing: opt('0.45em'), }, + warp: { + enableBorder: opt(false), + border: opt(colors.yellow), + background: opt(colors.base2), + text: opt(colors.yellow), + icon: opt(colors.yellow), + icon_background: opt(colors.base2), + spacing: opt('0.45em'), + } }, }, menus: { @@ -1142,6 +1151,17 @@ const options = mkOptions(CONFIG, { scrollUp: opt(''), scrollDown: opt(''), }, + warp: { + label: opt(true), + onIcon: opt(''), + offIcon: opt('󰇖'), + onLabel: opt('On'), + offLabel: opt('Off'), + rightClick: opt(''), + middleClick: opt(''), + scrollUp: opt(''), + scrollDown: opt(''), + }, }, }, diff --git a/src/scss/style/bar/style.scss b/src/scss/style/bar/style.scss index dc75a21da..b9aa5100f 100644 --- a/src/scss/style/bar/style.scss +++ b/src/scss/style/bar/style.scss @@ -448,3 +448,25 @@ // custom font size 1.075em // ); + +@include styleModule( + // + // class name + 'warp', + // label color + $bar-buttons-modules-warp-text, + // icon color + $bar-buttons-modules-warp-icon, + // icon background if split style is used + $bar-buttons-modules-warp-icon_background, + // label background + $bar-buttons-modules-warp-background, + // inner spacing + $bar-buttons-modules-warp-spacing, + // if border enabled + $bar-buttons-modules-warp-enableBorder, + // border color + $bar-buttons-modules-warp-border, + // custom font size + 1.075em // +); From a91ad7ce3a7edb533ff2c3110222b4b809f06c0f Mon Sep 17 00:00:00 2001 From: myamusashi Date: Wed, 25 Dec 2024 19:30:34 +0700 Subject: [PATCH 2/2] add polling for icon --- src/components/bar/modules/warp/helpers/index.ts | 6 ++++++ src/components/bar/modules/warp/index.tsx | 12 +++++++++++- src/options.ts | 1 + 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/components/bar/modules/warp/helpers/index.ts b/src/components/bar/modules/warp/helpers/index.ts index 235a1b769..1729b0f63 100644 --- a/src/components/bar/modules/warp/helpers/index.ts +++ b/src/components/bar/modules/warp/helpers/index.ts @@ -15,3 +15,9 @@ export const toggleWarp = async (isWarpConnect: Variable): Promise { + execAsync(isWarpConnectCommand).then((res) => { + isWarpConnect.set(res === 'Connected'); + }); +}; diff --git a/src/components/bar/modules/warp/index.tsx b/src/components/bar/modules/warp/index.tsx index 3eeeb3840..f41c9ab72 100644 --- a/src/components/bar/modules/warp/index.tsx +++ b/src/components/bar/modules/warp/index.tsx @@ -2,12 +2,14 @@ import options from "src/options"; import { Module } from "../../shared/Module"; import { inputHandler, throttleInput } from "../../utils/helpers"; import { BarBoxChild } from "src/lib/types/bar"; -import { isWarpConnect, toggleWarp } from "./helpers"; +import { checkWarpStatus, isWarpConnect, toggleWarp } from "./helpers"; import { bind, Variable } from "astal"; import { Astal } from "astal/gtk3"; +import { FunctionPoller } from "src/lib/poller/FunctionPoller"; const { label, + pollingInterval, onIcon, offIcon, onLabel, @@ -18,6 +20,14 @@ const { scrollDown, } = options.bar.customModules.warp; +const dummyVar = Variable(undefined); + +checkWarpStatus(); + +const warpPoller = new FunctionPoller(dummyVar, [], bind(pollingInterval), checkWarpStatus); + +warpPoller.initialize('warp'); + const thorttledToggleWarp = throttleInput(() => toggleWarp(isWarpConnect), 1000); export const Warp = (): BarBoxChild => { diff --git a/src/options.ts b/src/options.ts index 1b2691811..d9bad79c9 100644 --- a/src/options.ts +++ b/src/options.ts @@ -1157,6 +1157,7 @@ const options = mkOptions(CONFIG, { offIcon: opt('󰇖'), onLabel: opt('On'), offLabel: opt('Off'), + pollingInterval: opt(1000 * 2), rightClick: opt(''), middleClick: opt(''), scrollUp: opt(''),