ags: sync

This commit is contained in:
end-4
2024-01-11 16:49:37 +07:00
parent cdd8f7e252
commit 22b5993f79
96 changed files with 3346 additions and 2598 deletions
-245
View File
@@ -1,245 +0,0 @@
// Not yet used. For cool drag and drop stuff. Thanks DevAlien
const Toggles = {};
Toggles.Wifi = NetworkToggle;
Toggles.Bluetooth = BluetoothToggle;
Toggles.DND = DNDToggle;
Toggles.ThemeToggle = ThemeToggle;
Toggles.ProfileToggle = ProfileToggle;
// Toggles.Record = RecordToggle;
// Toggles.Airplane = AirplaneToggle;
// Toggles.DoNotDisturb = DoNotDisturbToggle;
const TARGET = [Gtk.TargetEntry.new("text/plain", Gtk.TargetFlags.SAME_APP, 0)];
export class ActionCenter extends Gtk.Box {
static {
GObject.registerClass({
GTypeName: 'ActionCenter',
Properties: {
},
}, this);
}
constructor({ className = "ActionCenter", toggles, ...rest }) {
super(rest);
this.toggles = Toggles
this.currentToggles = Settings.getSetting("toggles", []);
this.mainFlowBox = this._setupFlowBox(className + QSView.editing && className + "Editing");
this.mainFlowBox.connect("drag_motion", this._dragMotionMain);
this.mainFlowBox.connect("drag_drop", this._dragDropMain);
this._dragged = {};
this._draggedExtra = {};
this._dragged;
this._currentPosition = 0;
this._orderedState;
this._draggedName;
this.updateList(toggles, this.mainFlowBox)
this.set_orientation(Gtk.Orientation.VERTICAL);
this.add(this.mainFlowBox)
this.mainFlowBox.set_size_request(1, 30)
if (QSView.editing) {
this.extraFlowBox = this._setupFlowBox(className);
this.extraFlowBox.connect("drag_motion", this._dragMotionExtra);
this.extraFlowBox.connect("drag_drop", this._dragDropExtra);
this.updateList(this._getExtraToggles(), this.extraFlowBox)
this.add(Box({
vertical: true,
children: [
Label("Extra widgets"),
Label("Drop here to remove or drag from here to add"),
this.extraFlowBox
]
}))
}
}
_getExtraToggles() {
let toggles = { ...this.toggles }
this.currentToggles.map(t => {
if (toggles[t]) {
delete toggles[t];
}
});
return Object.keys(toggles);
}
_setupFlowBox(className) {
const flowBox = new Gtk.FlowBox();
flowBox.set_valign(Gtk.Align.FILL);
flowBox.set_min_children_per_line(2);
flowBox.set_max_children_per_line(2);
flowBox.set_selection_mode(Gtk.SelectionMode.NONE);
flowBox.get_style_context().add_class(className);
flowBox.set_homogeneous(true);
flowBox.drag_dest_set(Gtk.DestDefaults.ALL, TARGET, Gdk.DragAction.COPY);
return flowBox;
}
createWidget = (name, index, type) => {
const editSetup = (widget) => {
widget.drag_source_set(
Gdk.ModifierType.BUTTON1_MASK,
TARGET,
Gdk.DragAction.COPY
);
widget.connect("drag-begin", (w, context) => {
const widgetContainer = widget.get_parent();
Gtk.drag_set_icon_surface(context, createSurfaceFromWidget(widgetContainer));
this._dragged = {
widget: widgetContainer.get_parent().get_parent(),
container: widgetContainer,
name: name,
currentPosition: type === "Main" ? index : null,
currentPositionExtra: type === "Extra" ? index : null,
from: type,
}
widgetContainer.get_style_context().add_class("hidden");
if (type !== "Main") {
this.extraFlowBox.remove(this._dragged.widget);
}
return true;
});
widget.connect("drag-failed", () => {
this.updateList(Settings.getSetting("toggles"), this.mainFlowBox)
this.updateList(this._getExtraToggles(), this.extraFlowBox)
});
}
let row = new Gtk.FlowBoxChild({ visible: true });
row.add(Toggles[name]({ setup: QSView.editing && editSetup, QSView: QSView }));
row._index = index;
row._name = name;
return row;
}
updateList(toggles, flowBox) {
let type = flowBox === this.mainFlowBox ? "Main" : "Extra"
var childrenBox = flowBox.get_children();
childrenBox.forEach((element) => {
flowBox.remove(element);
element.destroy();
});
if (!toggles) return;
toggles.forEach((name, i) => {
if (Toggles[name])
flowBox.add(this.createWidget(name, i, type));
});
flowBox.show_all();
}
_dragMotionMain = (widget, context, x, y, time) => {
if (this._dragged.currentPositionExtra !== null) {
this._dragged.currentPositionExtra = null;
if (this._isChild(this.extraFlowBox, this._dragged.widget)) {
this.extraFlowBox.remove(this._dragged.widget);
}
}
const children = this.mainFlowBox.get_children();
const sampleItem = children[0];
const sampleWidth = sampleItem.get_allocation().width;
const sampleHeight = sampleItem.get_allocated_height();
const perLine = Math.floor(this.mainFlowBox.get_allocation().width / sampleWidth);
const pos = Math.floor(y / sampleHeight) * perLine + Math.floor(x / sampleWidth);
if (pos >= children.length && pos !== 0) return false;
if (this._dragged.currentPosition === null) {
this.mainFlowBox.insert(this._dragged.widget, pos);
this._dragged.currentPosition = pos;
} else if (this._dragged.currentPosition !== pos) {
if (this._isChild(this.mainFlowBox, this._dragged.widget)) {
this.mainFlowBox.remove(this._dragged.widget);
}
this.mainFlowBox.insert(this._dragged.widget, pos);
this._dragged.currentPosition = pos;
}
return true;
}
_dragDropMain = () => {
if (this._dragged.from !== "Main") {
this.currentToggles.splice(this._dragged.currentPosition, 0, this._dragged.name);
} else {
const indexCurrentToggle = this.currentToggles.indexOf(this._dragged.name);
this.currentToggles.splice(indexCurrentToggle, 1);
this.currentToggles.splice(this._dragged.currentPosition, 0, this._dragged.name);
}
Settings.setSetting("toggles", this.currentToggles);
this._dragged.container.get_style_context().remove_class("hidden");
return true;
}
_dragDropExtra = () => {
if (this._dragged.from === "Main") {
const indexCurrentToggle = this.currentToggles.indexOf(this._dragged.name);
this.currentToggles.splice(indexCurrentToggle, 1);
}
Settings.setSetting("toggles", this.currentToggles);
this._dragged.container.get_style_context().remove_class("hidden");
return true;
}
_dragMotionExtra = (widget, context, x, y, time) => {
if (this._dragged.currentPosition !== null) {
this._dragged.currentPosition = null;
if (this._isChild(this.mainFlowBox, this._dragged.widget)) {
this.mainFlowBox.remove(this._dragged.widget);
}
}
const children = this.extraFlowBox.get_children();
const sampleItem = children[0];
let pos = 0;
if (sampleItem) {
const sampleWidth = sampleItem.get_allocation().width;
const sampleHeight = sampleItem.get_allocated_height();
const perLine = Math.floor(this.extraFlowBox.get_allocation().width / sampleWidth);
pos = Math.floor(y / sampleHeight) * perLine + Math.floor(x / sampleWidth);
}
if (pos >= children.length && pos !== 0) return false;
if (this._dragged.currentPositionExtra === null) {
this.extraFlowBox.insert(this._dragged.widget, pos);
this._dragged.currentPositionExtra = pos;
}
if (this._dragged.currentPositionExtra !== pos) {
if (this._isChild(this.extraFlowBox, this._dragged.widget)) {
this.extraFlowBox.remove(this._dragged.widget);
}
this.extraFlowBox.insert(this._dragged.widget, pos);
this._dragged.currentPositionExtra = pos;
}
return true;
}
_isChild(container, widget) {
let found = false;
container.get_children().forEach((c) => {
if (c === widget) found = true;
})
return found;
}
}
@@ -1,6 +1,6 @@
const { Gdk, Gtk } = imports.gi;
import { App, SCREEN_WIDTH, SCREEN_HEIGHT, Service, Utils, Variable, Widget } from '../imports.js';
const { Box, Button, Entry, EventBox, Icon, Label, Revealer, Scrollable, Stack } = Widget;
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
const { Revealer, Scrollable } = Widget;
export const MarginRevealer = ({
transition = 'slide_down',
@@ -8,51 +8,49 @@ export const MarginRevealer = ({
revealChild,
showClass = 'element-show', // These are for animation curve, they don't really hide
hideClass = 'element-hide', // Don't put margins in these classes!
extraProperties = [],
extraSetup = () => { },
...rest
}) => {
const widget = Scrollable({
...rest,
css: `min-height: 0px;`,
properties: [
['revealChild', true], // It'll be set to false after init if it's supposed to hide
['transition', transition],
['show', (self) => {
if (self._revealChild) return;
self.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.NEVER);
attribute: {
'revealChild': true, // It'll be set to false after init if it's supposed to hide
'transition': transition,
'show': () => {
if (widget.attribute.revealChild) return;
widget.hscroll = 'never';
widget.vscroll = 'never';
child.toggleClassName(hideClass, false);
child.toggleClassName(showClass, true);
self._revealChild = true;
widget.attribute.revealChild = true;
child.css = 'margin: 0px;';
}],
['hide', (self) => {
if (!self._revealChild) return;
},
'hide': () => {
if (!widget.attribute.revealChild) return;
child.toggleClassName(hideClass, true);
child.toggleClassName(showClass, false);
self._revealChild = false;
if (self._transition == 'slide_left')
widget.attribute.revealChild = false;
if (widget.attribute.transition == 'slide_left')
child.css = `margin-right: -${child.get_allocated_width()}px;`;
else if (self._transition == 'slide_right')
else if (widget.attribute.transition == 'slide_right')
child.css = `margin-left: -${child.get_allocated_width()}px;`;
else if (self._transition == 'slide_up')
else if (widget.attribute.transition == 'slide_up')
child.css = `margin-bottom: -${child.get_allocated_height()}px;`;
else if (self._transition == 'slide_down')
else if (widget.attribute.transition == 'slide_down')
child.css = `margin-top: -${child.get_allocated_height()}px;`;
}],
['toggle', (self) => {
},
'toggle': () => {
console.log('toggle');
if (self._revealChild) self._hide(self);
else self._show(self);
}],
...extraProperties,
],
setup: (self) => {
if (!revealChild)
self.set_policy(Gtk.PolicyType.ALWAYS, Gtk.PolicyType.ALWAYS);
else
self.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.NEVER);
self.child = child;
if (widget.attribute.revealChild) widget.attribute.hide();
else widget.attribute.show();
},
},
child: child,
hscroll: `${revealChild ? 'never' : 'always'}`,
vscroll: `${revealChild ? 'never' : 'always'}`,
setup: (self) => {
extraSetup(self);
}
});
child.toggleClassName(`${revealChild ? showClass : hideClass}`, true);
return widget;
+5 -3
View File
@@ -1,7 +1,7 @@
const { Gdk, Gtk } = imports.gi;
const GObject = imports.gi.GObject;
const { Gtk } = imports.gi;
const Lang = imports.lang;
import { Utils, Widget } from '../imports.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js'
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'
// -- Styling --
// min-height for diameter
@@ -17,6 +17,7 @@ export const AnimatedCircProg = ({
initTo = 0,
initAnimTime = 2900,
initAnimPoints = 1,
extraSetup = () => { },
...rest
}) => Widget.DrawingArea({
...rest,
@@ -100,5 +101,6 @@ export const AnimatedCircProg = ({
// }
}
else area.css = 'font-size: 0px;';
extraSetup(area);
},
})
-2
View File
@@ -1,5 +1,3 @@
const { GLib, Gio } = imports.gi;
function checkLeapYear(year) {
return (
year % 400 == 0 ||
+20 -17
View File
@@ -1,8 +1,8 @@
const { Gdk, Gtk } = imports.gi;
import { App, Service, Utils, Variable, Widget } from '../imports.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
import { MaterialIcon } from './materialicon.js';
import { setupCursorHover } from './cursorhover.js';
const { Box, Button, Entry, EventBox, Icon, Label, Revealer, Scrollable, Stack } = Widget;
const { Box, Button, Label, Revealer } = Widget;
export const ConfigToggle = ({ icon, name, desc = '', initValue, onChange, ...rest }) => {
let value = initValue;
@@ -37,22 +37,25 @@ export const ConfigToggle = ({ icon, name, desc = '', initValue, onChange, ...re
]
});
const interactionWrapper = Button({
child: widgetContent,
onClicked: () => { // mouse up/kb press
value = !value;
toggleIcon.toggleClassName('switch-fg-toggling-false', false);
if (!value) {
toggleIcon.label = '';
toggleIcon.toggleClassName('txt-poof', true);
attribute: {
toggle: (newValue) => {
value = !value;
toggleIcon.toggleClassName('switch-fg-toggling-false', false);
if (!value) {
toggleIcon.label = '';
toggleIcon.toggleClassName('txt-poof', true);
}
toggleButtonIndicator.toggleClassName('switch-fg-true', value);
toggleButton.toggleClassName('switch-bg-true', value);
if (value) Utils.timeout(1, () => {
toggleIcon.label = 'check';
toggleIcon.toggleClassName('txt-poof', false);
})
onChange(interactionWrapper, value);
}
toggleButtonIndicator.toggleClassName('switch-fg-true', value);
toggleButton.toggleClassName('switch-bg-true', value);
if(value) Utils.timeout(1, () => {
toggleIcon.label = 'check';
toggleIcon.toggleClassName('txt-poof', false);
})
onChange(interactionWrapper, value);
},
child: widgetContent,
onClicked: (self) => self.attribute.toggle(self),
setup: (button) => {
setupCursorHover(button),
button.connect('pressed', () => { // mouse down
+1 -3
View File
@@ -1,6 +1,4 @@
const { Gdk, Gtk } = imports.gi;
const CLICK_BRIGHTEN_AMOUNT = 0.13;
const { Gdk } = imports.gi;
export function setupCursorHover(button) {
const display = Gdk.Display.get_default();
+2 -2
View File
@@ -1,7 +1,7 @@
import { Widget } from '../imports.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
export const MaterialIcon = (icon, size, props = {}) => Widget.Label({
className: `icon-material txt-${size}`,
label: icon,
...props,
})
})
+1 -28
View File
@@ -57,7 +57,7 @@ const pad = (lines, start = 1, end = 1) => {
return lines.map((l) => l.padEnd(len + end, ' ').padStart(len + end + start, ' '))
}
export function convert(text) {
export default (text) => {
let lines = text.split('\n')
// Indicates if the current line is within a code block
@@ -205,33 +205,6 @@ export function convert(text) {
return output.join('\n')
}
const readFile = (f) => {
// node.js only and when running from the command line
const fs = require('fs')
return fs.readFileSync(f, 'utf8')
}
let __is_nodejs_main = false
try {
// node.js specific checks and exports
__is_nodejs_main = (require.main === module)
exports.convert = convert
} catch (e) { }
if (__is_nodejs_main) {
// running in node.js called from the CLI
let args = process.argv.slice(2)
if (args.length == 0 || args.find((a) => a == '-h')) {
console.log(`Usage: ${process.argv[1]} FILE [FILE...]`)
process.exit(0)
}
for (let i = 0; i < args.length; i++) {
const f = args[i];
process.stdout.write(convert(readFile(f)));
}
}
export const markdownTest = `# Heading 1
## Heading 2
### Heading 3
+2 -3
View File
@@ -1,7 +1,6 @@
const { Gdk, Gtk } = imports.gi;
const GObject = imports.gi.GObject;
const { Gtk } = imports.gi;
const Lang = imports.lang;
import { Utils, Widget } from '../imports.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
// min-height/min-width for height/width
// background-color/color for background/indicator color
+33 -23
View File
@@ -1,13 +1,13 @@
// This file is for the actual widget for each single notification
const { GLib, Gdk, Gtk } = imports.gi;
import { Utils, Widget } from '../imports.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js'
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'
const { lookUpIcon, timeout } = Utils;
const { Box, EventBox, Icon, Overlay, Label, Button, Revealer } = Widget;
import { MaterialIcon } from "./materialicon.js";
import { setupCursorHover } from "./cursorhover.js";
import { AnimatedCircProg } from "./animatedcircularprogress.js";
import { MarginRevealer } from './advancedrevealers.js';
function guessMessageType(summary) {
if (summary.includes('recording')) return 'screen_record';
@@ -93,13 +93,13 @@ export default ({
const widget = EventBox({
onHover: (self) => {
self.window.set_cursor(Gdk.Cursor.new_from_name(display, 'grab'));
if (!wholeThing._hovered)
wholeThing._hovered = true;
if (!wholeThing.attribute.hovered)
wholeThing.attribute.hovered = true;
},
onHoverLost: (self) => {
self.window.set_cursor(null);
if (wholeThing._hovered)
wholeThing._hovered = false;
if (wholeThing.attribute.hovered)
wholeThing.attribute.hovered = false;
if (isPopup) {
command();
}
@@ -109,13 +109,13 @@ export default ({
}
});
const wholeThing = Revealer({
properties: [
['id', notifObject.id],
['close', undefined],
['hovered', false],
['dragging', false],
['destroyWithAnims', () => destroyWithAnims]
],
attribute: {
'id': notifObject.id,
'close': undefined,
'hovered': false,
'dragging': false,
'destroyWithAnims': () => destroyWithAnims,
},
revealChild: false,
transition: 'slide_down',
transitionDuration: 200,
@@ -159,18 +159,23 @@ export default ({
label: notifObject.body,
}),
Box({
homogeneous: true,
className: 'notif-actions',
className: 'notif-actions spacing-h-5',
children: [
Button({
hexpand: true,
className: `notif-action notif-action-${notifObject.urgency}`,
label: 'Close',
onClicked: () => destroyWithAnims(),
child: Label({
label: 'Close',
})
}),
...notifObject.actions.map(action => Widget.Button({
hexpand: true,
className: `notif-action notif-action-${notifObject.urgency}`,
onClicked: () => notifObject.invoke(action.id),
label: action.label,
child: Label({
label: action.label,
})
}))
],
})
@@ -258,8 +263,13 @@ export default ({
className: `${isPopup ? 'popup-' : ''}notif-${notifObject.urgency} spacing-h-10`,
children: [
notifIcon,
notifText,
notifExpandButton,
Box({
className: 'spacing-h-5',
children: [
notifText,
notifExpandButton,
]
})
]
})
@@ -334,7 +344,7 @@ export default ({
}
}
wholeThing._dragging = Math.abs(offset_x) > 10;
wholeThing.attribute.dragging = Math.abs(offset_x) > 10;
if (widget.window)
widget.window.set_cursor(Gdk.Cursor.new_from_name(display, 'grabbing'));
@@ -354,9 +364,9 @@ export default ({
}, 'drag-update')
.hook(gesture, self => {
if (!self._ready) {
if (!self.attribute.ready) {
wholeThing.revealChild = true;
self._ready = true;
self.attribute.ready = true;
return;
}
const offset_h = gesture.get_offset()[1];
@@ -387,7 +397,7 @@ export default ({
if (widget.window)
widget.window.set_cursor(Gdk.Cursor.new_from_name(display, 'grab'));
wholeThing._dragging = false;
wholeThing.attribute.dragging = false;
}
initDirX = 0;
initDirVertical = -1;
+2 -1
View File
@@ -1,4 +1,5 @@
import { App, Widget } from '../imports.js';
import App from 'resource:///com/github/Aylur/ags/app.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
const { Box, Window } = Widget;
+1 -1
View File
@@ -1,4 +1,4 @@
import { Widget } from '../imports.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
const { Gtk } = imports.gi;
const Lang = imports.lang;
+1 -1
View File
@@ -1,4 +1,4 @@
import { App, Service, Utils, Widget } from '../imports.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
export const separatorLine = Widget.Box({
className: 'separator-line',
+28 -18
View File
@@ -1,4 +1,7 @@
import { App, Service, Utils, Widget } from '../imports.js';
import App from 'resource:///com/github/Aylur/ags/app.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
import { MaterialIcon } from './materialicon.js';
import Bluetooth from 'resource:///com/github/Aylur/ags/service/bluetooth.js';
import Network from 'resource:///com/github/Aylur/ags/service/network.js';
@@ -44,23 +47,21 @@ export const NotificationIndicator = (notifCenterName = 'sideright') => {
MaterialIcon('notifications', 'norm'),
Widget.Label({
className: 'txt-small titlefont',
properties: [
['increment', (self) => self._unreadCount++],
['markread', (self) => self._unreadCount = 0],
['update', (self) => self.label = `${self._unreadCount}`],
['unreadCount', 0],
],
attribute: {
unreadCount: 0,
update: (self) => self.label = `${self.attribute.unreadCount}`,
},
setup: (self) => self
.hook(Notifications, (self, id) => {
if (!id || Notifications.dnd) return;
if (!Notifications.getNotification(id)) return;
self._increment(self);
self._update(self);
self.attribute.unreadCount++;
self.attribute.update(self);
}, 'notified')
.hook(App, (self, currentName, visible) => {
if (visible && currentName === notifCenterName) {
self._markread(self);
self._update(self);
self.attribute.unreadCount = 0;
self.attribute.update(self);
}
})
,
@@ -74,8 +75,8 @@ export const NotificationIndicator = (notifCenterName = 'sideright') => {
export const BluetoothIndicator = () => Widget.Stack({
transition: 'slide_up_down',
items: [
['true', Widget.Label({ className: 'txt-norm icon-material', label: 'bluetooth' })],
['false', Widget.Label({ className: 'txt-norm icon-material', label: 'bluetooth_disabled' })],
['true', Widget.Label({ className: 'txt-norm icon-material', label: 'bluetooth' })],
],
setup: (self) => self
.hook(Bluetooth, stack => {
@@ -99,7 +100,7 @@ const NetworkWiredIndicator = () => Widget.Stack({
return;
const { internet } = Network.wired;
if (internet === 'connected' || internet === 'connecting')
if (['connecting', 'connected'].includes(internet))
stack.shown = internet;
else if (Network.connectivity !== 'full')
stack.shown = 'disconnected';
@@ -135,7 +136,7 @@ const NetworkWifiIndicator = () => Widget.Stack({
if (Network.wifi.internet == 'connected') {
stack.shown = String(Math.ceil(Network.wifi.strength / 25));
}
else if (Network.wifi.internet == 'disconnected' || Network.wifi.internet == 'connecting') {
else if (["disconnected", "connecting"].includes(Network.wifi.internet)) {
stack.shown = Network.wifi.internet;
}
}),
@@ -154,14 +155,14 @@ export const NetworkIndicator = () => Widget.Stack({
return;
}
const primary = Network.primary || 'fallback';
if (primary == 'wifi' || primary == 'wired')
if (['wifi', 'wired'].includes(primary))
stack.shown = primary;
else
stack.shown = 'fallback';
}),
});
const KeyboardLayout = ({ useFlag } = {}) => {
const HyprlandXkbKeyboardLayout = async ({ useFlag } = {}) => {
var initLangs = [];
var languageStackArray = [];
var currentKeyboard;
@@ -215,15 +216,24 @@ const KeyboardLayout = ({ useFlag } = {}) => {
return widgetRevealer;
}
const OptionalKeyboardLayout = async () => {
try {
return await HyprlandXkbKeyboardLayout({ useFlag: false });
} catch {
return null;
}
};
const optionalKeyboardLayoutInstance = await OptionalKeyboardLayout();
export const StatusIcons = (props = {}) => Widget.Box({
...props,
child: Widget.Box({
className: 'spacing-h-15',
children: [
KeyboardLayout({ useFlag: false }),
optionalKeyboardLayoutInstance,
NotificationIndicator(),
BluetoothIndicator(),
NetworkIndicator(),
BluetoothIndicator(),
]
})
});