generated from exteraGramPlugins/pluginBase
Publish plugin / publish (push) Successful in 5s
Read receipts, story views, typing and online status are held back per the options; read on interact, scheduled and silent sending as in AyuGram. Every option resolves chat -> account -> global; forum topics follow their group. Settings live in the plugin page, a chat/profile menu popup, and a drawer row for the current account. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
187 lines
7.0 KiB
Python
187 lines
7.0 KiB
Python
"""The plugin's settings screen.
|
|
|
|
main page global ghost mode switch, the option switches, the accounts
|
|
account page that account's choice per option (Global / On / Off) and
|
|
its chat exceptions
|
|
"""
|
|
|
|
from ui.settings import Divider, Header, Selector, Switch, Text
|
|
|
|
import features
|
|
import peers
|
|
from prefs import INHERIT, OFF, ON, account_key, chats_key, global_key
|
|
|
|
GHOST_KEY = "g_ghost"
|
|
GHOST_ICON = "ghost"
|
|
|
|
|
|
def _state(value):
|
|
return "On" if value else "Off"
|
|
|
|
|
|
class SettingsPage:
|
|
def __init__(self, plugin, prefs, menus):
|
|
self.plugin = plugin
|
|
self.prefs = prefs
|
|
self.menus = menus
|
|
|
|
# main page
|
|
|
|
def build(self):
|
|
prefs = self.prefs
|
|
# The master switch shows whether every essential is on (AyuGram's
|
|
# isGhostModeActive), whichever way they got there.
|
|
self.plugin.set_setting(GHOST_KEY, prefs.ghost_active(0))
|
|
rows = [
|
|
Header(text="Ghost mode"),
|
|
Switch(
|
|
key=GHOST_KEY,
|
|
text="Ghost mode",
|
|
default=False,
|
|
subtext="Turns all ghost essentials on or off",
|
|
icon=GHOST_ICON,
|
|
on_change=self._on_ghost_change,
|
|
),
|
|
Header(text="Ghost essentials"),
|
|
]
|
|
rows += [self._switch(f) for f in features.ESSENTIALS]
|
|
rows.append(Header(text="Options"))
|
|
rows += [self._switch(f) for f in features.EXTRAS]
|
|
rows.append(Divider(text="These are the defaults. Each account can override them, and each chat can override its account: open the chat's ⋮ menu → Ghost mode."))
|
|
rows.append(Header(text="Accounts"))
|
|
accounts = self._accounts()
|
|
for slot, uid in accounts:
|
|
rows.append(
|
|
Text(
|
|
text=peers.account_name(slot),
|
|
subtext=self._account_summary(uid),
|
|
icon="msg_contacts",
|
|
create_sub_fragment=lambda slot=slot, uid=uid: self.build_account(slot, uid),
|
|
)
|
|
)
|
|
if not accounts:
|
|
rows.append(Text(text="No signed-in accounts", icon="msg_info"))
|
|
rows.append(Divider(text="The side menu's Ghost mode item opens these options for the account in use."))
|
|
return rows
|
|
|
|
def _switch(self, feature):
|
|
return Switch(
|
|
key=global_key(feature),
|
|
text=feature.title,
|
|
default=feature.default,
|
|
subtext=feature.subtext,
|
|
icon=feature.icon,
|
|
on_change=self._on_essential_change if feature.essential else None,
|
|
)
|
|
|
|
def _on_ghost_change(self, enabled):
|
|
for feature in features.ESSENTIALS:
|
|
self.prefs.set_global(feature, enabled)
|
|
self.plugin.set_setting(GHOST_KEY, bool(enabled), True)
|
|
|
|
def _on_essential_change(self, _value):
|
|
active = self.prefs.ghost_active(0)
|
|
if bool(self.plugin.get_setting(GHOST_KEY, False)) != active:
|
|
self.plugin.set_setting(GHOST_KEY, active, True)
|
|
|
|
def _accounts(self):
|
|
try:
|
|
return peers.signed_in()
|
|
except Exception as exc:
|
|
self.plugin.log(f"accounts: {exc}")
|
|
return []
|
|
|
|
def _account_summary(self, uid):
|
|
overridden = len(self.prefs.account_overrides(uid))
|
|
chats = len(self.prefs.chat_overrides(uid))
|
|
parts = [f"Ghost mode {_state(self.prefs.ghost_active(uid)).lower()}"]
|
|
parts.append(f"{overridden} own option{'s' if overridden != 1 else ''}" if overridden else "global options")
|
|
if chats:
|
|
parts.append(f"{chats} chat exception{'s' if chats != 1 else ''}")
|
|
return " · ".join(parts)
|
|
|
|
# account page
|
|
|
|
def build_account(self, slot, uid):
|
|
prefs = self.prefs
|
|
ghost_key = f"a_{uid}_ghost"
|
|
self.plugin.set_setting(ghost_key, self._ghost_choice(uid))
|
|
rows = [
|
|
Header(text=peers.account_name(slot)),
|
|
Selector(
|
|
key=ghost_key,
|
|
text="Ghost mode",
|
|
default=INHERIT,
|
|
items=["Global", "On", "Off"],
|
|
icon=GHOST_ICON,
|
|
on_change=lambda choice: self._on_account_ghost_change(uid, choice),
|
|
),
|
|
Header(text="Options"),
|
|
]
|
|
for feature in features.ALL:
|
|
global_value = prefs.global_value(feature)
|
|
rows.append(
|
|
Selector(
|
|
key=account_key(uid, feature),
|
|
text=feature.title,
|
|
default=INHERIT,
|
|
items=[f"Global ({_state(global_value)})", "On", "Off"],
|
|
icon=feature.icon,
|
|
on_change=lambda _choice: self._refresh_account_ghost(uid),
|
|
)
|
|
)
|
|
rows.append(Divider(text="Global follows the plugin's main switches."))
|
|
rows.append(Header(text="Chat exceptions"))
|
|
chats = prefs.chat_overrides(uid)
|
|
for dialog, values in sorted(chats.items(), key=lambda item: peers.dialog_title(slot, item[0]).lower()):
|
|
rows.append(
|
|
Text(
|
|
text=peers.dialog_title(slot, dialog),
|
|
subtext=" · ".join(
|
|
f"{features.BY_KEY[k].title}: {_state(v)}" for k, v in values.items()
|
|
),
|
|
icon="msg_discussion",
|
|
on_click=lambda _view, dialog=dialog: self._edit_chat(slot, uid, dialog),
|
|
)
|
|
)
|
|
if chats:
|
|
rows.append(
|
|
Text(
|
|
text="Remove all chat exceptions",
|
|
icon="msg_delete",
|
|
red=True,
|
|
on_click=lambda _view: prefs.clear_chats(uid, True),
|
|
)
|
|
)
|
|
else:
|
|
rows.append(Text(text="No chat exceptions", icon="msg_info"))
|
|
rows.append(Divider(text="Add one from a chat's ⋮ menu → Ghost mode. Tap an exception to change it."))
|
|
return rows
|
|
|
|
def _ghost_choice(self, uid):
|
|
"""What the account's Ghost mode selector shows."""
|
|
choices = {self.prefs.account_choice(uid, f) for f in features.ESSENTIALS}
|
|
if choices == {INHERIT}:
|
|
return INHERIT
|
|
return ON if self.prefs.ghost_active(uid) else OFF
|
|
|
|
def _on_account_ghost_change(self, uid, choice):
|
|
for feature in features.ESSENTIALS:
|
|
self.prefs.set_account_choice(uid, feature, choice)
|
|
self.plugin.set_setting(f"a_{uid}_ghost", int(choice), True)
|
|
|
|
def _refresh_account_ghost(self, uid):
|
|
key = f"a_{uid}_ghost"
|
|
choice = self._ghost_choice(uid)
|
|
if self.plugin.get_setting(key, INHERIT) != choice:
|
|
self.plugin.set_setting(key, choice, True)
|
|
|
|
def _edit_chat(self, slot, uid, dialog):
|
|
# Reload the page once the dialog closes, so the list shows the result.
|
|
raw_key = chats_key(uid)
|
|
|
|
def closed():
|
|
self.plugin.set_setting(raw_key, self.plugin.get_setting(raw_key, ""), True)
|
|
|
|
self.menus.open_chat_dialog(slot, dialog, closed)
|