refactor: rename some flake attr directories

This commit is contained in:
matt1432 2024-12-16 15:51:41 -05:00
parent 1ce40f2c1a
commit 6ca0d7248b
329 changed files with 178 additions and 139 deletions

View file

@ -0,0 +1,44 @@
@use 'sass:color';
@use '../../style/colors';
.widget.audio {
.header {
.header-btn {
font-size: 30px;
margin: 5px;
transition: background 400ms;
&.active {
background: colors.$window_bg_color;
}
}
}
scrollable {
margin: 5px;
min-height: 400px;
box {
.item-btn {
margin: 3px;
}
}
}
.stream {
margin: 5px;
padding: 10px;
border-radius: 8px;
background-color: color.adjust(colors.$window_bg_color, $lightness: -3%);
.body {
.toggle {
padding: 5px;
icon {
font-size: 26px;
}
}
}
}
}

View file

@ -0,0 +1,18 @@
import { Astal } from 'astal/gtk3';
import PopupWindow from '../misc/popup-window';
import { get_gdkmonitor_from_desc } from '../../lib';
import AudioWidget from './main';
export default () => (
<PopupWindow
name="audio"
gdkmonitor={get_gdkmonitor_from_desc('desc:Acer Technologies Acer K212HQL T3EAA0014201')}
anchor={Astal.WindowAnchor.RIGHT | Astal.WindowAnchor.BOTTOM}
transition="slide bottom"
>
<AudioWidget />
</PopupWindow>
);

View file

@ -0,0 +1,106 @@
import { bind, Variable } from 'astal';
import { Gtk, Widget } from 'astal/gtk3';
import AstalWp from 'gi://AstalWp';
import Separator from '../misc/separator';
import Streams from './streams';
import Profiles from './profiles';
export default () => {
const audio = AstalWp.get_default()?.get_audio();
if (!audio) {
throw new Error('Could not find default audio devices.');
}
const Shown = Variable<string>('outputs');
const stack = (
<stack
shown={bind(Shown)}
transitionType={Gtk.StackTransitionType.SLIDE_LEFT_RIGHT}
>
<scrollable
name="outputs"
hscroll={Gtk.PolicyType.NEVER}
setup={(self) => setTimeout(() => {
self.add((
<box vertical>
{bind(audio, 'speakers').as(Streams)}
</box>
));
}, 1000)}
/>
<scrollable
name="inputs"
hscroll={Gtk.PolicyType.NEVER}
setup={(self) => setTimeout(() => {
self.add((
<box vertical>
{bind(audio, 'microphones').as(Streams)}
</box>
));
}, 1000)}
/>
<scrollable
name="profiles"
hscroll={Gtk.PolicyType.NEVER}
setup={(self) => setTimeout(() => {
self.add((
<box vertical>
{bind(audio, 'devices').as(Profiles)}
</box>
));
}, 1000)}
/>
</stack>
) as Widget.Stack;
const StackButton = ({ label = '', iconName = '' }) => (
<button
cursor="pointer"
className={bind(Shown).as((shown) =>
`header-btn${shown === label ? ' active' : ''}`)}
onButtonReleaseEvent={() => {
Shown.set(label);
}}
>
<box halign={Gtk.Align.CENTER}>
<icon icon={iconName} />
<Separator size={8} />
{label}
</box>
</button>
) as Widget.Button;
return (
<box
className="audio widget"
vertical
>
<box
className="header"
homogeneous
>
<StackButton label="outputs" iconName="audio-speakers-symbolic" />
<StackButton label="inputs" iconName="audio-input-microphone-symbolic" />
<StackButton label="profiles" iconName="application-default-symbolic" />
</box>
{stack}
</box>
);
};

View file

@ -0,0 +1,46 @@
import { bind } from 'astal';
import AstalWp from 'gi://AstalWp';
import { ComboBoxText } from '../misc/subclasses';
export default (devices: AstalWp.Device[]) => devices
.sort((a, b) => a.description.localeCompare(b.description))
.map((device) => (
<box className="stream" vertical>
<label label={bind(device, 'description')} />
<ComboBoxText
setup={(self) => {
const profiles = (device.get_profiles() ?? []).sort((a, b) => {
if (a.description === 'Off') {
return 1;
}
else if (b.description === 'Off') {
return -1;
}
else {
return a.description.localeCompare(b.description);
}
});
profiles.forEach((profile) => {
self.append(profile.index.toString(), profile.description);
});
self.set_active(
profiles.indexOf(
device.get_profile(device.get_active_profile())!,
),
);
}}
onChanged={(self) => {
device.set_active_profile(parseInt(self.activeId));
}}
/>
</box>
));

View file

@ -0,0 +1,96 @@
import { bind } from 'astal';
import { Gtk } from 'astal/gtk3';
import AstalWp from 'gi://AstalWp';
import { RadioButton } from '../misc/subclasses';
import Separator from '../misc/separator';
export default (streams: AstalWp.Endpoint[]) => {
let group: RadioButton | undefined;
return streams
.sort((a, b) => a.description.localeCompare(b.description))
.map((stream) => (
<box className="stream" vertical>
<box className="title">
<RadioButton
cursor="pointer"
css="margin-top: 1px;"
onRealize={(self) => {
if (!group) {
group = self;
}
else {
self.group = group;
}
self.active = stream.isDefault;
self.hook(stream, 'notify::is-default', () => {
self.active = stream.isDefault;
});
}}
onButtonReleaseEvent={() => {
stream.isDefault = true;
}}
/>
<Separator size={8} />
<label label={bind(stream, 'description')} />
</box>
<Separator size={4} vertical />
<box className="body">
<button
cursor="pointer"
className="toggle"
valign={Gtk.Align.END}
onButtonReleaseEvent={() => {
stream.mute = !stream.mute;
}}
>
<icon
icon={bind(stream, 'mute').as((isMuted) => {
if (stream.mediaClass === AstalWp.MediaClass.AUDIO_MICROPHONE) {
return isMuted ?
'audio-input-microphone-muted-symbolic' :
'audio-input-microphone-symbolic';
}
else {
return isMuted ?
'audio-volume-muted-symbolic' :
'audio-speakers-symbolic';
}
})}
/>
</button>
<Separator size={4} />
<slider
hexpand
halign={Gtk.Align.FILL}
drawValue
cursor="pointer"
value={bind(stream, 'volume')}
onDragged={(self) => {
stream.set_volume(self.value);
}}
/>
</box>
</box>
));
};

View file

@ -0,0 +1,15 @@
import { Astal } from 'astal/gtk3';
import PopupWindow from '../misc/popup-window';
import AudioWidget from './main';
export default () => (
<PopupWindow
name="audio"
anchor={Astal.WindowAnchor.RIGHT | Astal.WindowAnchor.TOP}
>
<AudioWidget />
</PopupWindow>
);