482 lines
13 KiB
Python
482 lines
13 KiB
Python
from .. import fediverse
|
|
from ..database import db, default_permissions
|
|
from ..exceptions import AccountNotFoundError, NoAccountsError
|
|
from ..functions import SignalBlock, connect, get_buffer_text
|
|
from ..objects.login_rows import SavedLoginRow
|
|
from ..passwords import passdb
|
|
|
|
|
|
class StatusBar:
|
|
def __init__(self, window):
|
|
self.window = window
|
|
self.app = window.app
|
|
|
|
self.siteoptions_handler_ids = []
|
|
self.bookmark_row = None
|
|
self.theme_enabled = False
|
|
|
|
self.toot_acct = None
|
|
self.toot_post = None
|
|
self.toot_max_len = 500
|
|
|
|
self.unsaved_logins = []
|
|
|
|
self.setup()
|
|
|
|
|
|
def bookmark_get_data(self):
|
|
data = DotDict()
|
|
|
|
for k,v in self.bookmark_fields.items():
|
|
if k == 'description':
|
|
data[k] = get_buffer_text(v.get_buffer())
|
|
|
|
else:
|
|
data[k] = v.get_text()
|
|
|
|
return data
|
|
|
|
|
|
def bookmark_set_data(self, name=None, url=None, category=None, description=None):
|
|
data = dict(name=name, url=url, category=category, description=description)
|
|
|
|
for k,v in data.items():
|
|
value = v if v != None else ''
|
|
|
|
if k == 'description':
|
|
self.bookmark_fields[k].get_buffer().set_text(value)
|
|
|
|
else:
|
|
self.bookmark_fields[k].set_text(value)
|
|
|
|
|
|
def login_unsaved_del_row(self, row):
|
|
self.logins.unsaved.remove(row['container'])
|
|
self.unsaved_logins.remove(row)
|
|
|
|
|
|
def login_unsaved_get_row(self, widget):
|
|
for row in self.unsaved_logins:
|
|
if widget == row['container']:
|
|
return row
|
|
|
|
|
|
def login_unsaved_new(self, data):
|
|
self.logins.unsaved.add(SavedLoginRow(data))
|
|
|
|
|
|
def login_unsaved_refresh(self):
|
|
for child in self.logins.unsaved.get_children():
|
|
self.logins.unsaved.remove(child)
|
|
child.destroy()
|
|
|
|
for row in self.unsaved_logins:
|
|
self.logins.unsaved(UnsavedLoginRow(row)['container'])
|
|
|
|
|
|
def toot_close(self, *args):
|
|
self.window['statusbar-toot-popover'].popdown()
|
|
|
|
|
|
def toot_clear(self, *args):
|
|
self.toot_fields.spoiler.set_text('')
|
|
self.toot_fields.content.get_buffer().set_text('')
|
|
self.toot_fields.visibility.set_active(0)
|
|
self.toot_update_count()
|
|
self.toot_set_reply()
|
|
|
|
|
|
def toot_set_account(self):
|
|
try:
|
|
self.toot_account = self.app.get_default_account()
|
|
|
|
except NoAccountsError:
|
|
self.window.notification('No active fedi accounts', 'error')
|
|
return False
|
|
|
|
return True
|
|
|
|
|
|
def toot_get_info(self):
|
|
return DotDict(
|
|
spoiler = self.toot_fields.spoiler.get_text(),
|
|
content = get_buffer_text(self.toot_fields.content.get_buffer()),
|
|
visibility = self.toot_fields.visibility.get_active_text()
|
|
)
|
|
|
|
|
|
def toot_send(self, *args):
|
|
data = self.toot_get_info()
|
|
options = {
|
|
'spoiler': data.spoiler,
|
|
'visibility': data.visibility.lower()
|
|
}
|
|
|
|
if not (data.spoiler or data.content):
|
|
return self.window.notification('Unwilling to send empty post', level='error')
|
|
|
|
if self.window['statusbar-toot-reply-scroll'].get_visible():
|
|
options['reply_id'] = self.toot_post.id
|
|
|
|
if fediverse.Post(self.toot_account.domain, self.toot_account.token, data.content, **options):
|
|
self.window.notification('Sent toot')
|
|
self.window['statusbar-toot-popover'].popdown()
|
|
self.toot_clear()
|
|
|
|
else:
|
|
self.window.notification('Failed to send toot', level='error')
|
|
|
|
|
|
def toot_set_reply(self, toot=None):
|
|
self.toot_post = toot
|
|
|
|
reply = self.toot_fields.reply
|
|
scroll = self.window['statusbar-toot-reply-scroll']
|
|
privacy = self.window['statusbar-toot-visibility']
|
|
account = self.toot_post.get('account') if toot else None
|
|
|
|
if not toot and not account:
|
|
scroll.hide()
|
|
return
|
|
|
|
text_buffer = reply.get_buffer()
|
|
text_buffer.set_text(f'Reply to: {account.display_name} ({account.acct}):\n\n{toot.content}')
|
|
reply.set_buffer(text_buffer)
|
|
|
|
privacy.set_active_id(toot.get('visibility', 'public'))
|
|
|
|
scroll.show()
|
|
|
|
|
|
def toot_update_count(self, *args):
|
|
spoiler = len(self.toot_fields.spoiler.get_text())
|
|
content = self.toot_fields.content.get_buffer().get_char_count()
|
|
num = spoiler + content
|
|
|
|
self.toot_fields.count.set_text(str(self.toot_max_len - num))
|
|
|
|
|
|
def handle_status_button(self, name):
|
|
try:
|
|
if not self.window[f'statusbar-{name}'].get_active():
|
|
return
|
|
|
|
except AttributeError:
|
|
pass
|
|
|
|
tab = self.window.active_tab
|
|
|
|
if name == 'debug':
|
|
#self.window.set_icons()
|
|
#self.window.themes.load_main()
|
|
#self.window.notification('Reloaded icons and main css', system=True)
|
|
#self.window.active_tab.editing_action('select')
|
|
#self.window.active_tab.editing_action('copy')
|
|
self.window.notification('Merp!', 'INFO', 0)
|
|
print(self.window.context.get_cookie_manager().delete_cookies_for_domain(self.window.active_tab.url.domain))
|
|
|
|
#if self.window.themes.current_theme:
|
|
#self.window.themes.UnloadTheme()
|
|
|
|
#else:
|
|
#self.window.themes.LoadTheme('test')
|
|
|
|
elif name == 'bookmark':
|
|
if not tab.url:
|
|
return
|
|
|
|
self.window['statusbar-bookmark-popover'].grab_focus()
|
|
|
|
with db.session as s:
|
|
self.bookmark_row = s.get_bookmark(tab.url)
|
|
|
|
if not self.bookmark_row:
|
|
self.window['statusbar-bookmark-delete'].set_sensitive(False)
|
|
|
|
return self.bookmark_set_data(
|
|
name = tab.title,
|
|
url = tab.url,
|
|
category = 'Default'
|
|
)
|
|
|
|
self.window['statusbar-bookmark-delete'].set_sensitive(True)
|
|
self.bookmark_set_data(
|
|
name = self.bookmark_row.name,
|
|
url = self.bookmark_row.url,
|
|
category = self.bookmark_row.category,
|
|
description = self.bookmark_row.description
|
|
)
|
|
|
|
elif name == 'siteoptions':
|
|
if not self.window['statusbar-siteoptions'].get_active() or not tab.url.hostname():
|
|
return
|
|
|
|
with db.session as s:
|
|
row = s.get_permission(tab.url.hostname())
|
|
|
|
self.window['statusbar-siteoptions-domain'].set_text(tab.url.hostname())
|
|
self.window['statusbar-siteoptions-reset'].set_sensitive(True if row != None else False)
|
|
self.siteoptions_row = row
|
|
|
|
with SignalBlock(self.siteoptions_handler_ids):
|
|
for k, v in default_permissions.items():
|
|
value = row.get(k, v)
|
|
self.window[f'statusbar-siteoptions-{k}'].set_state(value)
|
|
|
|
self.window['statusbar-siteoptions-reset'].set_sensitive(row and row.id != None)
|
|
|
|
self.window['statusbar-siteoptions-reset'].grab_focus()
|
|
|
|
elif name == 'logins':
|
|
self.window['statusbar-logins-saved-list'].grab_focus()
|
|
self.handle_logins_refresh()
|
|
|
|
elif name == 'toot':
|
|
if not self.toot_set_account():
|
|
return self.window['statusbar-toot-popover'].popdown()
|
|
|
|
self.toot_max_len = self.toot_account.toot_limit
|
|
self.toot_update_count()
|
|
self.toot_set_reply(self.toot_post)
|
|
|
|
self.window['statusbar-toot-content'].grab_focus()
|
|
|
|
|
|
def handle_bookmark_button(self, name):
|
|
with db.session as s:
|
|
if name == 'save':
|
|
data = self.bookmark_get_data()
|
|
|
|
if self.bookmark_row:
|
|
s.update_row(self.bookmark_row, **data)
|
|
|
|
else:
|
|
s.put_bookmark(**data)
|
|
|
|
elif name == 'delete':
|
|
if self.bookmark_row:
|
|
s.remove_row(self.bookmark_row)
|
|
|
|
self.window['statusbar-bookmark-popover'].popdown()
|
|
|
|
|
|
def handle_fedi_button(self, name):
|
|
post = self.window.active_tab.fedi_post
|
|
|
|
if not post or not self.toot_set_account():
|
|
return
|
|
|
|
domain, token = self.toot_account.domain, self.toot_account.token
|
|
|
|
if name == 'reply':
|
|
#self.toot_set_reply(post)
|
|
self.toot_post = post
|
|
self.window['statusbar-toot'].activate()
|
|
|
|
elif name == 'favorite':
|
|
if post.favourited == True:
|
|
if fediverse.UnFavorite(domain, token, post.id):
|
|
post.favourited = False
|
|
self.window.notification('Unfavorited post')
|
|
|
|
else:
|
|
self.window.notification('Failed to unfavorite post', 'error')
|
|
|
|
else:
|
|
if fediverse.Favorite(domain, token, post.id):
|
|
post.favourited = True
|
|
self.window.notification('Favorited post')
|
|
|
|
else:
|
|
self.window.notification('Failed to favorite post', 'error')
|
|
|
|
elif name == 'boost':
|
|
if post.reblogged == True:
|
|
if fediverse.UnBoost(domain, token, post.id):
|
|
post.reblogged = False
|
|
self.window.notification('Unboosted post')
|
|
|
|
else:
|
|
self.window.notification('Failed to unboost post', 'error')
|
|
|
|
else:
|
|
if fediverse.Boost(domain, token, post.id):
|
|
post.reblogged = True
|
|
self.window.notification('Boosted post')
|
|
|
|
else:
|
|
self.window.notification('Failed to boost post', 'error')
|
|
|
|
fediverse.cache.post.store(self.window.active_tab.url, post)
|
|
|
|
|
|
def handle_siteoptions_switch(self, name, switch):
|
|
tab = self.window.active_tab
|
|
|
|
if not tab.webview:
|
|
return
|
|
|
|
with db.session as s:
|
|
s.put_permission(tab.url.domain, name, switch.get_active())
|
|
|
|
self.window['statusbar-siteoptions-reset'].set_sensitive(True)
|
|
|
|
|
|
def handle_siteoptions_button(self, name):
|
|
if name == 'reset':
|
|
domain = self.window.active_tab.url.domain
|
|
|
|
with db.session as s:
|
|
s.del_permission(domain)
|
|
|
|
self.handle_status_button('siteoptions')
|
|
|
|
elif name == 'close':
|
|
self.window['statusbar-siteoptions-popover'].popdown()
|
|
|
|
|
|
def handle_logins_button(self, name):
|
|
if name == 'clear':
|
|
for widget in self.window['statusbar-logins-unsaved-list']:
|
|
widget.handle_cancel()
|
|
|
|
self.window['statusbar-logins-popover'].popdown()
|
|
|
|
|
|
def handle_logins_refresh(self):
|
|
login_list = self.window['statusbar-logins-saved-list']
|
|
|
|
for child in login_list.get_children():
|
|
child.destroy()
|
|
|
|
for row in passdb.fetch(domain=self.window.active_tab.url.hostname()):
|
|
login_list.add(SavedLoginRow(row, self.window.active_tab.url)['container'])
|
|
|
|
|
|
def handle_toot_key_press(self, textview, event, *args):
|
|
keyname = Gdk.keyval_name(event.keyval)
|
|
|
|
if keyname.lower() == 'return' and event.state == Gdk.ModifierType.CONTROL_MASK:
|
|
self.toot_send()
|
|
return True
|
|
|
|
|
|
def handle_toot_spoiler_activate(self, *args):
|
|
self.window['statusbar-toot-content'].grab_focus()
|
|
|
|
|
|
def setup(self):
|
|
self.bookmark_fields = DotDict(
|
|
name = self.window['statusbar-bookmark-title'],
|
|
url = self.window['statusbar-bookmark-url'],
|
|
category = self.window['statusbar-bookmark-category'],
|
|
description = self.window['statusbar-bookmark-description']
|
|
)
|
|
|
|
self.toot_fields = DotDict(
|
|
reply = self.window['statusbar-toot-reply'],
|
|
spoiler = self.window['statusbar-toot-spoiler'],
|
|
content = self.window['statusbar-toot-content'],
|
|
visibility = self.window['statusbar-toot-visibility'],
|
|
count = self.window['statusbar-toot-count']
|
|
)
|
|
|
|
self.logins = DotDict(
|
|
unsaved = self.window['statusbar-logins-unsaved-list'],
|
|
saved = self.window['statusbar-logins-saved-list']
|
|
)
|
|
|
|
signals = {
|
|
'bookmark': [
|
|
{'signal': 'toggled', 'callback': self.handle_status_button}
|
|
],
|
|
'bookmark-save': [
|
|
{'signal': 'clicked', 'callback': self.handle_bookmark_button}
|
|
],
|
|
'bookmark-delete': [
|
|
{'signal': 'clicked', 'callback': self.handle_bookmark_button}
|
|
],
|
|
'bookmark-close': [
|
|
{'signal': 'clicked', 'callback': self.handle_bookmark_button}
|
|
],
|
|
'favorite': [
|
|
{'signal': 'clicked', 'callback': self.handle_fedi_button}
|
|
],
|
|
'boost': [
|
|
{'signal': 'clicked', 'callback': self.handle_fedi_button}
|
|
],
|
|
'reply': [
|
|
{'signal': 'clicked', 'callback': self.handle_fedi_button}
|
|
],
|
|
'debug': [
|
|
{'signal': 'clicked', 'callback': self.handle_status_button}
|
|
],
|
|
'toot': [
|
|
{'signal': 'toggled', 'callback': self.handle_status_button}
|
|
],
|
|
'siteoptions': [
|
|
{'signal': 'toggled', 'callback': self.handle_status_button}
|
|
],
|
|
'logins': [
|
|
{'signal': 'toggled', 'callback': self.handle_status_button}
|
|
],
|
|
'logins-close': [
|
|
{'signal': 'clicked', 'callback': self.handle_logins_button}
|
|
],
|
|
'logins-unsaved-clear': [
|
|
{'signal': 'clicked', 'callback': self.handle_logins_button}
|
|
],
|
|
'siteoptions-reset': [
|
|
{'signal': 'clicked', 'callback': self.handle_siteoptions_button}
|
|
],
|
|
'siteoptions-close': [
|
|
{'signal': 'clicked', 'callback': self.handle_siteoptions_button}
|
|
],
|
|
'toot-spoiler': [
|
|
{'signal': 'changed', 'callback': self.toot_update_count},
|
|
{'signal': 'activate', 'callback': self.handle_toot_spoiler_activate}
|
|
],
|
|
'toot-reset': [
|
|
{'signal': 'clicked', 'callback': self.toot_clear}
|
|
],
|
|
'toot-send': [
|
|
{'signal': 'clicked', 'callback': self.toot_send}
|
|
],
|
|
'toot-close': [
|
|
{'signal': 'clicked', 'callback': self.toot_close}
|
|
],
|
|
'toot-content': [
|
|
{'signal': 'key-press-event', 'callback': self.handle_toot_key_press, 'kwargs': {'original_args': True}}
|
|
]
|
|
}
|
|
|
|
for name, sigs in signals.items():
|
|
for sig in sigs:
|
|
full_name = f'statusbar-{name}'
|
|
short_name = name.split('-')[-1]
|
|
self.window.Connect(full_name, sig['signal'], sig['callback'], short_name, *sig.get('args', []), **sig.get('kwargs', {}))
|
|
|
|
connect(self.window['statusbar-toot-content'].get_buffer(), 'changed', self.toot_update_count)
|
|
|
|
# extra work needs to be done to toggle webview settings
|
|
self.permissions = DotDict({
|
|
'instance': False,
|
|
'adblock': True,
|
|
'fullscreen': True,
|
|
'autoplay': False,
|
|
'dialog': True,
|
|
'notification': False,
|
|
'microphone': False,
|
|
'location': False,
|
|
'camera': False,
|
|
#'javascript': True,
|
|
#'images': True,
|
|
#'autoplay': False,
|
|
#'insecure': False
|
|
})
|
|
|
|
for name in self.permissions:
|
|
widget = self.window[f'statusbar-siteoptions-{name}']
|
|
sigid = self.window.Connect(f'statusbar-siteoptions-{name}', 'state-set', self.handle_siteoptions_switch, name, widget)
|
|
self.siteoptions_handler_ids.append([sigid, widget])
|