Port to GTK4 (#310)

This commit is contained in:
Bleak Grey 2021-07-23 14:41:03 +03:00 committed by GitHub
parent dc15fd4112
commit cb7a17963c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
161 changed files with 6159 additions and 5347 deletions

0
.buildconfig Normal file → Executable file
View File

0
.github/FUNDING.yml vendored Normal file → Executable file
View File

0
.github/ISSUE_TEMPLATE/bug-report.md vendored Normal file → Executable file
View File

0
.github/workflows/build.yml vendored Normal file → Executable file
View File

0
.gitignore vendored Normal file → Executable file
View File

0
LICENSE Normal file → Executable file
View File

7
README.md Normal file → Executable file
View File

@ -22,9 +22,9 @@ Simple [Mastodon](https://github.com/tootsuite/mastodon) client for Linux
libxml2-dev | 2.9.10 |
libgee-0.8-dev | 0.8.5 |
libsoup2.4-dev | 2.64 |
libgtk-3-dev | 3.22 |
libhandy-1.0-dev | 1.0.0 | Will be attempted to install automatically if not present.
libsecret-1-dev | 0.20 | Optional. Used for storing accounts using Secret Service API.
libgtk-4-dev | 4.3.0 |
libadwaita-1.0-dev | 1.0.0-alpha2 | Will be attempted to install automatically if not present.
libsecret-1-dev | 0.20 |
2. Run `install.sh` in the project directory. The app will launch automatically on success.
@ -43,4 +43,3 @@ You can always help by reporting bugs, submitting pull requests, and suggesting
* German translation by [@koyuawsmbrtn](https://github.com/koyuawsmbrtn)
* Spanish translation by [@oscfdezdz](https://github.com/oscfdezdz)
* Norwegian (Bokmål) translation by [@Octolinger](https://github.com/Octolinger)

105
com.github.bleakgrey.tootle.json Normal file → Executable file
View File

@ -1,57 +1,60 @@
{
"app-id": "com.github.bleakgrey.tootle",
"runtime": "org.gnome.Platform",
"sdk": "org.gnome.Sdk",
"runtime-version": "3.38",
"command": "com.github.bleakgrey.tootle",
"finish-args": [
"--share=network",
"--share=ipc",
"--socket=fallback-x11",
"--socket=wayland",
"--filesystem=xdg-run/dconf",
"--filesystem=~/.config/dconf:ro",
"--talk-name=ca.desrt.dconf",
"--env=DCONF_USER_CONFIG_DIR=.config/dconf"
],
"cleanup": [
"/include",
"/lib/pkgconfig",
"/man",
"/share/doc",
"/share/gtk-doc",
"/share/man",
"/share/pkgconfig",
"*.la",
"*.a"
],
"modules": [
{
"name": "libhandy",
"buildsystem": "meson",
"config-opts": [
"-Dtests=false",
"-Dexamples=false",
"-Dglade_catalog=disabled"
],
"sources": [
"app-id" : "com.github.bleakgrey.tootle",
"runtime" : "org.gnome.Platform",
"sdk" : "org.gnome.Sdk",
"runtime-version" : "40",
"command" : "com.github.bleakgrey.tootle",
"finish-args" : [
"--share=network",
"--share=ipc",
"--socket=fallback-x11",
"--socket=wayland",
"--filesystem=xdg-run/dconf",
"--filesystem=~/.config/dconf:ro",
"--talk-name=ca.desrt.dconf",
"--env=DCONF_USER_CONFIG_DIR=.config/dconf"
],
"cleanup" : [
"/include",
"/lib/pkgconfig",
"/man",
"/share/doc",
"/share/gtk-doc",
"/share/man",
"/share/pkgconfig",
"*.la",
"*.a"
],
"modules" : [
{
"type": "archive",
"url": "https://ftp.acc.umu.se/pub/GNOME/sources/libhandy/1.0/libhandy-1.0.3.tar.xz",
"sha256": "559bb3acc2c362488917eb72ed25bdc181f4ae26ac94d177634cc5d34c867f7a"
}
]
},
{
"name": "tootle",
"builddir": true,
"buildsystem": "meson",
"sources": [
"name" : "libadwaita",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"-Dexamples=false",
"-Dtests=false"
],
"sources" : [
{
"type" : "archive",
"url" : "https://gitlab.gnome.org/GNOME/libadwaita/-/archive/594eb987c57e4d20370cc20520871f230ff02ae2/libadwaita-594eb987c57e4d20370cc20520871f230ff02ae2.tar",
"sha256" : "960d8e95864cac71be9e893d37baace82d67ecb06b3b09bd24b9fdfece9eca9c"
}
]
},
{
"type": "dir",
"path": "."
"name" : "tootle",
"builddir" : true,
"buildsystem" : "meson",
"sources" : [
{
"type" : "dir",
"path" : "."
}
]
}
]
],
"build-options" : {
"env" : { }
}
]
}

105
data/app.css Normal file → Executable file
View File

@ -1,53 +1,43 @@
.header .chip {
padding: 4px 12px;
border-radius: 4px;
border: 1px solid black;
.sidebar .badge {
padding: 2px 12px;
border-radius: 999px;
background: @accent_bg_color;
color: @text_view_bg;
}
.attachment {
border-radius: 5px;
background: rgba (150, 150, 150, 0.2);
/* .header .chip { */
/* padding: 4px 12px; */
/* border-radius: 4px; */
/* border: 1px solid black; */
/* } */
.attachment, .attachment button, flowboxchild {
padding:0px;
margin:0px;
}
.attachment .pic {
border-radius: 5px;
}
.attachment .chip {
padding: 6px;
border-radius:6px;
.attachment .osd {
padding: 6px 12px;
border-radius: 6px;
margin: 8px;
}
.ttl-header-button {
margin: 0px;
border-radius: 0px;
border-top: none;
border-bottom: none;
}
.ttl-header-button .title, .ttl-header-button .subtitle {
padding-left: 0px;
padding-right: 0px;
}
.padded.ttl-view {
margin: 32px 0 32px 0;
}
.ttl-view:not(.padded) .content row {
border-radius: 0px;
}
.ttl-action-bar .circular {
box-shadow: none;
}
/* .ttl-header-button { */
/* margin: 0px; */
/* border-radius: 0px; */
/* border-top: none; */
/* border-bottom: none; */
/* } */
/* .ttl-header-button .title, .ttl-header-button .subtitle { */
/* padding-left: 0px; */
/* padding-right: 0px; */
/* } */
.ttl-flat-button {
padding: 0px;
margin: 0px;
}
.ttl-post {
padding: 0px;
}
.ttl-thread-line {
background: @theme_fg_color;
opacity: .1;
@ -55,9 +45,9 @@
margin-bottom: -8px;
}
.ttl-large-body {
font-size: 110%;
}
/* .ttl-large-body { */
/* font-size: 110%; */
/* } */
.ttl-code {
font-family: monospace;
@ -65,3 +55,38 @@
background: rgba(150,150,150,.1);
border-radius: 6px;
}
.ttl-view .small .content row {
border-left: none;
border-right: none;
border-radius:0px;
}
.ttl-view .content row {
padding: 0px;
}
.ttl-view .large:first-child {
margin-top: 32px;
}
.ttl-view .large:last-child {
margin-bottom: 32px;
}
/*
Profile
*/
.ttl-profile-cover .header-image {
background:grey;
}
.ttl-profile-cover avatar {
border: 6px solid @theme_base_color;
background: @theme_base_color;
}
.large .header-image {
border-radius:6px 6px 0 0;
}

0
data/com.github.bleakgrey.tootle.appdata.xml.in Normal file → Executable file
View File

0
data/com.github.bleakgrey.tootle.desktop.in Normal file → Executable file
View File

10
data/com.github.bleakgrey.tootle.gschema.xml Normal file → Executable file
View File

@ -1,13 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<schemalist>
<enum id='com.github.bleakgrey.tootle.API.Visibility'>
<value nick='public' value='0'/>
<value nick='unlisted' value='1'/>
<value nick='private' value='2'/>
<value nick='direct' value='3'/>
</enum>
<schema path="/com/github/bleakgrey/tootle/" id="com.github.bleakgrey.tootle" gettext-domain="com.github.bleakgrey.tootle">
<key name="active-account" type="s">
@ -22,9 +15,6 @@
<key name="work-in-background" type="b">
<default>false</default>
</key>
<key name="default-post-visibility" enum="com.github.bleakgrey.tootle.API.Visibility">
<default>'public'</default>
</key>
<key name="timeline-page-size" type="i">
<default>12</default>
</key>

19
data/gresource.xml Normal file → Executable file
View File

@ -2,24 +2,37 @@
<gresources>
<gresource prefix="/com/github/bleakgrey/tootle/">
<file alias="app.css">app.css</file>
<file preprocess="xml-stripblanks">icons/scalable/actions/mention-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/actions/hashtag-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/actions/globe-symbolic.svg</file>
<file preprocess="xml-stripblanks">icons/scalable/actions/bell-symbolic.svg</file>
<file>gtk/help-overlay.ui</file>
<file>gtk/dropdown/icon.ui</file>
<file>gtk/dropdown/full.ui</file>
<file>ui/views/new_account.ui</file>
<file>ui/views/base.ui</file>
<file>ui/views/profile_header.ui</file>
<file>ui/views/sidebar/view.ui</file>
<file>ui/views/sidebar/account.ui</file>
<file>ui/views/sidebar/item.ui</file>
<file>ui/widgets/status.ui</file>
<file>ui/widgets/accounts_button.ui</file>
<file>ui/widgets/accounts_button_item.ui</file>
<file>ui/widgets/profile_field_row.ui</file>
<file>ui/widgets/timeline_menu.ui</file>
<file>ui/widgets/list_item.ui</file>
<file>ui/widgets/list_editor_item.ui</file>
<file>ui/widgets/attachment_slot.ui</file>
<file>ui/widgets/compose_attachment.ui</file>
<file>ui/widgets/adaptive_button.ui</file>
<file>ui/dialogs/new_account.ui</file>
<file>ui/dialogs/compose.ui</file>
<file>ui/dialogs/main.ui</file>
<file>ui/dialogs/preferences.ui</file>
<file>ui/dialogs/list_editor.ui</file>
<file>ui/menus.ui</file>
</gresource>
</gresources>

63
data/gtk/dropdown/full.ui Normal file
View File

@ -0,0 +1,63 @@
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkBox">
<property name="orientation">horizontal</property>
<property name="spacing">6</property>
<child>
<object class="GtkImage">
<property name="margin-start">6</property>
<property name="margin-end">6</property>
<property name="margin-top">6</property>
<property name="margin-bottom">6</property>
<binding name="icon_name">
<lookup name="icon_name" type="TootleInstanceAccountVisibility">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel">
<property name="xalign">0</property>
<binding name="label">
<lookup name="name" type="TootleInstanceAccountVisibility">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="xalign">0</property>
<binding name="label">
<lookup name="description" type="TootleInstanceAccountVisibility">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
<style>
<class name="caption"/>
<class name="dim-label"/>
</style>
</object>
</child>
</object>
</child>
</object>
</property>
</template>
</interface>

45
data/gtk/dropdown/icon.ui Normal file
View File

@ -0,0 +1,45 @@
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkImage">
<binding name="icon_name">
<lookup name="icon_name" type="TootleInstanceAccountVisibility">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
<!-- <object class="GtkLabel"> -->
<!-- <property name="xalign">0</property> -->
<!-- <binding name="label"> -->
<!-- <lookup name="name" type="TootleInstanceAccountVisibility"> -->
<!-- <lookup name="item">GtkListItem</lookup> -->
<!-- </lookup> -->
<!-- </binding> -->
<!-- </object> -->
<!-- <object class="GtkBox"> -->
<!-- <property name="orientation">horizontal</property> -->
<!-- </object> -->
<!-- <object class="GtkTreeExpander" id="expander"> -->
<!-- <binding name="list-row"> -->
<!-- <lookup name="item">GtkListItem</lookup> -->
<!-- </binding> -->
<!-- <property name="child"> -->
<!-- <object class="GtkLabel"> -->
<!-- <property name="xalign">0</property> -->
<!-- <binding name="label"> -->
<!-- <lookup name="schema" type="GSettings"> -->
<!-- <lookup name="item">expander</lookup> -->
<!-- </lookup> -->
<!-- </binding> -->
<!-- </object> -->
<!-- </property> -->
<!-- </object> -->
</property>
</template>
</interface>

56
data/gtk/help-overlay.ui Normal file
View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkShortcutsWindow" id="help_overlay">
<property name="modal">1</property>
<child>
<object class="GtkShortcutsSection">
<property name="section-name">application</property>
<child>
<object class="GtkShortcutsGroup">
<property name="title" translatable="yes">Touch gestures</property>
<child>
<object class="GtkShortcutsShortcut">
<property name="accelerator">&lt;ctrl&gt;R</property>
<property name="title" translatable="yes">Refresh column</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="accelerator">&lt;ctrl&gt;T</property>
<property name="title" translatable="yes">Compose a post</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkShortcutsSection">
<property name="section-name">shortcuts</property>
<!-- <property name="max-height">12</property> -->
<child>
<object class="GtkShortcutsGroup">
<property name="title" translatable="yes">Touch gestures</property>
<!-- <child> -->
<!-- <object class="GtkShortcutsShortcut"> -->
<!-- <property name="shortcut-type">gesture-two-finger-swipe-right</property> -->
<!-- <property name="title" translatable="yes">Switch to the next document</property> -->
<!-- </object> -->
<!-- </child> -->
<child>
<object class="GtkShortcutsShortcut">
<property name="shortcut-type">gesture-two-finger-swipe-left</property>
<property name="title" translatable="yes">Previous column</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>

0
data/icons/color-nightly.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 80 KiB

0
data/icons/color.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View File

@ -0,0 +1,157 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<filter id="a" height="100%" width="100%" x="0%" y="0%">
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
</filter>
<mask id="b">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.3"/>
</g>
</mask>
<clipPath id="c">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<mask id="d">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.05"/>
</g>
</mask>
<clipPath id="e">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<mask id="f">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.05"/>
</g>
</mask>
<clipPath id="g">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<mask id="h">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.05"/>
</g>
</mask>
<clipPath id="i">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<mask id="j">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.05"/>
</g>
</mask>
<clipPath id="k">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<mask id="l">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.05"/>
</g>
</mask>
<clipPath id="m">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<mask id="n">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.05"/>
</g>
</mask>
<clipPath id="o">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<mask id="p">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.3"/>
</g>
</mask>
<clipPath id="q">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<mask id="r">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.5"/>
</g>
</mask>
<clipPath id="s">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<mask id="t">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.4"/>
</g>
</mask>
<clipPath id="u">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<mask id="v">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.4"/>
</g>
</mask>
<clipPath id="w">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<mask id="x">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.5"/>
</g>
</mask>
<clipPath id="y">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<mask id="z">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.5"/>
</g>
</mask>
<clipPath id="A">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<g clip-path="url(#c)" mask="url(#b)" transform="matrix(1 0 0 1 -620 -222)">
<path d="m 562.460938 212.058594 h 10.449218 c -1.183594 0.492187 -1.296875 2.460937 0 3 h -10.449218 z m 0 0" fill="#2e3436"/>
</g>
<path d="m -8 -20 v 3 l -3 2.5 v 1 l 3 2.5 v 3" fill="none" stroke="#2e3436" stroke-width="2"/>
<g fill="#2e3436">
<path d="m 13 6.5 c 0 2.761719 -2.238281 5 -5 5 s -5 -2.238281 -5 -5 s 2.238281 -5 5 -5 s 5 2.238281 5 5 z m 0 0"/>
<path d="m 3 6.5 h 10 v 6 h -10 z m 0 0"/>
<path d="m 2.5 13 h 11 c 0.550781 0 1 -0.449219 1 -1 s -0.449219 -1 -1 -1 h -11 c -0.550781 0 -1 0.449219 -1 1 s 0.449219 1 1 1 z m 0 0"/>
<path d="m 10 14 c 0 0.714844 -0.382812 1.375 -1 1.730469 c -0.617188 0.359375 -1.382812 0.359375 -2 0 c -0.617188 -0.355469 -1 -1.015625 -1 -1.730469"/>
<path d="m 9.5 1.5 c 0 0.828125 -0.671875 1.5 -1.5 1.5 s -1.5 -0.671875 -1.5 -1.5 s 0.671875 -1.5 1.5 -1.5 s 1.5 0.671875 1.5 1.5 z m 0 0"/>
</g>
<g clip-path="url(#e)" mask="url(#d)" transform="matrix(1 0 0 1 -620 -222)">
<path d="m 16 632 h 1 v 1 h -1 z m 0 0" fill="#2e3436" fill-rule="evenodd"/>
</g>
<g clip-path="url(#g)" mask="url(#f)" transform="matrix(1 0 0 1 -620 -222)">
<path d="m 17 631 h 1 v 1 h -1 z m 0 0" fill="#2e3436" fill-rule="evenodd"/>
</g>
<g clip-path="url(#i)" mask="url(#h)" transform="matrix(1 0 0 1 -620 -222)">
<path d="m 18 634 h 1 v 1 h -1 z m 0 0" fill="#2e3436" fill-rule="evenodd"/>
</g>
<g clip-path="url(#k)" mask="url(#j)" transform="matrix(1 0 0 1 -620 -222)">
<path d="m 16 634 h 1 v 1 h -1 z m 0 0" fill="#2e3436" fill-rule="evenodd"/>
</g>
<g clip-path="url(#m)" mask="url(#l)" transform="matrix(1 0 0 1 -620 -222)">
<path d="m 17 635 h 1 v 1 h -1 z m 0 0" fill="#2e3436" fill-rule="evenodd"/>
</g>
<g clip-path="url(#o)" mask="url(#n)" transform="matrix(1 0 0 1 -620 -222)">
<path d="m 19 635 h 1 v 1 h -1 z m 0 0" fill="#2e3436" fill-rule="evenodd"/>
</g>
<g clip-path="url(#q)" mask="url(#p)" transform="matrix(1 0 0 1 -620 -222)">
<path d="m 136 660 v 7 h 7 v -7 z m 0 0" fill="#2e3436"/>
</g>
<g clip-path="url(#s)" mask="url(#r)" transform="matrix(1 0 0 1 -620 -222)">
<path d="m 199 642 h 3 v 12 h -3 z m 0 0" fill="#2e3436"/>
</g>
<g clip-path="url(#u)" mask="url(#t)" transform="matrix(1 0 0 1 -620 -222)">
<path d="m 209.5 144.160156 c 0.277344 0 0.5 0.222656 0.5 0.5 v 1 c 0 0.277344 -0.222656 0.5 -0.5 0.5 s -0.5 -0.222656 -0.5 -0.5 v -1 c 0 -0.277344 0.222656 -0.5 0.5 -0.5 z m 0 0" fill="#2e3436"/>
</g>
<g clip-path="url(#w)" mask="url(#v)" transform="matrix(1 0 0 1 -620 -222)">
<path d="m 206.5 144.160156 c 0.277344 0 0.5 0.222656 0.5 0.5 v 1 c 0 0.277344 -0.222656 0.5 -0.5 0.5 s -0.5 -0.222656 -0.5 -0.5 v -1 c 0 -0.277344 0.222656 -0.5 0.5 -0.5 z m 0 0" fill="#2e3436"/>
</g>
<g clip-path="url(#y)" mask="url(#x)" transform="matrix(1 0 0 1 -620 -222)">
<path d="m 229.5 143.160156 c -0.546875 0 -1 0.457032 -1 1 c 0 0.546875 0.453125 1 1 1 s 1 -0.453125 1 -1 c 0 -0.542968 -0.453125 -1 -1 -1 z m 0 0" fill="#2e3436"/>
</g>
<g clip-path="url(#A)" mask="url(#z)" transform="matrix(1 0 0 1 -620 -222)">
<path d="m 226.453125 143.160156 c -0.519531 0 -0.953125 0.433594 -0.953125 0.953125 v 0.09375 c 0 0.519531 0.433594 0.953125 0.953125 0.953125 h 0.09375 c 0.519531 0 0.953125 -0.433594 0.953125 -0.953125 v -0.09375 c 0 -0.519531 -0.433594 -0.953125 -0.953125 -0.953125 z m 0 0" fill="#2e3436"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -0,0 +1,403 @@
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<svg xmlns:cc='http://creativecommons.org/ns#' xmlns:dc='http://purl.org/dc/elements/1.1/' sodipodi:docname='globe-symbolic.svg' height='16.004578' id='svg7384' xmlns:inkscape='http://www.inkscape.org/namespaces/inkscape' xmlns:osb='http://www.openswatchbook.org/uri/2009/osb' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:sodipodi='http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd' xmlns:svg='http://www.w3.org/2000/svg' version='1.1' inkscape:version='1.0.1 (3bc2e813f5, 2020-09-07)' viewBox='0 0 16 16.004578' width='16' xmlns='http://www.w3.org/2000/svg'>
<metadata id='metadata90'>
<rdf:RDF>
<cc:Work rdf:about=''>
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource='http://purl.org/dc/dcmitype/StillImage'/>
<dc:title>Gnome Symbolic Icon Theme</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview inkscape:bbox-nodes='true' inkscape:bbox-paths='true' bordercolor='#666666' borderopacity='1' inkscape:current-layer='layer13' inkscape:cx='13.946489' inkscape:cy='46.286833' inkscape:document-rotation='0' gridtolerance='10' inkscape:guide-bbox='true' guidetolerance='10' id='namedview88' inkscape:measure-end='0,0' inkscape:measure-start='56,310.597' inkscape:object-nodes='true' inkscape:object-paths='true' objecttolerance='10' pagecolor='#ebebeb' inkscape:pageopacity='1' inkscape:pageshadow='2' showborder='false' showgrid='false' showguides='false' inkscape:snap-bbox='true' inkscape:snap-bbox-edge-midpoints='true' inkscape:snap-bbox-midpoints='true' inkscape:snap-global='true' inkscape:snap-grids='true' inkscape:snap-intersection-paths='true' inkscape:snap-nodes='true' inkscape:snap-others='false' inkscape:snap-to-guides='true' inkscape:window-height='1376' inkscape:window-maximized='0' inkscape:window-width='2560' inkscape:window-x='26' inkscape:window-y='23' inkscape:zoom='16'>
<inkscape:grid empspacing='4' enabled='true' id='grid4866' originx='-679.98255' originy='-40.000001' snapvisiblegridlinesonly='true' spacingx='1px' spacingy='1px' type='xygrid' visible='true'/>
<inkscape:grid dotted='true' empspacing='4' id='grid2980' originx='-679.98255' originy='-40.000001' spacingx='0.5' spacingy='0.5' type='xygrid'/>
</sodipodi:namedview>
<title id='title9167'>Gnome Symbolic Icon Theme</title>
<defs id='defs7386'>
<linearGradient id='linearGradient7212' osb:paint='solid'>
<stop id='stop7214' offset='0' style='stop-color:#000000;stop-opacity:1;'/>
</linearGradient>
<clipPath clipPathUnits='userSpaceOnUse' id='clipPath17189-2-3'>
<circle cx='280' cy='20' id='circle17191-8-6' r='200' style='display:inline;opacity:1;fill:url(#radialGradient17193);fill-opacity:1;stroke:none;stroke-width:0.0403508px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new'/>
</clipPath>
</defs>
<g inkscape:groupmode='layer' id='layer1' inkscape:label='ui' style='display:inline' transform='translate(-679.98255,160)'/>
<g inkscape:groupmode='layer' id='layer21' inkscape:label='legacy' style='display:none' transform='translate(-679.98255,-40)'>
<g id='g5237' inkscape:label='keyboard input' style='display:inline;enable-background:new' transform='rotate(-90,50.499998,658.5)'>
<rect height='16' id='rect5225' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:1;marker:none;enable-background:new' transform='scale(-1,1)' width='16' x='-49' y='588'/>
<rect height='1' id='rect5229' style='color:#000000;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;enable-background:accumulate' width='1' x='42.999996' y='600'/>
<rect height='1' id='rect5231' style='color:#000000;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;enable-background:accumulate' width='1' x='42.999996' y='591'/>
<rect height='2.00001' id='rect5233' rx='1.0000011' ry='1.0000011' style='color:#000000;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;enable-background:accumulate' width='2.0000021' x='42' y='591'/>
<rect height='2.00001' id='rect5235' rx='1.0000011' ry='1.0000011' style='color:#000000;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;enable-background:accumulate' width='2.0000021' x='41.999996' y='599'/>
</g>
<g id='g5252' inkscape:label='test run-tests testing prototype beta pass valid checkbox checkmark check' style='display:inline' transform='translate(-148.05898,202.99682)'>
<rect height='16' id='rect5244' style='color:#bebebe;overflow:visible;opacity:0.514644;fill:none;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;marker:none;enable-background:accumulate' width='16' x='48.116268' y='398'/>
<g id='g5246' style='font-weight:bold;font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell Bold&apos;;letter-spacing:0px;word-spacing:0px;fill:#000000' transform='matrix(0.28893613,0,0,0.28893613,95.491581,418.94283)'/>
</g>
<g id='g5274' inkscape:label='border ui resize margins size' style='display:inline;enable-background:new' transform='translate(-32.000003,-108)'>
<rect height='16' id='rect5260' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;opacity:0.514644;fill:none;stroke:none;stroke-width:3;marker:none;enable-background:accumulate' width='16' x='11.982551' y='668.00458'/>
<path inkscape:connector-curvature='0' d='m 16,676 a 2,2 0 0 0 -2,2 2,2 0 0 0 2,2 2,2 0 0 0 2,-2 2,2 0 0 0 -2,-2 z m 0,1 a 1,1 0 0 1 1,1 1,1 0 0 1 -1,1 1,1 0 0 1 -1,-1 1,1 0 0 1 1,-1 z' id='path5262' style='opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal'/>
<path inkscape:connector-curvature='0' d='m 27,672 v 11 H 17 v -11 z' id='path5264' style='opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:0.35;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal'/>
<path inkscape:connector-curvature='0' d='m 21,669 a 2,2 0 0 0 -2,2 2,2 0 0 0 2,2 2,2 0 0 0 2,-2 2,2 0 0 0 -2,-2 z m 0,1 a 1,1 0 0 1 1,1 1,1 0 0 1 -1,1 1,1 0 0 1 -1,-1 1,1 0 0 1 1,-1 z' id='path5266' style='opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal'/>
</g>
<g id='g5310' inkscape:label='time measure seconds timer' style='display:inline;enable-background:new' transform='translate(-92.000003,-468)'>
<rect height='16' id='rect5298' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;opacity:0.514644;fill:none;stroke:none;stroke-width:3;marker:none;enable-background:accumulate' width='16' x='11.982552' y='668.00458'/>
<path inkscape:connector-curvature='0' d='m 17,680 v 2 h 5 v -2 c -1.5,-1.5 -3.5,-1.5 -5,0 z' id='path5300' sodipodi:nodetypes='ccccc' style='opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none'/>
<path inkscape:connector-curvature='0' d='m 14,671 h 11 c 2,0 2,-2 2,-2 H 12 c 0,0 0,2 2,2 z' id='path5304' sodipodi:nodetypes='ccccc' style='opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none'/>
<path inkscape:connector-curvature='0' d='m 14,681 h 11 c 2,0 2,2 2,2 H 12 c 0,0 0,-2 2,-2 z' id='path5308' sodipodi:nodetypes='ccccc' style='opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none'/>
</g>
<g id='g5324' inkscape:label='time measure seconds timer' style='display:inline' transform='translate(-761.0002,567)'>
<rect height='16' id='rect5314' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;opacity:0.514644;fill:none;stroke:none;stroke-width:3;marker:none;enable-background:accumulate' width='16' x='660.98273' y='-366.99542'/>
<circle cx='726.90594' cy='-219.20323' id='circle5320' r='2' style='opacity:1;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1' transform='matrix(0.70710678,-0.70710678,-0.70710678,-0.70710678,0,0)'/>
</g>
<g id='g5342' inkscape:label='alarm clock morning' style='display:inline' transform='translate(-781.0002,567)'>
<rect height='16' id='rect5328' rx='0.14408804' ry='0.15129246' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:1;marker:none;enable-background:new' width='16' x='741.00018' y='-367'/>
<circle cx='748.50018' cy='-357.5' id='circle5332' r='5.5' style='color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:#2e3436;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate'/>
<path inkscape:connector-curvature='0' d='M 745.1252,-353.09375 744.0002,-352' id='path5334' sodipodi:nodetypes='cc' style='color:#000000;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:#2e3436;stroke-width:2;stroke-linecap:round;stroke-opacity:1;marker:none;enable-background:accumulate'/>
<path inkscape:connector-curvature='0' d='m 752.09395,-353 0.90625,1' id='path5336' sodipodi:nodetypes='cc' style='color:#000000;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:#2e3436;stroke-width:2;stroke-linecap:round;stroke-opacity:1;marker:none;enable-background:accumulate'/>
<path inkscape:connector-curvature='0' d='m 743.11127,-365.57867 a 2.5,2.5 0 0 0 -0.68975,3.4676 l 4.15735,-2.77785 a 2.5,2.5 0 0 0 -3.4676,-0.68975 z' id='path5338' style='opacity:1;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1'/>
<path inkscape:connector-curvature='0' d='m 753.88912,-365.57867 a 2.5,2.5 0 0 1 0.68975,3.4676 l -4.15735,-2.77785 a 2.5,2.5 0 0 1 3.4676,-0.68975 z' id='path5340' style='opacity:1;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1'/>
</g>
<g id='g5390' inkscape:label='ancient scroll roll papyrus' style='display:inline' transform='translate(-1001.0002,567)'>
<rect height='16' id='rect5388' style='color:#bebebe;overflow:visible;fill:none;stroke:none;stroke-width:2;marker:none' transform='matrix(0,-1,-1,0,0,0)' width='16' x='350.99234' y='-797.00018'/>
</g>
<g id='g5410' inkscape:label='ancient scroll roll papyrus' style='display:inline' transform='translate(-961.0002,567)'>
<circle cx='813.9931' cy='362.99991' id='circle5394' r='2' style='opacity:1;fill:none;fill-opacity:1;stroke:#2e3436;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;enable-background:new' transform='scale(1,-1)'/>
<rect height='16' id='rect5404' style='color:#bebebe;overflow:visible;fill:none;stroke:none;stroke-width:2;marker:none' transform='matrix(0,-1,-1,0,0,0)' width='16' x='350.99234' y='-817.00018'/>
</g>
<g id='g5436' inkscape:label='ancient scroll roll papyrus' style='display:inline' transform='translate(-1021.0002,567)'>
<rect height='16' id='rect5434' style='color:#bebebe;overflow:visible;fill:none;stroke:none;stroke-width:2;marker:none' transform='matrix(0,-1,-1,0,0,0)' width='16' x='350.99234' y='-777.00018'/>
</g>
<g id='g5462' inkscape:label='ancient scroll roll papyrus' style='display:inline' transform='translate(-1021.0002,567)'>
<circle cx='-354.99991' cy='833.99298' id='circle5448' r='2' style='opacity:1;fill:none;fill-opacity:1;stroke:#2e3436;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;enable-background:new' transform='matrix(0,1,1,0,0,0)'/>
<rect height='16' id='rect5458' style='color:#bebebe;overflow:visible;fill:none;stroke:none;stroke-width:2;marker:none' transform='matrix(0,-1,-1,0,0,0)' width='16' x='350.99234' y='-837.00018'/>
</g>
<g id='g5482' inkscape:label='ancient scroll roll papyrus' style='display:inline' transform='translate(-1021.0002,567)'>
<circle cx='-353.99939' cy='853.00775' id='circle5466' r='2' style='opacity:1;fill:none;fill-opacity:1;stroke:#2e3436;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;enable-background:new' transform='matrix(0,1,1,0,0,0)'/>
<rect height='16' id='rect5476' style='color:#bebebe;overflow:visible;fill:none;stroke:none;stroke-width:2;marker:none' transform='scale(1,-1)' width='16' x='841.00018' y='350.99231'/>
</g>
<g id='g5508' inkscape:label='ancient scroll roll papyrus' style='display:inline' transform='rotate(90,-14.999922,-575.99244)'>
<rect height='16' id='rect5506' style='color:#bebebe;overflow:visible;fill:none;stroke:none;stroke-width:2;marker:none' transform='matrix(0,-1,-1,0,0,0)' width='16' x='350.99234' y='-777.00018'/>
</g>
<g id='g5212' inkscape:label='podcast radio broadcast' transform='translate(-500,40)'>
<rect height='16' id='rect5202' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:1;marker:none' width='16' x='479.98264' y='720'/>
<path inkscape:connector-curvature='0' d='m 487.42857,731.00705 h 1.14285 c 1.89944,0 3.42858,1.52914 3.42858,3.42857 v 0.80321 C 492,736.00074 491.23883,736 491.23883,736 h -6.47766 c 0,0 -0.76118,7.4e-4 -0.76117,-0.76117 v -0.80321 c 0,-1.89943 1.52914,-3.42857 3.42857,-3.42857 z' id='path5204' sodipodi:nodetypes='sssscccss' style='color:#bebebe;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate'/>
<path inkscape:connector-curvature='0' d='m 488,726 c 1.10457,0 2,0.89543 2,2 0,1.10457 -0.89542,2 -2,2 -1.10456,0 -2,-0.89543 -2,-2 0,-1.10457 0.89543,-2 2,-2 z' id='path5208' sodipodi:nodetypes='sssss' style='color:#bebebe;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate'/>
</g>
<g id='g5632' inkscape:label='point-of-interest gas station diesel pump' style='display:inline' transform='translate(-180.00001,-138)'>
<path inkscape:connector-curvature='0' d='m -148.65625,-39.59375 -0.6875,0.71875 2.4375,2.40625 v 2.5625 0.21875 l 0.15625,0.125 0.78125,0.78125 -0.0312,4.308057 c 0,0.962454 -0.30794,1.505255 -0.9949,1.505255 -0.61105,0 -1.00515,-0.479735 -1.00515,-1.479636 l 0.004,-2.083676 c 0,-0.903868 -0.57343,-1.46875 -1.55441,-1.46875 h -1.01167 v 1 h 0.98042 c 0.32421,0 0.58566,0.252678 0.58566,0.46875 v 2.083676 c 0,1.66609 0.9908,2.463063 1.996,2.463063 1.28725,0 2,-0.805782 2.00042,-2.463063 l 0.0625,-7.271176 v -0.21875 l -0.15625,-0.15625 z' id='path5626' sodipodi:nodetypes='ccccccccsccccccccsccccc' style='color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:1px;marker:none;enable-background:accumulate' transform='translate(180,218)'/>
<rect height='16' id='rect5628' inkscape:label='audio-volume-high' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:1;marker:none' transform='rotate(-90)' width='16' x='-194' y='20'/>
<path inkscape:connector-curvature='0' d='m -157,-39 c -1.108,0 -2,0.892001 -2,2 v 11 c -0.554,0 -1,0.446 -1,1 h 11 c 0,-0.554 -0.446,-1 -1,-1 v -11 c 0,-1.107999 -0.892,-2 -2,-2 z m 0.99437,1.972272 h 3.01126 c 0.554,0 1,0.446001 1,1 v 2 c 0,0.553999 -0.446,1 -1,1 h -3.01126 c -0.554,0 -1,-0.446001 -1,-1 v -2 c 0,-0.553999 0.446,-1 1,-1 z' id='path5630' sodipodi:nodetypes='ssccccssssssssssss' style='color:#000000;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;enable-background:accumulate' transform='translate(180,218)'/>
</g>
<g id='g5646' inkscape:label='sitting park bench wood' style='display:inline' transform='translate(-140,-138)'>
<rect height='16' id='rect5636' inkscape:label='audio-volume-high' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:1;marker:none' transform='rotate(-90)' width='16' x='-194' y='20'/>
<rect height='2' id='rect5638' rx='0' ry='0' style='color:#000000;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;enable-background:accumulate' width='14.000002' x='21' y='187'/>
<rect height='4' id='rect5640' rx='0' ry='0' style='color:#000000;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;enable-background:accumulate' width='14.000002' x='21' y='182'/>
<rect height='12' id='rect5642' rx='0' ry='0' style='color:#000000;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;enable-background:accumulate' width='2' x='22' y='181'/>
<rect height='12' id='rect5644' rx='0' ry='0' style='color:#000000;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;enable-background:accumulate' width='2.0000017' x='32' y='181'/>
</g>
<g id='g5660' inkscape:label='point-of-interest education university hat school' style='display:inline' transform='translate(-100,-138)'>
<rect height='16' id='rect5650' inkscape:label='audio-volume-high' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:1;marker:none' transform='rotate(-90)' width='16' x='-194' y='20'/>
<path inkscape:connector-curvature='0' d='M 23.031251,187.41984 C 23.02165,187.51337 23,187.59966 23,187.69524 23,189.5204 24.790861,191 26.999999,191 29.209139,191 31,189.5204 31,187.69524 c 0,-0.0722 -0.02574,-0.13556 -0.03125,-0.20655 L 27,190 Z' id='path5652' sodipodi:nodetypes='csssccc' style='color:#000000;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:0.949982px;marker:none;enable-background:accumulate'/>
<path inkscape:connector-curvature='0' d='m 26.96875,180.96875 -6.46875,3.5 6.5,4.09375 6.625,-4.03125 z M 27,184 c 0.552285,0 1,0.22386 1,0.5 0,0.27614 -0.447715,0.5 -1,0.5 -0.552285,0 -1,-0.22386 -1,-0.5 0,-0.27614 0.447715,-0.5 1,-0.5 z' id='path5654' style='fill:#2e3436;fill-opacity:1;stroke:none'/>
<circle cx='-46.5' cy='-31.5' id='circle5658' r='1.5' style='color:#000000;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;enable-background:accumulate' transform='matrix(0.66854633,0,0,0.66854633,65.090224,209.06203)'/>
</g>
<g id='g5676' inkscape:label='world globe map' style='display:inline;enable-background:new' transform='translate(-52.000003,-628)'>
<rect height='16' id='rect5664' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;opacity:0.514644;fill:none;stroke:none;stroke-width:3;marker:none;enable-background:accumulate' width='16' x='11.982551' y='668.00458'/>
<g id='g5674' style='display:inline' transform='translate(12,667.98828)'>
<path inkscape:connector-curvature='0' d='m 1,7.0117188 v 1 h 13 v -1 z' id='path5666' style='color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.5;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate'/>
<path inkscape:connector-curvature='0' d='m 1,4.0117188 v 1 h 13 v -1 z' id='path5668' style='color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.5;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate'/>
<path inkscape:connector-curvature='0' d='m 1,10.011719 v 1 h 13 v -1 z' id='path5670' style='color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.5;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate'/>
<path inkscape:connector-curvature='0' d='m 494,164.5 c -4.13029,0 -7.5,3.36971 -7.5,7.5 0,4.13029 3.36971,7.5 7.5,7.5 4.13029,0 7.5,-3.36971 7.5,-7.5 0,-4.13029 -3.36971,-7.5 -7.5,-7.5 z m 0,2 c 0.25596,0 0.50553,0.0232 0.75195,0.0566 0.19059,0.26016 0.38153,0.59041 0.54883,1.02539 C 495.7226,168.67877 496,170.25704 496,172 c 0,1.74296 -0.2774,3.31928 -0.69922,4.41602 -0.16776,0.43617 -0.35967,0.767 -0.55078,1.02734 -0.24581,0.0333 -0.49471,0.0566 -0.75,0.0566 -0.25529,0 -0.50419,-0.0234 -0.75,-0.0566 -0.19111,-0.26034 -0.38302,-0.59117 -0.55078,-1.02734 C 492.2774,175.31928 492,173.74296 492,172 c 0,-1.74296 0.2774,-3.32123 0.69922,-4.41797 0.1673,-0.43498 0.35824,-0.76523 0.54883,-1.02539 C 493.49447,166.5232 493.74404,166.5 494,166.5 Z m -2.08789,0.4082 c -0.0474,0.10764 -0.10239,0.1998 -0.14649,0.31446 C 491.28262,168.47846 491,170.15311 491,172 c 0,1.84689 0.28262,3.51959 0.76562,4.77539 0.0443,0.11525 0.0988,0.20826 0.14649,0.31641 C 489.90574,176.27348 488.5,174.30916 488.5,172 c 0,-2.30916 1.40574,-4.27348 3.41211,-5.0918 z m 4.17578,0 c 2.00637,0.81832 3.41211,2.78264 3.41211,5.0918 0,2.30916 -1.40574,4.27348 -3.41211,5.0918 0.0477,-0.10815 0.10216,-0.20116 0.14649,-0.31641 C 496.71738,175.51959 497,173.84689 497,172 c 0,-1.84689 -0.28263,-3.52154 -0.76562,-4.77734 -0.0441,-0.11466 -0.0991,-0.20682 -0.14649,-0.31446 z' id='path5672' style='color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate' transform='translate(-486.5,-164.48828)'/>
</g>
</g>
<g id='g5689' inkscape:label='world globe earth continents planet' style='display:inline;enable-background:new' transform='translate(-32.000003,-628)'>
<rect height='16' id='rect5680' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;opacity:0.514644;fill:none;stroke:none;stroke-width:3;marker:none;enable-background:accumulate' width='16' x='11.982551' y='668.00458'/>
<g id='g5682' style='display:inline' transform='translate(12,667.98828)'/>
<circle cx='19.5' cy='675.5' id='circle5684' r='6.5' style='opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#2e3436;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal'/>
<path clip-path='url(#clipPath17189-2-3)' inkscape:connector-curvature='0' d='m 152,-12 v -32 l 32,-32 h 32 v -32 l -32,-32 H 56 v 128 l 32,32 32,32 v 32 l 32,32 v 32 32 l 32,32 v -32 l 32,-32 V 116 L 248,84 216,52 184,20 h -32 -32 v -32 z m 128,-64 32,32 32,-32 h 32 32 l 33,48.000008 v 16 L 472,20 V -140 H 344 v 32 h -32 z m 32,32 -32,32 v 32 l 32,32 h 32 l 17,24.000008 v 32.000002 32 L 408,180 440,148 V 52 L 472,20 439.05046,21.86025 408,-12 v -7.999992 h -39 l -16,-24 z' id='path5687' sodipodi:nodetypes='cccccccccccccccccccccccccccccccccccccccccccccccccccccccc' style='display:inline;opacity:0.5;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:0.409542px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new' transform='matrix(0.02758747,0,0,0.02758747,11.783399,674.96238)'/>
</g>
<g id='g5697' inkscape:label='grocery food drink buy shop cart' transform='translate(-560)'>
<rect height='16' id='rect5693' inkscape:label='audio-volume-high' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:1;marker:none' transform='rotate(-90)' width='16' x='-76' y='440'/>
<path inkscape:connector-curvature='0' d='M 443.99805,61.992188 A 0.50005,0.50005 0 0 0 443.91016,62 H 442 c -0.554,0 -1,0.446 -1,1 0,0.554 0.446,1 1,1 h 1.77148 l 1.125,6 h -0.36132 A 0.50005,0.50005 0 0 0 444.5,70 c -0.53509,3e-6 -1.03128,0.286595 -1.29883,0.75 -0.26755,0.463407 -0.26755,1.036593 0,1.5 0.26755,0.463405 0.76374,0.749997 1.29883,0.75 h 0.58789 A 1.5,1.5 0 0 0 445,73.5 1.5,1.5 0 0 0 446.5,75 1.5,1.5 0 0 0 448,73.5 1.5,1.5 0 0 0 447.91211,73 h 3.17578 A 1.5,1.5 0 0 0 451,73.5 1.5,1.5 0 0 0 452.5,75 1.5,1.5 0 0 0 454,73.5 1.5,1.5 0 0 0 452.5625,72.003906 0.50005,0.50005 0 0 0 452.5,72 h -8 c -0.17943,-10e-7 -0.34388,-0.09461 -0.43359,-0.25 -0.0897,-0.155395 -0.0897,-0.344605 0,-0.5 0.0897,-0.155394 0.25416,-0.249999 0.43359,-0.25 h 7 c 0.64722,0 1.2071,-0.308959 1.61133,-0.753906 0.40422,-0.444948 0.6884,-1.017821 0.91992,-1.648438 0.46305,-1.261233 0.71177,-2.778396 0.95898,-3.998047 A 0.50005,0.50005 0 0 0 454.5,64 h -9.70898 l -0.29883,-1.591797 a 0.50005,0.50005 0 0 0 -0.49414,-0.416015 z M 444.97852,65 H 446 v 1 h 1 v -1 h 1 v 1 h 1 v -1 h 1 v 1 h 1 v -1 h 1 v 1 h 1 v -1 h 0.86719 c -0.0643,0.327528 -0.13435,0.664255 -0.20117,1 H 453 v 1 h 0.45117 c -0.0829,0.349536 -0.17342,0.684773 -0.27734,1 H 453 v 0.462891 c -0.0767,0.188274 -0.15297,0.3787 -0.23828,0.537109 H 452 v 0.871094 C 451.85005,69.952837 451.69009,70 451.5,70 H 451 v -1 h -1 v 1 h -1 v -1 h -1 v 1 h -1 v -1 h -1 v 1 h -0.084 l -0.1875,-1 H 446 v -1 h -0.45898 l -0.1875,-1 H 446 v -1 h -0.83398 z M 446,67 v 1 h 1 v -1 z m 1,0 h 1 v -1 h -1 z m 1,0 v 1 h 1 v -1 z m 1,0 h 1 v -1 h -1 z m 1,0 v 1 h 1 v -1 z m 1,0 h 1 v -1 h -1 z m 1,0 v 1 h 1 v -1 z m 0,1 h -1 v 1 h 1 z m -2,0 h -1 v 1 h 1 z m -2,0 h -1 v 1 h 1 z' id='path5695' style='opacity:1;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1'/>
</g>
<g id='g4985' inkscape:label='camera cameras switch toggle mode multiple multicam' style='display:inline;enable-background:new' transform='translate(-39.999993,162)'>
<rect height='16' id='rect4973' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:1;marker:none' width='16' x='20' y='276'/>
<rect height='7' id='rect4975' rx='0.99979997' ry='1' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:1;marker:none' transform='scale(-1,1)' width='7' x='-31' y='277'/>
<path inkscape:connector-curvature='0' d='M 23.734639,280.47612 21.36294,277.77777 H 21 v 5.44445 h 0.341813 z' id='path4977' sodipodi:nodetypes='cccccc' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:1;marker:none'/>
</g>
<g id='g5004' inkscape:label='transport transit car vehicle electric ev' style='display:inline;enable-background:new' transform='translate(-771.9985,69.99997)'>
<path inkscape:connector-curvature='0' d='m 735,435.00003 c -0.45916,-1.8e-4 -0.85946,0.31232 -0.9707,0.75781 l -1,4 c -0.0196,0.0792 -0.0294,0.16057 -0.0293,0.24219 v 0.0391 c -0.56438,0.0953 -1,0.56199 -1,1.1543 v 2.61325 c 0,0.59231 0.43562,1.05902 1,1.1543 V 446.5 c 0,0.277 0.223,0.5 0.5,0.5 h 2 c 0.277,0 0.5,-0.223 0.5,-0.5 V 445 h 4 v 1.5 c 0,0.277 0.5,0.5 0.5,0.5 h 2 c 0,0 0.5,-0.223 0.5,-0.5 v -1.53906 c 0.56438,-0.0953 1,-0.56199 1,-1.1543 v -2.61325 c 0,-0.59231 -0.43562,-1.05902 -1,-1.1543 v -0.0391 c 1.5e-4,-0.0816 -0.01,-0.16296 -0.0293,-0.24219 l -1,-4 c -0.11124,-0.44549 -0.51154,-0.75799 -0.9707,-0.75781 z m 0.78125,2 h 4.4375 l 0.75,3 h -5.9375 z m -1.25,4.03853 c 0.82843,0 1.5,0.67157 1.5,1.5 0,0.82843 -0.67157,1.5 -1.5,1.5 -0.82843,0 -1.5,-0.67157 -1.5,-1.5 0,-0.82843 0.67157,-1.5 1.5,-1.5 z m 7,0 c 0.82843,0 1.5,0.67157 1.5,1.5 0,0.82843 -0.67157,1.5 -1.5,1.5 -0.82843,0 -1.5,-0.67157 -1.5,-1.5 0,-0.82843 0.67157,-1.5 1.5,-1.5 z' id='path4996' sodipodi:nodetypes='cccccsscssssccsssscsscccccccccccssssssssss' style='color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate' transform='translate(0,-64)'/>
<rect height='16' id='rect4998' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;opacity:0.514644;fill:none;fill-opacity:1;stroke:none;stroke-width:3;marker:none;enable-background:accumulate' width='16' x='731.99719' y='368.00003'/>
<path inkscape:connector-curvature='0' d='m 743.9985,369.50003 v 1.5 h -0.97227 v 2 c 0,1.10457 1.44786,2 2.55243,2 1.10457,0 2.41984,-0.89543 2.41984,-2 v -2 h -1 v -1.5 c 0,-0.28168 -0.27624,-0.50374 -0.51562,-0.5 -0.23202,0.004 -0.48438,0.20271 -0.48438,0.5 v 1.5 h -0.41984 -0.58016 v -1.5 c 0,-0.25 -0.27624,-0.50374 -0.51562,-0.5 -0.23202,0.004 -0.48438,0.23392 -0.48438,0.5 z' id='path5000' sodipodi:nodetypes='cccssscccscccccsc' style='opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2.66667;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal'/>
<path inkscape:connector-curvature='0' d='M 745.49023,372.99219 A 0.50005,0.50005 0 0 0 744.99805,373.5 v 6.85938 c 0,0.52775 -0.24799,0.62202 -0.49414,0.61914 -0.24615,-0.003 -0.50586,-0.10807 -0.50586,-0.66602 V 379 a 0.50005,0.50005 0 1 0 -1,0 v 1.3125 c 0,0.98892 0.74029,1.65718 1.49414,1.66602 0.75385,0.009 1.50586,-0.64693 1.50586,-1.61914 V 373.5 a 0.50005,0.50005 0 0 0 -0.50782,-0.50781 z' id='path5002' style='color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate'/>
</g>
<g id='g5022' inkscape:label='audio headset heaphones microphone mic mike' style='display:inline;enable-background:new' transform='translate(-100.9998,11)'>
<rect height='16' id='rect5010' style='fill:none;stroke:none' width='16.000002' x='81.000198' y='467'/>
<path inkscape:connector-curvature='0' d='m 88.968786,466.99908 c -3.305456,0 -6.023869,3.00835 -5.968586,5.71875 0.06164,3.02218 0.933593,4.69547 1.125,5.28125 1.583096,0 -0.125,0 1.400504,0 -1.16149,-2.29152 -1.049064,-5.1562 -1.049064,-5.1562 0,-2.37255 2.006651,-4.31249 4.492146,-4.3125 2.485496,0 4.499787,1.92062 4.492147,4.375 -0.02342,1.67413 -0.171684,2.28358 -1.005236,4.8125 h 1.570681 c 0.224499,-0.64458 0.973822,-2.06546 0.973822,-4.90625 0,-2.8298 -2.725958,-5.8125 -6.031414,-5.8125 z' id='path5012' sodipodi:nodetypes='cscccscccssc' style='fill:#2e3436;fill-opacity:1;stroke:none'/>
<rect height='5.1319256' id='rect5014' rx='1.8617905' ry='1.8614891' style='fill:#2e3436;fill-opacity:1;stroke:none' transform='matrix(-0.96317422,-0.26887809,-0.3026725,0.95309462,0,0)' width='3.1448481' x='-234.4108' y='431.70209'/>
<rect height='5.1319256' id='rect5016' rx='1.8617905' ry='1.8614891' style='fill:#2e3436;fill-opacity:1;stroke:none' transform='matrix(0.96317422,-0.26887809,0.3026725,0.95309462,0,0)' width='3.1448481' x='-64.604736' y='479.60641'/>
<rect height='2' id='rect5018' rx='0.9921875' ry='1' style='color:#000000;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;enable-background:accumulate' width='2' x='89.011238' y='480'/>
</g>
<g id='g5034' inkscape:label='audio headphones ear audio ' style='display:inline;enable-background:new' transform='translate(-121.0002,11)'>
<rect height='16' id='rect5026' style='fill:none;stroke:none' width='16.000002' x='81.000198' y='467'/>
<rect height='6.0516844' id='rect5028' rx='1.862784' ry='1.862784' style='fill:#2e3436;fill-opacity:1;stroke:none' transform='matrix(0.95982607,-0.28059566,0.29019891,0.95696635,0,0)' width='3.5680485' x='-58.621819' y='480.85031'/>
<path inkscape:connector-curvature='0' d='m 88.968786,468 c -3.305456,0 -6.023914,3.00835 -5.968586,5.71875 0.04825,2.36557 0.808593,4.69547 1,5.28125 1.583096,0 0,0 1.525504,0 -1.16149,-2.29152 -1.049064,-5.1562 -1.049064,-5.1562 0,-2.37255 2.006651,-4.31249 4.492146,-4.3125 2.485496,0 4.499787,1.82687 4.492147,4.28125 -0.02342,1.67413 -0.171684,2.65858 -1.005236,5.1875 h 1.570681 c 0.224499,-0.64458 0.973822,-3.19046 0.973822,-5.28125 0,-2.8298 -2.725958,-5.71875 -6.031414,-5.71875 z' id='path5030' sodipodi:nodetypes='cscccscccssc' style='fill:#2e3436;fill-opacity:1;stroke:none'/>
<rect height='6.0516844' id='rect5032' rx='1.862784' ry='1.862784' style='fill:#2e3436;fill-opacity:1;stroke:none' transform='matrix(-0.95982607,-0.28059566,-0.29019891,0.95696635,0,0)' width='3.5680485' x='-228.98027' y='430.93314'/>
</g>
<g id='g5062' inkscape:label='camera video film cinema' style='display:inline;enable-background:new' transform='translate(-212.00001,90)'>
<rect height='16' id='rect5042' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:1;marker:none;enable-background:new' transform='rotate(90)' width='16' x='388' y='-168.00044'/>
<circle cx='158.5' cy='392.5' id='circle5044' r='2.5' style='opacity:1;fill:none;fill-opacity:1;stroke:#2e3436;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1'/>
<circle cx='164.5' cy='392.5' id='circle5046' r='2.5' style='opacity:1;fill:none;fill-opacity:1;stroke:#2e3436;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1'/>
<rect height='1' id='rect5052' style='color:#000000;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;enable-background:accumulate' transform='scale(-1,1)' width='1' x='-153' y='400'/>
<rect height='1' id='rect5054' style='color:#000000;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;enable-background:accumulate' transform='scale(-1,1)' width='1' x='-153' y='395'/>
<path inkscape:connector-curvature='0' d='m 153,396 3,2 -3,2 z' id='path5056' sodipodi:nodetypes='cccc' style='color:#000000;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:new'/>
<path inkscape:connector-curvature='0' d='m 166,396 h 2 v 2 l -1,1 h -1 z' id='path5058' sodipodi:nodetypes='cccccc' style='color:#000000;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;enable-background:accumulate'/>
<path inkscape:connector-curvature='0' d='m 166,395 v 6 c 0,1 -1,1 -1,1 h -7 c 0,0 -1,0 -1,-1 v -6 z' id='path5060' sodipodi:nodetypes='cccccc' style='fill:#2e3436;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1'/>
</g>
<g id='g5722' inkscape:label='font weight bold text type' style='display:inline;enable-background:new' transform='translate(-305.00021,611)'>
<rect height='16' id='rect5716' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:1;marker:none' width='16' x='141.0002' y='357'/>
</g>
<g id='g5732' inkscape:label='font style underline text type' style='display:inline;enable-background:new' transform='translate(-285.00021,611)'>
<rect height='16' id='rect5726' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:1;marker:none' width='16' x='141.0002' y='357'/>
</g>
<g id='g5742' inkscape:label='font style strikeout strikethrough text type' style='display:inline;enable-background:new' transform='translate(-265.00021,611)'>
<rect height='16' id='rect5736' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:1;marker:none' width='16' x='141.0002' y='357'/>
<path inkscape:connector-curvature='0' d='m 244,709 v 2 h 6 c 0.42816,0 1,0.61414 1,1 h 2 c 0,-1.63434 -1.3198,-3 -3,-3 z m -1,7 c 0.006,0.72062 0.26893,1.45271 0.78125,2.03125 C 244.29357,718.60979 245.09172,719 246,719 h 6 1 v -1 -2 h -2 v 1 h -5 c -0.39787,0 -0.56691,-0.10979 -0.71875,-0.28125 C 245.12941,716.54729 245.00248,716.27938 245,716 Z' id='path5738' style='color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;marker:none;enable-background:accumulate' transform='translate(-99.000002,-349)'/>
</g>
<g id='g5750' inkscape:label='font style italic slanted text type' style='display:inline;enable-background:new' transform='translate(-245.00021,611)'>
<rect height='16' id='rect5746' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:1;marker:none' width='16' x='141.0002' y='357'/>
</g>
<g id='g5762' inkscape:label='font style underline text type direction ' style='display:inline;enable-background:new' transform='translate(-64.006173,968.04939)'>
<path inkscape:connector-curvature='0' d='m 6.0001232,-1.2e-4 v 2 h 5.9999998 c 0.42816,0 1,0.61414 1,1 v 1 H 8.0001232 c -0.91927,0 -1.7356,0.38396 -2.25,0.96875 -0.5144,0.58479 -0.75639,1.31063 -0.75,2.03125 0.006,0.72062 0.26893,1.45271 0.78125,2.03125 0.51232,0.57854 1.31047,0.96875 2.21875,0.96875 h 5.9999998 1 v -1 -6 c 0,-1.63434 -1.3198,-3 -3,-3 z m 2,6 h 4.9999998 v 2 H 8.0001232 c -0.39787,0 -0.56691,-0.10979 -0.71875,-0.28125 -0.15184,-0.17146 -0.27877,-0.43937 -0.28125,-0.71875 -0.002,-0.27938 0.10467,-0.55354 0.25,-0.71875 0.14533,-0.16521 0.32764,-0.28125 0.75,-0.28125 z' id='path5754' style='color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:xx-small;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;marker:none;enable-background:accumulate'/>
<rect height='15.999999' id='rect5756' style='fill:none;stroke:none' width='16' x='-1.6064154e-08' y='-0.049382459'/>
<path inkscape:connector-curvature='0' d='m 4,14.95063 -1,-10e-6 c -0.26531,-3e-5 -0.53058,-0.0931 -0.71875,-0.28124 l -2,-2.00001 L -1e-5,12.38812 v -0.87499 l 0.28126,-0.28126 2,-1.99999 C 2.46943,9.04367 2.73472,8.95067 3.00001,8.95067 l 1,-1e-5 v 1 c 4e-5,0.26531 -0.0931,0.53059 -0.28121,0.71877 l -1.28126,1.28124 1.28125,1.28125 c 0.18815,0.18817 0.28125,0.45345 0.28125,0.71875 v 1 z' id='path5758' sodipodi:nodetypes='ccccccccscccccccc' style='color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:&apos;Bitstream Vera Sans&apos;;-inkscape-font-specification:&apos;Bitstream Vera Sans&apos;;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;marker:none;enable-background:accumulate'/>
</g>
<g id='g5774' inkscape:label='font style underline text type direction ' style='display:inline;enable-background:new' transform='translate(-264.00041,262)'>
<rect height='16' id='rect5766' style='fill:none;stroke:none' width='15.999999' x='180.0002' y='706'/>
<path inkscape:connector-curvature='0' d='m 182.00032,706 v 2 h 6 c 0.42816,0 1,0.61414 1,1 v 1 h -5 c -0.91927,0 -1.7356,0.38396 -2.25,0.96875 -0.5144,0.58479 -0.75639,1.31063 -0.75,2.03125 0.006,0.72062 0.26893,1.45271 0.78125,2.03125 0.51232,0.57854 1.31047,0.96875 2.21875,0.96875 h 6 1 v -1 -6 c 0,-1.63434 -1.3198,-3 -3,-3 z m 2,6 h 5 v 2 h -5 c -0.39787,0 -0.56691,-0.10979 -0.71875,-0.28125 -0.15184,-0.17146 -0.27877,-0.43937 -0.28125,-0.71875 -0.002,-0.27938 0.10467,-0.55354 0.25,-0.71875 0.14533,-0.16521 0.32764,-0.28125 0.75,-0.28125 z' id='path5768' style='color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:xx-small;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;marker:none;enable-background:accumulate'/>
<path inkscape:connector-curvature='0' d='m 192.00019,721.00001 1,-10e-6 c 0.26531,-3e-5 0.53058,-0.0931 0.71875,-0.28124 l 2,-2.00001 0.28126,-0.28125 v -0.87499 l -0.28126,-0.28126 -2,-1.99999 c -0.18818,-0.18821 -0.45347,-0.28121 -0.71876,-0.28121 l -1,-10e-6 v 1 c -4e-5,0.26531 0.0931,0.53059 0.28121,0.71877 l 1.28126,1.28124 -1.28125,1.28125 c -0.18815,0.18817 -0.28125,0.45345 -0.28125,0.71875 v 1 z' id='path5770' sodipodi:nodetypes='ccccccccscccccccc' style='color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:&apos;Bitstream Vera Sans&apos;;-inkscape-font-specification:&apos;Bitstream Vera Sans&apos;;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;marker:none;enable-background:accumulate'/>
</g>
<g id='g5784' inkscape:label='font style underline text type squiggly wrong spellcheck' style='display:inline;enable-background:new' transform='translate(-285.00021,631)'>
<rect height='16' id='rect5778' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:1;marker:none' width='16' x='141.0002' y='357'/>
</g>
<g id='g5111' inkscape:label='weather windy hazard' style='enable-background:new' transform='translate(-412,510)'>
<rect height='16' id='rect5097' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;fill-opacity:1;stroke:none;stroke-width:1.781;marker:none;enable-background:new' width='16' x='391.99979' y='88'/>
</g>
<g id='g5139' inkscape:label='weather snow snowflake' style='display:inline;enable-background:new' transform='translate(-261.00021,321)'>
<rect height='16' id='rect5131' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:1.781;marker:none;enable-background:new' width='16' x='221' y='277'/>
<path d='m 221.99434,281.25286 a 0.50005,0.50005 0 0 0 0.19368,0.68015 l 1.32779,0.7666 -1.24673,0.72583 a 0.50005,0.50005 0 1 0 0.50295,0.86322 l 1.74005,-1.01385 2.98711,1.72461 -2.98769,1.72562 -1.73989,-1.01376 a 0.50005,0.50005 0 1 0 -0.50249,0.86233 l 1.24698,0.72688 -1.32879,0.7664 a 0.50005,0.50005 0 0 0 -0.186,0.69324 l 0.002,10e-4 a 0.50005,0.50005 0 0 0 0.6853,0.17238 l 1.32712,-0.76737 0.006,1.44243 a 0.50005,0.50005 0 1 0 0.9986,-0.003 l -0.008,-2.01393 2.98672,-1.72393 3.9e-4,3.44854 -1.74799,1.00026 a 0.50005,0.50005 0 1 0 0.49665,0.86634 l 1.25227,-0.71587 -0.001,1.533 a 0.50005,0.50005 0 0 0 0.50769,0.50737 l 0.002,10e-4 a 0.50005,0.50005 0 0 0 0.49161,-0.50777 l -6.7e-4,-1.53397 1.25299,0.71649 a 0.50005,0.50005 0 1 0 0.49556,-0.86634 l -1.74789,-0.99991 6.6e-4,-3.45018 3.03109,1.75 -0.0189,2.00532 a 0.50025967,0.50025967 0 1 0 1.00048,0.009 l 0.0129,-1.44042 1.28551,0.74219 a 0.50005,0.50005 0 1 0 0.5,-0.86602 l -1.28551,-0.74219 1.24096,-0.73143 a 0.50025967,0.50025967 0 1 0 -0.5083,-0.86178 l -1.72723,1.01899 -3.03109,-1.75 3.03117,-1.75014 1.72832,1.01817 a 0.50026024,0.50026024 0 1 0 0.50693,-0.86202 l -1.23975,-0.73159 1.28533,-0.74189 a 0.50050004,0.50050004 0 1 0 -0.501,-0.8666 l -1.28534,0.74188 -0.0125,-1.43931 a 0.50026265,0.50026265 0 0 0 -0.99984,0.009 l 0.0168,2.00565 -3.03117,1.75013 8e-5,-3.50013 1.74551,-0.98816 a 0.50025967,0.50025967 0 1 0 -0.49203,-0.87044 l -1.25272,0.70885 -1.8e-4,-1.48408 a 0.50050004,0.50050004 0 1 0 -1.001,-5.8e-4 l 1.7e-4,1.48407 -1.25345,-0.70786 a 0.50026024,0.50026024 0 1 0 -0.49307,0.87003 l 1.74592,0.98769 -8e-5,3.50014 -2.98711,-1.72461 0.008,-2.01386 a 0.50005,0.50005 0 1 0 -0.99905,-0.004 l -0.005,1.44251 -1.32779,-0.7666 a 0.50005,0.50005 0 0 0 -0.69368,0.18587 z' id='use5135' style='color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate'/>
<path d='m 222.00215,288.76067 a 0.50005,0.50005 0 0 0 0.68587,0.17234 l 1.32779,-0.7666 0.005,1.44262 a 0.50005,0.50005 0 1 0 0.99905,-0.004 l -0.008,-2.01385 2.98711,-1.72461 5.9e-4,3.45023 -1.74789,0.99991 a 0.50005,0.50005 0 1 0 0.49556,0.86633 l 1.25298,-0.71648 -6.7e-4,1.53397 a 0.50005,0.50005 0 0 0 0.50736,0.5077 l 0.002,-10e-4 a 0.50005,0.50005 0 0 0 0.49194,-0.5073 l -0.001,-1.533 1.25226,0.71587 a 0.50005,0.50005 0 1 0 0.49665,-0.86634 l -1.74798,-1.00026 3.9e-4,-3.44854 2.98672,1.72393 -0.008,2.01393 a 0.50005,0.50005 0 1 0 0.9986,0.003 l 0.006,-1.44243 1.32711,0.76737 a 0.50005,0.50005 0 0 0 0.69324,-0.18599 l 0.002,-10e-4 a 0.50005,0.50005 0 0 0 -0.19394,-0.67964 l -1.32879,-0.7664 1.24699,-0.72687 a 0.50005,0.50005 0 1 0 -0.50249,-0.86234 l -1.73989,1.01376 -2.98762,-1.72566 3.03109,-1.75 1.72723,1.01899 a 0.50025967,0.50025967 0 1 0 0.5083,-0.86178 l -1.24096,-0.73143 1.28551,-0.74219 a 0.50005,0.50005 0 1 0 -0.5,-0.86602 l -1.28551,0.74219 -0.0129,-1.44042 a 0.50025967,0.50025967 0 1 0 -1.00048,0.009 l 0.0189,2.00532 -3.03109,1.75 -8e-5,-3.50014 1.74592,-0.98769 a 0.50026024,0.50026024 0 1 0 -0.49307,-0.87002 l -1.25345,0.70786 1.7e-4,-1.48407 a 0.50050004,0.50050004 0 1 0 -1.001,5.8e-4 l -1.8e-4,1.48407 -1.25272,-0.70884 a 0.50026265,0.50026265 0 0 0 -0.49203,0.87044 l 1.74535,0.98826 8e-5,3.50013 -3.03117,-1.75013 0.017,-2.00574 a 0.50025967,0.50025967 0 1 0 -0.99984,-0.009 l -0.0125,1.43932 -1.28534,-0.74189 a 0.50050004,0.50050004 0 1 0 -0.501,0.8666 l 1.28533,0.74189 -1.23975,0.73159 a 0.50026024,0.50026024 0 1 0 0.50693,0.86203 l 1.72832,-1.01817 3.03117,1.75014 -2.98711,1.72461 -1.74005,-1.01386 a 0.50005,0.50005 0 1 0 -0.50295,0.86323 l 1.24656,0.72591 -1.32779,0.7666 a 0.50005,0.50005 0 0 0 -0.18587,0.69368 z' id='use5137' style='color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate'/>
</g>
<g id='g5166' inkscape:label='weather showers rain rainfall wet' style='display:inline;enable-background:new' transform='translate(-261.00021,321)'>
<rect height='16' id='rect5150' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:1.781;marker:none;enable-background:new' width='16' x='201' y='277'/>
<path inkscape:connector-curvature='0' d='m 210.46539,277 c -1.27312,0 -2.30725,0.97301 -2.44824,2.21875 C 207.6931,279.09667 207.36073,279 206.99446,279 c -1.64309,0 -2.97508,1.34315 -2.97508,3 0,0.0982 0.0218,0.1855 0.0309,0.28125 C 203.75312,282.10201 203.39921,282 203.02769,282 c -1.0954,0 -1.9834,0.89543 -1.9834,2 0,1.10457 0.888,2 1.9834,2 h 12.39618 c 0.82155,0 1.48754,-0.67157 1.48754,-1.5 0,-0.82843 -0.66599,-1.5 -1.48754,-1.5 -0.20539,0 -0.41085,0.0491 -0.58882,0.125 0.0522,-0.20194 0.0929,-0.40658 0.0929,-0.625 0,-1.22936 -0.88592,-2.22819 -2.04537,-2.4375 0.0416,-0.18136 0.062,-0.36843 0.062,-0.5625 0,-1.38071 -1.10999,-2.5 -2.47924,-2.5 z' id='path5152' sodipodi:nodetypes='ccsscssccsscscscc' style='color:#000000;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2.4;marker:none;enable-background:accumulate'/>
</g>
<g id='g5191' inkscape:label='weather fog mist visibility grey' style='display:inline;enable-background:new' transform='translate(-361.0002,321)'>
<rect height='16' id='rect5183' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:1.781;marker:none;enable-background:new' width='16' x='281' y='277'/>
</g>
<g id='g4915' inkscape:label='photography' transform='translate(-140)'>
<circle cx='128' cy='328' id='circle4902' r='2' style='opacity:1;fill:none;fill-opacity:1;stroke:#2e3436;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1'/>
<rect height='16' id='rect4913' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:1;marker:none' width='16' x='120' y='320'/>
</g>
<g id='g4935' inkscape:label='photography' transform='translate(-60.000003)'>
<rect height='16' id='rect4927' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:1;marker:none' width='16' x='20' y='340'/>
<rect height='8' id='rect4933' rx='1.5' ry='1.5' style='opacity:1;fill:none;fill-opacity:1;stroke:#2e3436;stroke-width:2;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1' width='4' x='31' y='344'/>
</g>
<g id='g4952' inkscape:label='photography' transform='translate(-80.000003)'>
<rect height='12' id='rect4940' style='display:inline;opacity:1;fill:none;fill-opacity:1;stroke:#2e3436;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1' transform='translate(-241.0002,567)' width='12.000013' x='303.00021' y='-225'/>
<rect height='16' id='rect4950' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:1;marker:none' width='16' x='60' y='340'/>
</g>
<g id='g4883' inkscape:label='auth authentication finger fingeprint reader' style='display:inline;enable-background:new' transform='translate(67.999597,-128)'>
<path inkscape:connector-curvature='0' d='m -101,377 h 2 l 4,1 v 4 c 0,1 -1,1 -1,1 h -5 z' id='path4875' sodipodi:nodetypes='ccccccc' style='fill:#2e3436;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1'/>
<rect height='16' id='rect4877' style='fill:none;stroke:none' width='16.000002' x='-107.9996' y='368'/>
<path inkscape:connector-curvature='0' d='m -101,368 c -2.19729,0 -4,1.80271 -4,4 0,1.46662 0.81247,2.74314 2,3.43945 V 372 c 0,-1.0907 0.9093,-2 2,-2 1.0907,0 2,0.9093 2,2 v 3 a 1.0001,1.0001 0 0 1 0.24219,0.0293 l 0.25586,0.0645 C -97.59491,374.35838 -97,373.24958 -97,372 c 0,-2.19729 -1.80271,-4 -4,-4 z' id='path4879' style='color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:0.35;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate'/>
</g>
<g id='g4897' inkscape:label='people shaking hands agreement' style='display:inline;enable-background:new' transform='translate(-312.00001,-268)'>
<rect height='16' id='rect4891' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:1;marker:none' width='16' x='292.00018' y='508'/>
<path inkscape:connector-curvature='0' d='m 296,509 c -1.10457,0 -2,0.89543 -2,2 0,1.10457 0.89543,2 2,2 1.10457,0 2,-0.89543 2,-2 0,-1.10457 -0.89543,-2 -2,-2 z m -0.041,4.98633 c -0.1041,0.004 -0.2069,0.0247 -0.30468,0.0606 C 294.91825,514.15783 293,514.73772 293,518 v 5 h 4 v -4.69141 c 0.10035,0.0704 0.20153,0.13719 0.30664,0.19532 0.95244,0.52671 1.91552,0.50008 2.69922,0.49609 H 300.5 c 0.5,0 0.5,-0.5 0.5,-0.5 0,0 0,-0.5 0.0137,-0.5 H 300 v -1 c -0.002,-10e-6 -0.004,-10e-6 -0.006,0 -0.77718,0.004 -1.31336,-0.0228 -1.7207,-0.24805 -0.40735,-0.22527 -0.86965,-0.70463 -1.32422,-2.06836 -0.13583,-0.42858 -0.54096,-0.71384 -0.99024,-0.69726 z' id='path4893' sodipodi:nodetypes='sssssccsccccccccccccccc' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.84615;marker:none;enable-background:accumulate'/>
<path inkscape:connector-curvature='0' d='m 304,509 c 1.10457,0 2,0.89543 2,2 0,1.10457 -0.89543,2 -2,2 -1.10457,0 -2,-0.89543 -2,-2 0,-1.10457 0.89543,-2 2,-2 z m 0.041,4.98633 c 0.1041,0.004 0.2069,0.0247 0.30468,0.0606 C 305.08175,514.15783 307,514.73772 307,518 v 5 h -4 v -4.69141 c -0.10035,0.0704 -0.20153,0.13719 -0.30664,0.19532 -0.95244,0.52671 -1.91552,0.50008 -2.69922,0.49609 H 299.5 c -0.5,0 -0.5,-0.5 -0.5,-0.5 0,0 0,-0.5 -0.0137,-0.5 H 300 v -1 c 0.002,-10e-6 0.004,-10e-6 0.006,0 0.77718,0.004 1.31336,-0.0228 1.7207,-0.24805 0.40735,-0.22527 0.86965,-0.70463 1.32422,-2.06836 0.13583,-0.42858 0.54096,-0.71384 0.99024,-0.69726 z' id='path4895' sodipodi:nodetypes='sssssccsccccccccccccccc' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#2e3436;fill-opacity:0.5;fill-rule:nonzero;stroke:none;stroke-width:1.84615;marker:none;enable-background:accumulate'/>
</g>
<g id='g4843' inkscape:label='antarctic' transform='translate(-60.000003)'>
<rect height='2.0000174' id='rect4827' rx='0.5' ry='0.5' style='color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.4;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;enable-background:accumulate' width='1' x='29' y='143.99997'/>
<rect height='2' id='rect4829' rx='0.5' ry='0.5' style='color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.4;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;enable-background:accumulate' width='1' x='26' y='144'/>
<rect height='1' id='rect4831' rx='0.5' ry='0.5' style='color:#000000;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;enable-background:accumulate' width='1' x='29' y='145'/>
<path inkscape:connector-curvature='0' d='m 28.03125,140 c -1.737358,0 -2.933874,0.5199 -3.9375,1.5 -0.963449,0.9409 -1.309151,2.179 -1.53125,3.75 0,0 -0.240045,1.3003 0.0625,1.8438 -0.492951,0.5876 -2.59375,3.2187 -2.59375,4.4062 0.366384,1.1425 2.291251,-1.4769 2.625,0.031 0.284363,1.2849 0.857205,1.784 2.03125,2.5 -0.935316,0.084 -1.65625,0.477 -1.65625,0.9687 1.162767,0.7149 1.238428,0.8125 2.4375,0.8125 1.104569,0 1.5625,-0.2602 1.5625,-0.8125 0,-0.034 0.0065,-0.061 0,-0.094 0.331698,0.054 0.660862,0.094 1,0.094 v -1.5 c -2.216,0 -3.482007,-0.983 -4.125,-3.0312 -0.445321,-1.4186 0.5625,-3.2813 0.5625,-3.2813 -0.763331,-0.8775 -0.611864,-5.1339 2.53125,-5.2812 0.535657,0.1177 0.598255,1.0951 1.03125,1.0937 v -3 z' id='path4833' style='color:#000000;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;enable-background:accumulate'/>
<path inkscape:connector-curvature='0' d='m 27.044194,146.2487 v 0.5 c 0,0.554 1,1.5 1,1.5 0,0 1,-0.946 1,-1.5 v -0.5 h -1 z' id='path4835' sodipodi:nodetypes='cscsccc' style='color:#000000;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;enable-background:accumulate'/>
<rect height='1.0000174' id='rect4837' rx='0.4531163' ry='0.4531163' style='color:#000000;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;enable-background:accumulate' width='1' x='26' y='144.99997'/>
<path d='m 28.03125,140.0003 c 1.737358,0 2.933874,0.5199 3.9375,1.5 0.963449,0.9409 1.309151,2.179 1.53125,3.75 0,0 0.240045,1.30025 -0.0625,1.84375 0.492951,0.5876 2.59375,3.21875 2.59375,4.40625 -0.366384,1.1425 -2.291251,-1.47665 -2.625,0.0312 -0.284363,1.2849 -0.857205,1.784 -2.03125,2.5 0.935316,0.084 1.65625,0.47705 1.65625,0.96875 -1.162767,0.7149 -1.238428,0.8125 -2.4375,0.8125 -1.104569,0 -1.5625,-0.2602 -1.5625,-0.8125 0,-0.034 -0.0065,-0.0608 0,-0.0937 -0.331698,0.054 -0.660862,0.0937 -1,0.0937 -0.339138,0 -0.668302,-0.0397 -1,-0.0937 0.0065,0.033 0,0.0598 0,0.0937 0,0.5523 -0.457931,0.8125 -1.5625,0.8125 -1.199072,0 -1.274733,-0.0976 -2.4375,-0.8125 0,-0.4917 0.720934,-0.88475 1.65625,-0.96875 -1.174045,-0.716 -1.746887,-1.2151 -2.03125,-2.5 -0.333749,-1.5079 -2.258616,1.11125 -2.625,-0.0312 0,-1.1875 2.100799,-3.81865 2.59375,-4.40625 -0.302545,-0.5435 -0.0625,-1.84375 -0.0625,-1.84375 0.222099,-1.571 0.567801,-2.8091 1.53125,-3.75 1.003626,-0.9801 2.200142,-1.5 3.9375,-1.5 z m 1.03125,1.90625 c -0.535657,0.1177 -0.598255,1.09515 -1.03125,1.09375 -0.432995,10e-4 -0.495593,-0.97605 -1.03125,-1.09375 -3.143114,0.1473 -3.294581,4.40375 -2.53125,5.28125 0,0 -1.007821,1.86265 -0.5625,3.28125 0.642993,2.0482 1.909,3.03125 4.125,3.03125 2.216,0 3.482007,-0.98305 4.125,-3.03125 0.445321,-1.4186 -0.5625,-3.28125 -0.5625,-3.28125 0.763331,-0.8775 0.611864,-5.13395 -2.53125,-5.28125 z' id='use4839' style='color:#000000;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;enable-background:accumulate'/>
<rect height='16' id='rect4841' style='opacity:0.05;fill:none;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1' width='16' x='20' y='139.99788'/>
</g>
<g id='g4866' inkscape:label='tux' transform='translate(-100,20)'>
<rect height='1' id='rect4850' rx='0.5' ry='0.5' style='color:#000000;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;enable-background:accumulate' width='1' x='49' y='124.00005'/>
<path inkscape:connector-curvature='0' d='m 48.000037,120.0005 c -1.737358,0 -2.453927,0.33581 -3.375037,1.0932 -1.573603,1.60489 -1.990061,2.97962 -1.15625,4.9998 -1.086701,0.7438 -2.4375,3.7187 -2.4375,4.9062 0.0017,-0.0752 1.587209,0.9531 1.587209,0.9531 -0.852224,0.4998 -1.221324,1.3449 -0.993459,2.0781 0.378091,1.2166 2.113428,1.9063 3.3125,1.9063 1.145815,0.042 1.873086,-0.2148 2.09375,-1.0315 C 47.362948,134.9597 47.660862,135 48,135 v -1 h -1 c 0,0 -0.0044,-0.3162 2.4e-4,-0.4075 0.06393,-1.2579 -0.469729,-1.5597 -0.917077,-1.9495 -0.703892,-0.58144 -1.613477,-0.34165 -2.01332,-0.2913 l -0.28771,-0.4469 c -0.773304,-1.20117 0.427249,-3.4067 1.947034,-4.6304 -1.147639,-0.6037 -1.648446,-4.2733 1.270796,-4.1967 1.154376,-0.059 0.567042,1.4933 1.000037,1.4919 V 120 Z' id='path4852' sodipodi:nodetypes='cccccacccccsccsccccc' style='color:#000000;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;enable-background:accumulate'/>
<path inkscape:connector-curvature='0' d='m 48,125.4082 c -0.714394,0.0101 -2.03125,0.74805 -2.03125,0.74805 -0.72331,0.43545 1.621068,1.34235 2.03125,1.24805 0.410182,0.0943 2.75456,-0.8126 2.03125,-1.24805 0,0 -1.316856,-0.73791 -2.03125,-0.74805 z' id='path4854' style='color:#000000;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;enable-background:accumulate'/>
<rect height='1.0000174' id='rect4856' rx='0.4531163' ry='0.4531163' style='color:#000000;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;enable-background:accumulate' width='1' x='46' y='123.99993'/>
<path inkscape:connector-curvature='0' d='m 49.5,123 c -0.545351,0 -1,0.45465 -1,1 0,0.54535 0.454649,1 1,1 0.545351,0 1,-0.45465 1,-1 0,-0.54535 -0.454649,-1 -1,-1 z' id='path4858' style='color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.5;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate'/>
<path d='m 48,119.9995 c 1.737358,0 2.45389,0.33636 3.375,1.09375 1.573603,1.60489 1.990061,2.97982 1.15625,5 1.086701,0.7438 2.4375,3.71875 2.4375,4.90625 -0.0017,-0.0752 -1.587891,0.95313 -1.587891,0.95312 0.852224,0.4998 1.222006,1.34493 0.994141,2.07813 -0.378091,1.2166 -2.113428,1.90625 -3.3125,1.90625 -1.145815,0.042 -1.873086,-0.21455 -2.09375,-1.03125 -0.331698,0.054 -0.629612,0.0937 -0.96875,0.0937 -0.339138,0 -0.637052,-0.0417 -0.96875,-0.0957 -0.220664,0.8167 -0.947935,1.0752 -2.09375,1.0332 -1.199072,0 -2.934409,-0.68965 -3.3125,-1.90625 -0.227865,-0.7332 0.141917,-1.57833 0.994141,-2.07813 0,1e-5 -1.586191,-1.02832 -1.587891,-0.95312 0,-1.1875 1.350799,-4.16245 2.4375,-4.90625 -0.833811,-2.02018 -0.417353,-3.39511 1.15625,-5 0.92111,-0.75739 1.637642,-1.09375 3.375,-1.09375 z m 1,2.07812 c -1.154376,-0.059 -0.567005,1.49359 -1,1.49219 v -0.002 c -0.432995,0.001 0.154376,-1.54923 -1,-1.49024 -2.919242,-0.0766 -2.419123,3.59162 -1.271484,4.19532 -1.519785,1.2237 -2.72057,3.42969 -1.947266,4.63086 l 0.289062,0.44726 c 0.399844,-0.0504 1.30978,-0.29042 2.013672,0.29102 0.447348,0.38985 0.979946,0.69137 0.916016,1.94927 -0.0046,0.0913 0,0.4082 0,0.4082 h 1 1 c 0,0 0.0046,-0.3169 0,-0.4082 -0.06393,-1.2579 0.468668,-1.55942 0.916016,-1.94922 0.703892,-0.58144 1.613828,-0.34137 2.013672,-0.29102 l 0.289062,-0.44726 c 0.773304,-1.20117 -0.427481,-3.40716 -1.947266,-4.63086 1.147639,-0.6037 1.647758,-4.27191 -1.271484,-4.19532 z' id='use4860' style='color:#000000;display:inline;overflow:visible;visibility:visible;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;enable-background:accumulate'/>
<path inkscape:connector-curvature='0' d='M 46.453125,123 C 45.933747,123 45.5,123.43375 45.5,123.95312 v 0.0938 C 45.5,124.56625 45.933747,125 46.453125,125 h 0.09375 C 47.066253,125 47.5,124.56625 47.5,124.04688 v -0.0938 C 47.5,123.43375 47.066253,123 46.546875,123 Z' id='path4862' style='color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.5;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate'/>
<rect height='16' id='rect4864' style='opacity:0.05;fill:none;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1' width='16' x='40' y='119.99788'/>
</g>
<g id='g8508-7' inkscape:label='multitasking switch overview multi task shell window app' style='display:inline' transform='matrix(1,0,0,-1,-59.99979,872.00765)'>
<rect height='16' id='rect8500-3' style='color:#bebebe;overflow:visible;fill:none;stroke-width:2;marker:none' width='16' x='19.99975' y='296'/>
<g id='g8502-5' style='opacity:0.25'/>
<rect height='12' id='rect8510-6' rx='1' ry='1' style='opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#2e3436;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal' transform='scale(1,-1)' width='8' x='23.99979' y='-310.00766'/>
<rect height='8' id='rect8512-2' rx='1' ry='1' style='opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#2e3436;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal' transform='scale(1,-1)' width='3' x='20.99979' y='-308.00766'/>
<rect height='8' id='rect8514-9' rx='1' ry='1' style='opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#2e3436;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal' transform='scale(1,-1)' width='3' x='31.99979' y='-308.00766'/>
</g>
<g id='g3913-3' inkscape:label='auth finger authentication security fingerprint' style='display:inline;enable-background:new' transform='translate(-370.0004,110)'>
<title id='title3926-6'>fingerprint2</title>
<rect height='16' id='rect3893-7' style='fill:none;stroke:none' width='16.000002' x='292.0004' y='368'/>
<ellipse cx='306' cy='379' id='path3915-0' rx='1' ry='1.0000167' style='opacity:1;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:56;stroke-opacity:1'/>
</g>
<g id='g3014' inkscape:label='hearing impairment' transform='translate(-400)'>
<rect height='16' id='rect3005' style='color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:1;marker:none;enable-background:new' transform='scale(-1,1)' width='16' x='-315.99969' y='40.011276'/>
<path inkscape:connector-curvature='0' d='m 306.99939,44.007812 c 1.10457,0 2,0.895431 2,2 0,1.104569 -0.89543,2 -2,2 -1.10457,0 -2,-0.895431 -2,-2 0,-1.104569 0.89543,-2 2,-2 z' id='path3007' sodipodi:nodetypes='sssss' style='fill:#2e3436;fill-opacity:1;stroke:none'/>
<path inkscape:connector-curvature='0' d='m 307.12634,41.009766 c 2.12194,0.05807 3.97747,1.445809 4.63282,3.464843 0.75008,2.34285 -0.31176,4.883664 -2.50586,5.996094 l -0.0371,0.01953 -0.0371,0.01563 c -0.535,0.217 -0.64399,0.417188 -0.83399,0.867188 -0.19,0.45 -0.32673,1.151578 -0.80273,1.892578 -0.775,1.207 -2.11969,1.723094 -3.30469,1.496094 -1.185,-0.227 -2.23828,-1.325906 -2.23828,-2.753907 v -1 c -1e-5,-0.0026 -1e-5,-0.0052 0,-0.0078 0,-0.552285 0.44772,-1 1,-1 0.55228,0 1,0.447715 1,1 10e-6,0.0026 10e-6,0.0052 0,0.0078 v 1 c 0,0.572002 0.23323,0.716063 0.61523,0.789063 0.383,0.073 0.8871,-0.05038 1.2461,-0.609375 0.222,-0.346 0.34958,-0.899797 0.64258,-1.591797 0.293,-0.693 0.88487,-1.521359 1.92187,-1.943359 l -0.0742,0.03516 c 1.32315,-0.662244 1.96265,-2.192894 1.50391,-3.599609 -0.44893,-1.408648 -1.86053,-2.2772 -3.32031,-2.042969 -1.4587,0.224083 -2.53552,1.479263 -2.53516,2.955078 v 0.0078 c -0.004,0.549232 -0.45075,0.992205 -1,0.992188 -0.54925,1.7e-5 -0.99571,-0.442956 -1,-0.992188 V 46.003908 46 c 2.9e-4,-0.03328 0.002,-0.06652 0.006,-0.09961 0.0663,-2.763497 2.35747,-4.951586 5.12109,-4.890625 z' id='path3010' sodipodi:nodetypes='sccccscssccsccscccccccccccccccs' style='fill:#2e3436;fill-opacity:1;stroke:none'/>
</g>
<g id='g3085' inkscape:label='vision impairment' transform='translate(-380,20)'>
<rect height='16' id='rect3072' style='opacity:0.154;vector-effect:none;fill:none;fill-opacity:1;stroke:none;stroke-width:20;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal' width='16' x='360' y='40'/>
<circle cx='366.99786' cy='42.0625' id='circle3077' r='2' style='opacity:1;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1'/>
</g>
</g>
<g inkscape:groupmode='layer' id='layer9' inkscape:label='shapes' style='display:inline' transform='translate(-920.98275,527)'/>
<g inkscape:groupmode='layer' id='g7628' inkscape:label='other' style='display:inline' transform='translate(-920.98275,527)'/>
<g inkscape:groupmode='layer' id='layer19' inkscape:label='multimedia' transform='translate(-679.98255,-40)'/>
<g inkscape:groupmode='layer' id='layer13' inkscape:label='maps' transform='translate(-679.98255,-40)'>
<path d='m 687.5,40 c -4.13029,0 -7.5,3.36971 -7.5,7.5 0,4.13029 3.36971,7.5 7.5,7.5 4.13029,0 7.5,-3.36971 7.5,-7.5 0,-4.13029 -3.36971,-7.5 -7.5,-7.5 z m 0,2 c 0.25596,0 0.50553,0.02324 0.75195,0.05664 0.19059,0.26016 0.38153,0.59041 0.54883,1.02539 0.10643,0.27672 0.20316,0.585037 0.28906,0.917969 h -3.17968 c 0.0859,-0.332926 0.18263,-0.641259 0.28906,-0.917969 0.1673,-0.43498 0.35824,-0.76523 0.54883,-1.02539 C 686.99447,42.023201 687.24404,42 687.5,42 Z m -2.08789,0.408203 c -0.0474,0.10764 -0.10238,0.199793 -0.14649,0.314453 -0.14817,0.385261 -0.27082,0.820362 -0.3789,1.277344 h -1.61914 c 0.57174,-0.691172 1.29967,-1.247212 2.14453,-1.591797 z m 4.17578,0 c 0.84486,0.344585 1.57279,0.900625 2.14453,1.591797 h -1.61914 c -0.10808,-0.456982 -0.23073,-0.892083 -0.3789,-1.277344 -0.0441,-0.11466 -0.0991,-0.206813 -0.14649,-0.314453 z M 682.60352,45 h 2.08398 c -0.097,0.626968 -0.14805,1.300857 -0.16797,2 h -2.48242 c 0.0644,-0.715604 0.25633,-1.391461 0.56641,-2 z m 3.09765,0 h 3.59766 c 0.10288,0.616332 0.15963,1.294445 0.18164,2 h -3.96094 c 0.022,-0.705555 0.0788,-1.383672 0.18164,-2 z m 4.61133,0 h 2.08398 c 0.31008,0.608539 0.50199,1.284396 0.56641,2 h -2.48242 c -0.0199,-0.699143 -0.071,-1.373032 -0.16797,-2 z m -8.27539,3 h 2.48242 c 0.0199,0.699016 0.071,1.373407 0.16797,2 h -2.08398 c -0.31008,-0.608539 -0.50199,-1.284396 -0.56641,-2 z m 3.48242,0 h 3.96094 c -0.022,0.705447 -0.0788,1.38405 -0.18164,2 h -3.59766 c -0.10289,-0.61595 -0.15963,-1.294553 -0.18164,-2 z m 4.96094,0 h 2.48242 c -0.0644,0.715604 -0.25633,1.391461 -0.56641,2 h -2.08398 c 0.097,-0.626593 0.14805,-1.300984 0.16797,-2 z m -7.21289,3 h 1.61914 c 0.10802,0.456194 0.23088,0.890525 0.3789,1.275391 0.0443,0.11525 0.0988,0.208256 0.14649,0.316406 C 684.56725,52.247212 683.83932,51.691172 683.26758,51 Z m 2.64258,0 h 3.17968 c -0.0858,0.332074 -0.18282,0.639787 -0.28906,0.916016 -0.16776,0.43617 -0.35967,0.767003 -0.55078,1.027343 C 688.00419,52.976659 687.75529,53 687.5,53 c -0.25529,0 -0.50419,-0.02344 -0.75,-0.05664 -0.19111,-0.26034 -0.38302,-0.591173 -0.55078,-1.027343 C 686.09298,51.639787 685.99595,51.332074 685.91016,51 Z m 4.20312,0 h 1.61914 c -0.57174,0.691172 -1.29967,1.247212 -2.14453,1.591797 0.0477,-0.10815 0.10215,-0.201156 0.14649,-0.316406 0.14802,-0.384866 0.27088,-0.819197 0.3789,-1.275391 z' id='path832' style='color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate'/>
</g>
<g inkscape:groupmode='layer' id='layer11' inkscape:label='graphics' style='display:inline' transform='translate(-679.98255,160)'/>
<g inkscape:groupmode='layer' id='layer14' inkscape:label='food-drink' transform='translate(-679.98255,-40)'/>
<g inkscape:groupmode='layer' id='g6387' inkscape:label='devices' style='display:inline' transform='translate(-679.98255,160)'/>
<g inkscape:groupmode='layer' id='layer18' inkscape:label='text' transform='translate(-679.98255,-40)'/>
<g inkscape:groupmode='layer' id='layer17' inkscape:label='weather' transform='translate(-679.98255,-40)'/>
<g inkscape:groupmode='layer' id='layer16' inkscape:label='camera' transform='translate(-679.98255,-40)'/>
<g inkscape:groupmode='layer' id='layer10' inkscape:label='body' style='display:inline' transform='translate(-679.98255,160)'/>
<g inkscape:groupmode='layer' id='layer15' inkscape:label='animals' transform='translate(-679.98255,-40)'/>
<g inkscape:groupmode='layer' id='layer12' inkscape:label='alert' transform='translate(-679.98255,160)'/>
<g inkscape:groupmode='layer' id='layer20' inkscape:label='accessibility' transform='translate(-679.98255,-40)'/>
</svg>

After

Width:  |  Height:  |  Size: 88 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 97 KiB

View File

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16"
height="16"
version="1.1"
id="svg10"
sodipodi:docname="mention-symbolic.svg"
inkscape:version="1.0.2 (e86c870879, 2021-01-15)">
<metadata
id="metadata16">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs14" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1016"
id="namedview12"
showgrid="false"
inkscape:zoom="37.432465"
inkscape:cx="4.1468168"
inkscape:cy="9.8841469"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="svg10" />
<g
fill="#474747"
id="g8"
transform="matrix(2.3598344,0,0,2.283804,-9.4385468,-11.405684)">
<path
d="M 7.285,5.004 A 3.506,3.506 0 0 0 4.027,8.94 3.506,3.506 0 0 0 7.515,12 5.68,5.68 0 0 0 9.159,11.724 L 8.843,10.775 c 0,0 -0.706,0.225 -1.331,0.225 H 7.51 A 2.494,2.494 0 0 1 5.02,8.814 2.495,2.495 0 0 1 6.887,6.076 2.797,2.797 0 0 1 8.695,6.24 C 9.221,6.481 9.585,6.87 9.699,7.299 9.823,7.763 9.786,8.269 9.615,8.574 9.517,8.75 9.212,8.928 9,9 V 8.5 C 9,7.677 8.323,7 7.5,7 6.678,7 6,7.677 6,8.5 6,9.322 6.678,10 7.5,10 7.676,10 7.843,9.963 8,9.906 V 9.951 L 8.45,9.998 C 9.391,10.094 10.142,9.681 10.488,9.062 10.835,8.444 10.843,7.705 10.666,7.041 10.458,6.257 9.846,5.669 9.112,5.332 A 3.75,3.75 0 0 0 7.285,5.004 Z M 7.5,8 C 7.782,8 8,8.218 8,8.5 8,8.782 7.782,9 7.5,9 A 0.493,0.493 0 0 1 7,8.5 C 7,8.218 7.218,8 7.5,8 Z"
style="line-height:normal;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;text-transform:none;text-orientation:mixed;shape-padding:0;isolation:auto;mix-blend-mode:normal"
color="#000000"
font-weight="400"
font-family="sans-serif"
overflow="visible"
id="path6" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

0
data/icons/symbolic.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

0
data/meson.build Normal file → Executable file
View File

0
data/screenshot1.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 187 KiB

After

Width:  |  Height:  |  Size: 187 KiB

0
data/screenshot2.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 142 KiB

After

Width:  |  Height:  |  Size: 142 KiB

0
data/screenshot3.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 187 KiB

After

Width:  |  Height:  |  Size: 187 KiB

0
data/screenshot4.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 158 KiB

After

Width:  |  Height:  |  Size: 158 KiB

View File

@ -1,407 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.2 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<requires lib="gtk" version="4.0"/>
<requires lib="libhandy" version="1.0"/>
<template class="TootleDialogsCompose" parent="HdyWindow">
<property name="can_focus">False</property>
<property name="modal">True</property>
<template class="TootleDialogsCompose" parent="AdwWindow">
<property name="modal">1</property>
<property name="default_width">500</property>
<property name="default_height">300</property>
<property name="type_hint">dialog</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="HdyHeaderBar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<object class="AdwHeaderBar" id="header">
<property name="hexpand">1</property>
<property name="show_end_title_buttons">0</property>
<property name="show_start_title_buttons">0</property>
<property name="centering-policy">strict</property>
<child type="title">
<object class="HdyViewSwitcherTitle" id="mode_switcher">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stack">mode</property>
<object class="AdwViewSwitcherTitle" id="title_switcher">
<!-- <property name="title" translatable="yes">Title</property> -->
<!-- <property name="subtitle" translatable="yes">Subtitle</property> -->
</object>
</child>
<child>
<object class="GtkButton" id="commit">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="on_commit" swapped="no"/>
<child>
<object class="GtkStack" id="commit_stack">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="commit_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Publish</property>
</object>
<packing>
<property name="name">ready</property>
</packing>
</child>
<child>
<object class="GtkSpinner">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="active">True</property>
</object>
<packing>
<property name="name">working</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="pack_type">end</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="close">
<property name="label" translatable="yes">Cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<child type="start">
<object class="GtkButton" id="close_button">
<property name="label" translatable="yes">Close</property>
<signal name="clicked" handler="on_close" swapped="no"/>
</object>
<packing>
<property name="position">2</property>
</packing>
</child>
<child type="end">
<object class="GtkButton" id="commit_button">
<property name="label" translatable="yes">Publish</property>
<signal name="clicked" handler="on_commit" swapped="no"/>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkStack" id="mode">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="transition_duration">100</property>
<property name="transition_type">crossfade</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="vexpand">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkRevealer" id="cw_revealer">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkEntry" id="cw">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="margin_left">6</property>
<property name="margin_right">6</property>
<property name="margin_start">6</property>
<property name="margin_end">6</property>
<property name="margin_top">6</property>
<property name="margin_bottom">6</property>
<property name="placeholder_text" translatable="yes">Write your warning here</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkSeparator">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="width_request">350</property>
<property name="height_request">150</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="overlay_scrolling">False</property>
<child>
<object class="GtkTextView" id="content">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="pixels_below_lines">8</property>
<property name="pixels_inside_wrap">8</property>
<property name="wrap_mode">word-char</property>
<property name="left_margin">8</property>
<property name="right_margin">8</property>
<property name="top_margin">8</property>
<property name="bottom_margin">8</property>
<property name="accepts_tab">False</property>
<property name="populate_all">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkActionBar" id="actions">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkMenuButton" id="visibility_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Visibility</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkImage" id="visibility_icon">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_end">6</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkImage" id="image3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">pan-down-symbolic</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<style>
<class name="flat"/>
</style>
</object>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkSeparator">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="attach_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Attach Media</property>
<signal name="clicked" handler="on_select_media" swapped="no"/>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">mail-attachment-symbolic</property>
</object>
</child>
<style>
<class name="image-button"/>
<class name="flat"/>
</style>
</object>
<packing>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="emoji_button">
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">Instance Emojis</property>
<property name="relief">none</property>
<property name="always_show_image">True</property>
<child>
<object class="GtkImage" id="image4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">face-smile-symbolic</property>
</object>
</child>
<style>
<class name="image-button"/>
<class name="flat"/>
</style>
</object>
<packing>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkToggleButton" id="cw_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">Spoiler Warning</property>
<property name="relief">none</property>
<property name="always_show_image">True</property>
<signal name="toggled" handler="validate" swapped="no"/>
<child>
<object class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">dialog-warning-symbolic</property>
</object>
</child>
<style>
<class name="image-button"/>
<class name="flat"/>
</style>
</object>
<packing>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="counter">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label">250</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="name">text</property>
<property name="title" translatable="yes">Text</property>
<property name="icon_name">edit</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<child>
<object class="GtkViewport">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkListBox" id="media_list">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="hexpand">True</property>
<property name="selection_mode">none</property>
<signal name="row-activated" handler="on_media_list_row_activated" swapped="no"/>
<child>
<object class="GtkListBoxRow" id="attach_item">
<property name="height_request">64</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="icon_name">list-add-symbolic</property>
</object>
</child>
</object>
</child>
<style>
<class name="content"/>
</style>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="name">media</property>
<property name="title" translatable="yes">Media</property>
<property name="icon_name">mail-attachment-symbolic</property>
<property name="position">1</property>
</packing>
</child>
<object class="AdwViewStack" id="stack">
<property name="hexpand">1</property>
<property name="vexpand">1</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<style>
<class name="ttl-view"/>
</style>
</object>
</child>
</template>
</interface>

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.36.0 -->
<interface>
<requires lib="gtk+" version="3.22"/>
<template class="TootleDialogsListEditor" parent="HdyWindow">
<requires lib="gtk" version="4.0"/>
<requires lib="gtk" version="4.0"/>
<template class="TootleDialogsListEditor" parent="AdwWindow">
<property name="can_focus">False</property>
<property name="modal">True</property>
<property name="default_width">300</property>
@ -10,94 +10,78 @@
<property name="type_hint">dialog</property>
<child>
<object class="GtkBox">
<property name="visible">0</property>
<property name="width_request">300</property>
<property name="height_request">500</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkHeaderBar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="visible">0</property>
<child type="title">
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="visible">0</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="visible">0</property>
<property name="label" translatable="yes">Name</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="name_entry">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="visible">0</property>
<property name="sensitive">0</property>
<property name="width_chars">20</property>
<signal name="changed" handler="validate" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<child>
<object class="GtkButton" id="cancel_btn">
<property name="visible">0</property>
<property name="label" translatable="yes">Cancel</property>
<property name="width_request">80</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="receives_default">1</property>
<signal name="clicked" handler="on_cancel_clicked" swapped="no"/>
</object>
</child>
<child>
<object class="GtkButton" id="save_btn">
<property name="visible">0</property>
<property name="width_request">80</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="sensitive">0</property>
<property name="receives_default">1</property>
<signal name="clicked" handler="on_save_clicked" swapped="no"/>
<child>
<object class="GtkStack" id="save_btn_stack">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="visible">0</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Save</property>
</object>
<packing>
<object class="GtkStackPage">
<property name="name">done</property>
</packing>
<property name="child">
<object class="GtkLabel">
<property name="visible">0</property>
<property name="label" translatable="yes">Save</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkSpinner">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="active">True</property>
</object>
<packing>
<object class="GtkStackPage">
<property name="name">working</property>
<property name="position">1</property>
</packing>
<property name="child">
<object class="GtkSpinner">
<property name="visible">0</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="active">True</property>
</object>
</property>
</object>
</child>
</object>
</child>
@ -107,18 +91,16 @@
</object>
<packing>
<property name="pack_type">end</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
<child>
<object class="GtkInfoBar" id="infobar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="visible">0</property>
<property name="message_type">error</property>
<property name="show_close_button">True</property>
<property name="revealed">False</property>
<property name="show_close_button">1</property>
<property name="revealed">0</property>
<signal name="response" handler="infobar_response" swapped="no"/>
<child internal-child="action_area">
<object class="GtkButtonBox">
@ -143,29 +125,23 @@
</child>
<child internal-child="content_area">
<object class="GtkBox">
<property name="can_focus">False</property>
<property name="visible">0</property>
<property name="spacing">16</property>
<child>
<placeholder/>
</child>
<child>
<object class="GtkLabel" id="infobar_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="visible">0</property>
<property name="margin_start">6</property>
<property name="margin_end">6</property>
<property name="margin_top">6</property>
<property name="margin_bottom">6</property>
<property name="hexpand">True</property>
<property name="wrap">True</property>
<property name="hexpand">1</property>
<property name="wrap">1</property>
<property name="wrap_mode">word-char</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<placeholder/>
@ -181,16 +157,15 @@
</child>
<child>
<object class="GtkSearchEntry" id="search_entry">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="visible">0</property>
<property name="sensitive">0</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="has_default">1</property>
<property name="margin_start">6</property>
<property name="margin_end">6</property>
<property name="margin_top">6</property>
<property name="margin_bottom">6</property>
<property name="hexpand">True</property>
<property name="hexpand">1</property>
<property name="width_chars">30</property>
<property name="truncate_multiline">True</property>
<property name="caps_lock_warning">False</property>
@ -203,32 +178,28 @@
</child>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="visible">0</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="hscrollbar_policy">never</property>
<child>
<property name="child">
<object class="GtkViewport">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<property name="visible">0</property>
<property name="child">
<object class="GtkListBox" id="listbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="visible">0</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="selection_mode">none</property>
<property name="activate_on_single_click">False</property>
<property name="activate_on_single_click">0</property>
<child type="placeholder">
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="visible">0</property>
<property name="opacity">0.35</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="margin_left">12</property>
<property name="margin_right">12</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="margin_start">12</property>
<property name="margin_end">12</property>
<property name="margin_top">18</property>
@ -237,34 +208,21 @@
<property name="spacing">6</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="visible">0</property>
<property name="pixel_size">48</property>
<property name="icon_name">face-sad-symbolic</property>
<property name="icon_size">0</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="visible">0</property>
<property name="label" translatable="yes">Nobody here</property>
<property name="justify">center</property>
<property name="wrap">True</property>
<property name="wrap">1</property>
<style>
<class name="title-2"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
@ -272,9 +230,9 @@
<class name="frame"/>
</style>
</object>
</child>
</property>
</object>
</child>
</property>
</object>
</child>
</object>

33
data/ui/dialogs/main.ui Normal file → Executable file
View File

@ -1,23 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.2 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<requires lib="libhandy" version="1.0"/>
<template class="TootleDialogsMainWindow" parent="HdyWindow">
<template class="TootleDialogsMainWindow" parent="AdwApplicationWindow">
<property name="width_request">360</property>
<property name="height_request">600</property>
<property name="can_focus">False</property>
<child>
<object class="HdyDeck" id="deck">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can_swipe_back">True</property>
<signal name="notify::transition-running" handler="on_child_transition"/>
<signal name="notify::visible-child" handler="on_child_transition"/>
<child>
<placeholder/>
<object class="AdwFlap" id="flap">
<child type="flap">
<object class="TootleViewsSidebar" id="sidebar">
</object>
</child>
<!-- <child type="separator"> -->
<!-- <object class="GtkSeparator"> -->
<!-- <property name="orientation">vertical</property> -->
<!-- </object> -->
<!-- </child> -->
<child type="content">
<object class="AdwLeaflet" id="leaflet">
<property name="can-swipe-back">1</property>
<property name="can-unfold">0</property>
<property name="hhomogeneous-folded">0</property>
<property name="hhomogeneous-unfolded">1</property>
<signal name="notify::child-transition-running" handler="on_child_transition"/>
<signal name="notify::visible-child" handler="on_view_changed"/>
</object>
</child>
</object>
</child>
</template>
</interface>

386
data/ui/dialogs/new_account.ui Normal file → Executable file
View File

@ -1,356 +1,172 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.2 -->
<interface>
<requires lib="gtk+" version="3.22"/>
<requires lib="libhandy" version="1.0"/>
<template class="TootleDialogsNewAccount" parent="HdyWindow">
<property name="can_focus">False</property>
<requires lib="gtk" version="4.0"/>
<template class="TootleDialogsNewAccount" parent="AdwWindow">
<property name="modal">True</property>
<property name="default_width">700</property>
<property name="default_height">500</property>
<property name="type_hint">dialog</property>
<property name="default_width">600</property>
<property name="default_height">450</property>
<property name="title" translatable="yes">Add Account</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<object class="AdwLeaflet" id="deck">
<property name="can_swipe_back">1</property>
<property name="can_unfold">0</property>
<signal name="notify::visible_child" handler="on_visible_child_notify" swapped="no"/>
<child>
<object class="HdyHeaderBar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="title" translatable="yes">Add Account</property>
<property name="show_close_button">True</property>
<object class="GtkBox" id="instance_step">
<property name="orientation">vertical</property>
<child>
<object class="GtkButton" id="back_button">
<property name="label" translatable="yes">Back</property>
<property name="width_request">80</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="on_back_clicked" swapped="no"/>
</object>
</child>
<child>
<object class="GtkButton" id="next_button">
<property name="width_request">80</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="on_next_clicked" swapped="no"/>
<object class="AdwHeaderBar">
<child>
<object class="GtkStack">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Next</property>
</object>
<packing>
<property name="name">idle</property>
</packing>
</child>
<child>
<object class="GtkSpinner">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
<property name="active">True</property>
</object>
<packing>
<property name="name">spinner</property>
<property name="position">1</property>
</packing>
</child>
<object class="GtkButton">
<property name="label" translatable="yes">Cancel</property>
<signal name="clicked" handler="gtk_window_destroy" swapped="yes"/>
</object>
</child>
<child type="end">
<object class="GtkButton">
<property name="receives_default">1</property>
<property name="label" translatable="yes">Next</property>
<property name="sensitive" bind-source="TootleDialogsNewAccount" bind-property="is_working" bind-flags="sync-create|invert-boolean"/>
<signal name="clicked" handler="on_next_clicked" swapped="no"/>
<style>
<class name="suggested-action"/>
</style>
</object>
</child>
<style>
<class name="suggested-action"/>
</style>
</object>
<packing>
<property name="pack_type">end</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="HdyClamp">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">18</property>
<property name="margin_right">18</property>
<property name="margin_top">18</property>
<property name="margin_bottom">18</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="maximum_size">400</property>
<child>
<object class="GtkStack" id="stack">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
<property name="transition_duration">100</property>
<property name="transition_type">crossfade</property>
<object class="AdwStatusPage">
<property name="vexpand">1</property>
<property name="icon_name">network-server-symbolic</property>
<property name="title" translatable="yes">What is Your Instance?</property>
<child>
<object class="GtkBox" id="instance_step">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">24</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="pixel_size">128</property>
<property name="icon_name">network-server-symbolic</property>
<property name="icon_size">0</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">What is your instance?</property>
<style>
<class name="title-1"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<object class="AdwClamp">
<property name="maximum-size">400</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">24</property>
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkButton">
<property name="label">https://</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="sensitive">0</property>
<property name="receives_default">1</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="instance_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">1</property>
<signal name="activate" handler="on_next_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<style>
<class name="linked"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">&lt;a href="https://joinmastodon.org/"&gt;Don't have one yet?&lt;/a&gt;</property>
<property name="use_markup">True</property>
<property name="track_visited_links">False</property>
<property name="label" translatable="yes">&lt;a href=&quot;https://joinmastodon.org/&quot;&gt;Don&apos;t have one yet?&lt;/a&gt;</property>
<property name="use_markup">1</property>
<property name="xalign">1</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="name">instance</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="code_step">
<property name="orientation">vertical</property>
<child>
<object class="AdwHeaderBar">
<child>
<object class="GtkBox" id="code_step">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
<property name="orientation">vertical</property>
<property name="spacing">24</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="pixel_size">128</property>
<property name="icon_name">dialog-password-symbolic</property>
<property name="icon_size">0</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Enter authorization code</property>
<style>
<class name="title-1"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<object class="GtkButton">
<property name="label" translatable="yes">Previous</property>
<signal name="clicked" handler="on_back_clicked" swapped="no"/>
</object>
</child>
<child type="end">
<object class="GtkButton">
<property name="receives_default">1</property>
<property name="label" translatable="yes">Next</property>
<property name="sensitive" bind-source="TootleDialogsNewAccount" bind-property="is_working" bind-flags="sync-create|invert-boolean"/>
<signal name="clicked" handler="on_next_clicked" swapped="no"/>
<style>
<class name="suggested-action"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="AdwStatusPage">
<property name="vexpand">1</property>
<property name="icon_name">dialog-password-symbolic</property>
<property name="title" translatable="yes">Enter Authorization Code</property>
<child>
<object class="AdwClamp">
<property name="maximum-size">400</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">24</property>
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<child>
<object class="GtkEntry" id="code_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<signal name="activate" handler="on_next_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="code_label">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">&lt;a href="tootle://manual_auth"&gt;Try manual authorization&lt;/a&gt;</property>
<property name="use_markup">True</property>
<property name="track_visited_links">False</property>
<property name="label" translatable="yes">&lt;a href=&quot;tootle://manual_auth&quot;&gt;Try manual authorization&lt;/a&gt;</property>
<property name="use_markup">1</property>
<property name="xalign">1</property>
<signal name="activate-link" handler="on_activate_code_label_link" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="name">code</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="done_step">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
<property name="orientation">vertical</property>
<property name="spacing">24</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="pixel_size">128</property>
<property name="icon_name">emblem-default-symbolic</property>
<property name="icon_size">0</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="hello_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">Hello, @user@instance.com!</property>
<style>
<class name="title-1"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="name">done</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="done_step">
<property name="orientation">vertical</property>
<child>
<object class="AdwHeaderBar">
<child type="end">
<object class="GtkButton">
<property name="receives_default">1</property>
<property name="label" translatable="yes">Done</property>
<property name="sensitive" bind-source="TootleDialogsNewAccount" bind-property="is_working" bind-flags="sync-create|invert-boolean"/>
<signal name="clicked" handler="on_next_clicked" swapped="no"/>
<style>
<class name="suggested-action"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="AdwStatusPage" id="done_page">
<property name="vexpand">1</property>
<property name="icon_name">emblem-default-symbolic</property>
<property name="title">Welcome!</property>
</object>
</child>
</object>
</child>
</object>
</child>

100
data/ui/dialogs/preferences.ui Normal file → Executable file
View File

@ -1,8 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.2 -->
<interface>
<requires lib="gtk+" version="3.22"/>
<requires lib="libhandy" version="0.0"/>
<object class="GtkAdjustment" id="font_adjustment">
<property name="lower">100</property>
<property name="upper">500</property>
@ -15,51 +12,50 @@
<property name="step_increment">1</property>
<property name="page_increment">1</property>
</object>
<template class="TootleDialogsPreferences" parent="HdyPreferencesWindow">
<property name="width_request">300</property>
<property name="can_focus">False</property>
<property name="default_width">500</property>
<property name="default_height">600</property>
<property name="search_enabled">False</property>
<template class="TootleDialogsPreferences" parent="AdwPreferencesWindow">
<child>
<object class="HdyPreferencesPage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<object class="AdwPreferencesPage">
<property name="icon_name">applications-system-symbolic</property>
<property name="title" translatable="yes">General</property>
<child>
<object class="HdyPreferencesGroup">
<property name="visible">True</property>
<property name="can_focus">False</property>
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes">Appearance</property>
<child>
<object class="HdyActionRow">
<property name="visible">True</property>
<property name="can_focus">False</property>
<object class="AdwActionRow">
<property name="title" translatable="yes">Dark theme</property>
<property name="activatable_widget">dark_theme</property>
<child>
<object class="GtkSwitch" id="dark_theme">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can_focus">0</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="HdyActionRow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<object class="AdwActionRow">
<property name="title" translatable="yes">Multiple Columns</property>
<property name="subtitle" translatable="yes">Warning: Expirimental and highly flammable</property>
<property name="activatable_widget">multiple_columns</property>
<property name="sensitive">0</property>
<child>
<object class="GtkSwitch" id="multiple_columns">
<property name="can_focus">0</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="visible">0</property>
<property name="title" translatable="yes">Text scale (%)</property>
<property name="activatable_widget">post_text_size</property>
<child>
<object class="GtkSpinButton" id="post_text_size">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="valign">center</property>
<property name="text" translatable="yes">100</property>
<property name="progress_pulse_step">0.050000000000000003</property>
<property name="climb_rate">0.05</property>
<property name="adjustment">font_adjustment</property>
<property name="value">100</property>
</object>
@ -69,64 +65,45 @@
</object>
</child>
<child>
<object class="HdyPreferencesGroup">
<property name="visible">True</property>
<property name="can_focus">False</property>
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes">Behavior</property>
<property name="sensitive">0</property>
<child>
<object class="HdyActionRow">
<property name="can_focus">False</property>
<object class="AdwActionRow">
<property name="title" translatable="yes">Autostart</property>
<property name="activatable_widget">autostart</property>
<property name="subtitle" translatable="yes">Start minimized at boot</property>
<child>
<object class="GtkSwitch" id="autostart">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can_focus">0</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="HdyActionRow">
<property name="can_focus">False</property>
<object class="AdwActionRow">
<property name="title" translatable="yes">Background work</property>
<property name="activatable_widget">work_in_background</property>
<property name="subtitle" translatable="yes">Receive notifications even when the app is closed</property>
<child>
<object class="GtkSwitch" id="work_in_background">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="HdyComboRow" id="default_post_visibility">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="title" translatable="yes">Default post visibility</property>
</object>
</child>
</object>
</child>
<child>
<object class="HdyPreferencesGroup">
<property name="visible">True</property>
<property name="can_focus">False</property>
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes">Timelines</property>
<child>
<object class="HdyActionRow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<object class="AdwActionRow">
<property name="title" translatable="yes">Posts per page</property>
<property name="activatable_widget">timeline_page_size</property>
<child>
<object class="GtkSpinButton" id="timeline_page_size">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="valign">center</property>
<property name="text" translatable="yes">10</property>
<property name="adjustment">page_adjustment</property>
@ -136,48 +113,39 @@
</object>
</child>
<child>
<object class="HdyActionRow">
<property name="can_focus">True</property>
<object class="AdwActionRow">
<property name="visible">0</property>
<property name="title" translatable="yes">Infinite scrolling</property>
<property name="activatable_widget">infinite_scrolling</property>
<property name="subtitle" translatable="yes">Warning: This will increase memory usage</property>
<child>
<object class="GtkSwitch" id="infinite_scrolling">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="HdyActionRow" id="live_updates_row">
<property name="visible">True</property>
<property name="can_focus">True</property>
<object class="AdwActionRow" id="live_updates_row">
<property name="title" translatable="yes">Stream timelines</property>
<property name="activatable_widget">live_updates</property>
<property name="subtitle" translatable="yes">Receive new posts and notifications in real-time</property>
<child>
<object class="GtkSwitch" id="live_updates">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="HdyActionRow">
<property name="visible">True</property>
<property name="sensitive" bind-source="live_updates" bind-property="state" bind-flags="sync-create">False</property>
<object class="AdwActionRow">
<property name="sensitive" bind-source="live_updates" bind-property="state" bind-flags="sync-create"/>
<property name="can_focus">True</property>
<property name="title" translatable="yes">Stream public timelines</property>
<property name="activatable_widget">public_live_updates</property>
<property name="subtitle" translatable="yes">Warning: This will increase memory usage</property>
<child>
<object class="GtkSwitch" id="public_live_updates">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="valign">center</property>
</object>
</child>

113
data/ui/menus.ui Normal file → Executable file
View File

@ -4,6 +4,61 @@
<menu id="profile-menu">
<section>
<attribute name="display-hint">circular-buttons</attribute>
<!-- <attribute name="label" translatable="yes">Interaction</attribute> -->
<item>
<attribute name="label" translatable="yes">Mention…</attribute>
<attribute name="action">view.mention</attribute>
<attribute name="target">public</attribute>
<attribute name="verb-icon">mention-symbolic</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Direct Message…</attribute>
<attribute name="action">view.mention</attribute>
<attribute name="target">direct</attribute>
<attribute name="verb-icon">mail-unread-symbolic</attribute>
</item>
<!-- <item> -->
<!-- <attribute name="label" translatable="yes">Copy Handle</attribute> -->
<!-- <attribute name="action">view.copy_handle</attribute> -->
<!-- <attribute name="verb-icon">emblem-shared-symbolic</attribute> -->
<!-- </item> -->
</section>
<section>
<!-- <submenu> -->
<attribute name="label" translatable="yes">Moderation</attribute>
<item>
<attribute name="label" translatable="yes">Hide Boosts</attribute>
<attribute name="action">view.hiding_reblogs</attribute>
<!-- <attribute name="hidden-when">action-disabled</attribute> -->
</item>
<item>
<attribute name="label" translatable="yes">Mute</attribute>
<attribute name="action">view.muting</attribute>
</item>
<section>
<item>
<attribute name="label" translatable="yes">Report</attribute>
<attribute name="action">view.report</attribute>
<!-- TODO: Reporting users -->
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Block</attribute>
<attribute name="action">view.blocking</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Block Domain</attribute>
<attribute name="action">view.domain_blocking</attribute>
<!-- <attribute name="hidden-when">action-disabled</attribute> -->
</item>
</section>
<!-- </submenu> -->
</section>
<section>
<attribute name="label" translatable="yes">Timeline</attribute>
<submenu id="profile-filter-menu">
<attribute name="label" translatable="yes">Filter</attribute>
<item>
@ -36,55 +91,25 @@
</section>
</submenu>
</section>
<section>
<item>
<attribute name="label" translatable="yes">Mention…</attribute>
<attribute name="action">view.mention</attribute>
<attribute name="target">public</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Direct Message…</attribute>
<attribute name="action">view.mention</attribute>
<attribute name="target">direct</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Copy Handle</attribute>
<attribute name="action">view.copy_handle</attribute>
</item>
</section>
<section>
<!-- <submenu> -->
<!-- <attribute name="label" translatable="yes">Moderation</attribute> -->
<!-- <section> -->
<submenu id="copy-menu">
<attribute name="label" translatable="yes">Copy</attribute>
<item>
<attribute name="label" translatable="yes">Hide Boosts</attribute>
<attribute name="action">view.hiding_reblogs</attribute>
<attribute name="hidden-when">action-disabled</attribute>
<attribute name="label" translatable="yes">Profile Handle</attribute>
<attribute name="action">view.copy_handle</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Mute</attribute>
<attribute name="action">view.muting</attribute>
<attribute name="label" translatable="yes">Profile Link</attribute>
<attribute name="action">view.copy_handle</attribute>
</item>
<section>
<item>
<attribute name="label" translatable="yes">Report</attribute>
<attribute name="action">view.report</attribute>
<!-- TODO: Reporting users -->
<attribute name="hidden-when">action-missing</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Block</attribute>
<attribute name="action">view.blocking</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Block Domain</attribute>
<attribute name="action">view.domain_blocking</attribute>
<attribute name="hidden-when">action-disabled</attribute>
</item>
</section>
<!-- </submenu> -->
</submenu>
<!-- </section> -->
<item>
<attribute name="label" translatable="yes">Refresh</attribute>
<attribute name="action">app.refresh</attribute>
</item>
</section>
</menu>

255
data/ui/views/base.ui Normal file → Executable file
View File

@ -1,220 +1,137 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.2 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<requires lib="libhandy" version="1.0"/>
<object class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">go-previous-symbolic</property>
</object>
<requires lib="gtk" version="4.0"/>
<requires lib="libadwaita" version="1.0"/>
<template class="TootleViewsBase" parent="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<signal name="size-allocate" handler="on_resized" swapped="no"/>
<child>
<object class="HdyHeaderBar" id="header">
<object class="AdwHeaderBar" id="header">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="show_close_button">True</property>
<property name="hexpand">True</property>
<property name="centering-policy">strict</property>
<child>
<object class="GtkButton" id="back_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Back</property>
<property name="image">image1</property>
<property name="icon_name">go-previous-symbolic</property>
<signal name="clicked" handler="on_close" swapped="no"/>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolled">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="vexpand">1</property>
<property name="hscrollbar_policy">never</property>
<child>
<property name="child">
<object class="GtkViewport">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="shadow_type">none</property>
<child>
<property name="child">
<object class="GtkBox" id="view">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="HdyClamp" id="clamp">
<object class="AdwClamp" id="clamp">
<property name="vexpand">1</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="maximum_size">650</property>
<property name="tightening_threshold">650</property>
<child>
<object class="GtkBox" id="column_view">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkStack" id="states">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="vhomogeneous">False</property>
<property name="vexpand">1</property>
<property name="vhomogeneous">0</property>
<property name="transition_type">crossfade</property>
<property name="interpolate_size">True</property>
<property name="interpolate_size">1</property>
<child>
<object class="GtkBox" id="status">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
<property name="margin_top">16</property>
<property name="margin_bottom">16</property>
<property name="orientation">vertical</property>
<property name="spacing">16</property>
<child>
<object class="GtkImage">
<property name="width_request">128</property>
<property name="height_request">128</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="pixel_size">128</property>
<property name="icon_name">com.github.bleakgrey.tootle-symbolic</property>
<property name="icon_size">0</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkStack" id="status_stack">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="transition_type">crossfade</property>
<child>
<object class="GtkLabel" id="status_message_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="name">message</property>
</packing>
</child>
<child>
<object class="GtkSpinner" id="status_spinner">
<property name="height_request">32</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">False</property>
<property name="active">True</property>
</object>
<packing>
<property name="name">spinner</property>
<property name="position">1</property>
</packing>
</child>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="status_button">
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="no_show_all">True</property>
<property name="halign">center</property>
<property name="relief">none</property>
<style>
<class name="flat"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<object class="GtkStackPage">
<property name="name">status</property>
<property name="title">page1</property>
</packing>
<property name="child">
<object class="GtkBox" id="status">
<property name="valign">center</property>
<property name="margin_top">16</property>
<property name="margin_bottom">16</property>
<property name="orientation">vertical</property>
<property name="spacing">16</property>
<child>
<object class="GtkImage">
<property name="width_request">128</property>
<property name="height_request">128</property>
<property name="pixel_size">128</property>
<property name="icon_name">com.github.bleakgrey.tootle-symbolic</property>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
<child>
<object class="GtkStack" id="status_stack">
<property name="transition_type">crossfade</property>
<child>
<object class="GtkStackPage">
<property name="name">message</property>
<property name="child">
<object class="GtkLabel" id="status_message_label">
<property name="use_markup">1</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">spinner</property>
<property name="child">
<object class="GtkSpinner" id="status_spinner">
<property name="height_request">32</property>
<property name="spinning">True</property>
</object>
</property>
</object>
</child>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
<child>
<object class="GtkButton" id="status_button">
<property name="visible">0</property>
<property name="halign">center</property>
<style>
<class name="flat"/>
</style>
</object>
</child>
</object>
</property>
</object>
</child>
<child>
<object class="GtkBox" id="content_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkListBox" id="content_list">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="selection_mode">none</property>
<style>
<class name="content"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<object class="GtkStackPage">
<property name="name">content</property>
<property name="title">page0</property>
<property name="position">1</property>
</packing>
<property name="child">
<object class="GtkBox" id="content_box">
<property name="orientation">vertical</property>
</object>
</property>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">1</property>
</packing>
</child>
<style>
<class name="ttl-view"/>
</style>
</object>
</child>
</property>
</object>
</child>
</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">1</property>
</packing>
</child>
</template>
</interface>

2
data/ui/views/new_account.ui Normal file → Executable file
View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<requires lib="gtk+" version="4.0"/>
<object class="GtkGrid" id="wizard">
<property name="width_request">350</property>
<property name="height_request">400</property>

232
data/ui/views/profile_header.ui Normal file → Executable file
View File

@ -1,134 +1,128 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.2 -->
<interface>
<requires lib="gtk+" version="3.14"/>
<object class="GtkGrid" id="grid">
<property name="width_request">400</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<requires lib="gtk" version="4.0"/>
<template class="TootleViewsProfileCover" parent="GtkBox">
<property name="margin_bottom">16</property>
<property name="row_spacing">8</property>
<property name="column_spacing">8</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkListBox" id="profile_list">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="selection_mode">none</property>
<property name="activate_on_single_click">False</property>
<child>
<object class="GtkListBoxRow">
<property name="width_request">100</property>
<property name="height_request">80</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="activatable">False</property>
<property name="selectable">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">8</property>
<property name="margin_right">8</property>
<property name="margin_top">8</property>
<property name="margin_bottom">8</property>
<property name="spacing">8</property>
<child>
<object class="TootleWidgetsAvatar" id="avatar">
<property name="visible">True</property>
<property name="margin_top">8</property>
<property name="margin_bottom">8</property>
<property name="margin_left">8</property>
<property name="margin_right">8</property>
<property name="size">96</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
<property name="margin_top">8</property>
<property name="margin_bottom">8</property>
<property name="orientation">vertical</property>
<property name="spacing">8</property>
<child>
<object class="TootleWidgetsRichLabel" id="handle">
<property name="visible">True</property>
<property name="selectable">True</property>
<style>
<class name="title-1"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="TootleWidgetsRichLabel" id="relationship">
<property name="visible">False</property>
<property name="opacity">0.5</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow" id="note_row">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="activatable">False</property>
<property name="selectable">False</property>
<child>
<object class="TootleWidgetsMarkupView" id="note">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">8</property>
<property name="margin_right">8</property>
<property name="margin_top">8</property>
<property name="margin_bottom">8</property>
<property name="selectable">True</property>
</object>
</child>
</object>
</child>
<object class="GtkListBox" id="info">
<property name="selection_mode">none</property>
<property name="activate_on_single_click">0</property>
<style>
<class name="content"/>
</style>
<child>
<object class="GtkListBoxRow">
<child>
<object class="GtkGrid">
<property name="row_homogeneous">0</property>
<child>
<object class="TootleWidgetsBackground" id="background">
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="height-request">224</property>
<property name="margin-bottom">50</property>
<layout>
<property name="column">0</property>
<property name="column-span">2</property>
<property name="row">0</property>
<property name="row-span">1</property>
</layout>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<placeholder/>
<object class="TootleWidgetsAvatar" id="avatar">
<property name="halign">start</property>
<property name="valign">end</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="size">100</property>
<layout>
<property name="column">0</property>
<property name="row">0</property>
<property name="row-span">1</property>
</layout>
</object>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
<object class="GtkBox">
<property name="margin_top">6</property>
<property name="margin_bottom">12</property>
<property name="margin_start">12</property>
<property name="margin_end">12</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="TootleWidgetsRichLabel" id="display_name">
<property name="label">Unknown</property>
<style>
<class name="title-3"/>
</style>
</object>
</child>
<child>
<object class="GtkLabel" id="handle">
<property name="label">@unknown@no.where</property>
<property name="xalign">0</property>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
<child>
<object class="TootleWidgetsMarkupView" id="note">
<property name="margin_top">6</property>
</object>
</child>
<!-- <child> -->
<!-- <object class="GtkLabel" id="rs-box"> -->
<!-- <property name="label">Follows you</property> -->
<!-- <property name="xalign">0</property> -->
<!-- <property name="halign">start</property> -->
<!-- <style> -->
<!-- <class name="badge"/> -->
<!-- <class name="osd"/> -->
<!-- </style> -->
<!-- </object> -->
<!-- </child> -->
<layout>
<property name="column">0</property>
<property name="row">4</property>
<property name="row-span">1</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
</object>
</child>
</object>
</child>
<!-- <child> -->
<!-- <object class="GtkListBoxRow"> -->
<!-- <child> -->
<!-- <object class="GtkListBox" id="field_list"> -->
<!-- <style> -->
<!-- <class name="content"/> -->
<!-- </style> -->
<!-- </object> -->
<!-- </child> -->
<!-- </object> -->
<!-- </child> -->
</object>
</child>
<style>
<class name="ttl-profile-cover"/>
</style>
</template>
</interface>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="TootleViewsSidebarAccountRow" parent="AdwActionRow">
<property name="height_request">76</property>
<property name="title_lines">2</property>
<property name="activatable">1</property>
<child type="prefix">
<object class="TootleWidgetsAvatar" id="avatar">
<property name="size">32</property>
</object>
</child>
<child type="suffix">
<object class="GtkButton" id="forget">
<property name="icon-name">user-trash-symbolic</property>
<property name="valign">center</property>
<signal name="clicked" handler="on_forget" swapped="no"/>
<style>
<class name="circular"/>
</style>
</object>
</child>
</template>
</interface>

39
data/ui/views/sidebar/item.ui Executable file
View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="TootleViewsSidebarItemRow" parent="GtkListBoxRow">
<property name="activatable">1</property>
<child>
<object class="GtkBox">
<property name="orientation">horizontal</property>
<property name="spacing">6</property>
<child>
<object class="GtkImage" id="icon">
<property name="icon_name">horizontal</property>
</object>
</child>
<child>
<object class="GtkLabel" id="label">
<property name="label">Label</property>
<property name="xalign">0</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkLabel" id="badge">
<property name="label">0</property>
<property name="xalign">1</property>
<property name="valign">center</property>
<style>
<class name="badge"/>
</style>
</object>
</child>
</object>
</child>
</template>
</interface>

130
data/ui/views/sidebar/view.ui Executable file
View File

@ -0,0 +1,130 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="TootleViewsSidebar" parent="GtkBox">
<property name="width_request">300</property>
<property name="orientation">vertical</property>
<child>
<object class="AdwHeaderBar">
<property name="show-start-title-buttons">0</property>
<property name="show-end-title-buttons">0</property>
<child type="start">
<object class="GtkButton" id="compose_button">
<property name="icon-name">document-edit-symbolic</property>
<property name="action-name">app.compose</property>
</object>
</child>
<child type="end">
<object class="GtkToggleButton" id="accounts_button">
<property name="icon-name">system-switch-user-symbolic</property>
<signal name="toggled" handler="on_mode_changed"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="vexpand">1</property>
<property name="child">
<object class="GtkViewport">
<child>
<object class="GtkStack" id="mode">
<property name="transition_type">crossfade</property>
<!-- Account actions -->
<child>
<object class="GtkStackPage">
<property name="name">items</property>
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<!-- Header -->
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="margin-top">12</property>
<property name="margin-bottom">12</property>
<property name="spacing">6</property>
<child>
<object class="TootleWidgetsAvatar" id="avatar">
<property name="size">64</property>
<property name="halign">start</property>
<property name="margin-bottom">6</property>
</object>
</child>
<child>
<object class="GtkLabel" id="title">
<property name="label">Account Name</property>
<property name="xalign">0</property>
<style>
<class name="title-2"/>
</style>
</object>
</child>
<child>
<object class="GtkLabel" id="subtitle">
<property name="label">Handle</property>
<property name="xalign">0</property>
<style>
<class name="body"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="GtkSeparator">
</object>
</child>
<child>
<object class="GtkListBox" id="items">
<property name="selection_mode">none</property>
<signal name="row_activated" handler="on_item_activated"/>
<style>
<class name="navigation-sidebar"/>
</style>
</object>
</child>
</object>
</property>
</object>
</child>
<!-- Active account menu -->
<child><object class="GtkStackPage"><property name="name">saved_accounts</property><property name="child">
<object class="GtkListBox" id="saved_accounts">
<property name="selection_mode">single</property>
<signal name="row_activated" handler="on_account_activated"/>
<style>
<class name="navigation-sidebar"/>
</style>
</object>
</property>
</object></child>
</object>
</child>
</object>
</property>
</object>
</child>
<style>
<class name="sidebar"/>
</style>
</template>
</interface>

View File

@ -1,484 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.2 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkPopover" id="popover">
<property name="can_focus">False</property>
<child>
<object class="GtkStack" id="stack">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hhomogeneous">False</property>
<property name="vhomogeneous">False</property>
<property name="transition_type">slide-left-right</property>
<property name="interpolate_size">True</property>
<child>
<object class="GtkBox">
<property name="width_request">275</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">12</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child>
<object class="GtkModelButton" id="item_accounts">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="text"> &lt;b&gt;&lt;span size="large"&gt;No account&lt;/span&gt;&lt;/b&gt;</property>
<property name="use_markup">True</property>
<property name="menu_name">accounts</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<object class="GtkFlowBox" id="actions">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">12</property>
<property name="margin_bottom">6</property>
<property name="homogeneous">True</property>
<property name="column_spacing">6</property>
<property name="row_spacing">6</property>
<property name="min_children_per_line">4</property>
<property name="max_children_per_line">4</property>
<property name="selection_mode">none</property>
<property name="activate_on_single_click">False</property>
<child>
<object class="GtkFlowBoxChild">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<child>
<object class="GtkButton" id="item_conversations">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Conversations</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkImage">
<property name="width_request">32</property>
<property name="height_request">32</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">user-invisible-symbolic</property>
</object>
</child>
<style>
<class name="circular"/>
<class name="image-button"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="GtkFlowBoxChild">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkButton" id="item_favs">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Favorites</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkImage">
<property name="width_request">32</property>
<property name="height_request">32</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">non-starred-symbolic</property>
</object>
</child>
<style>
<class name="circular"/>
<class name="image-button"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="GtkFlowBoxChild">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkButton" id="item_bookmarks">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Bookmarks</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkImage">
<property name="width_request">32</property>
<property name="height_request">32</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">user-bookmarks-symbolic</property>
</object>
</child>
<style>
<class name="circular"/>
<class name="image-button"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="GtkFlowBoxChild">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<child>
<object class="GtkButton" id="item_lists">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Lists</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkImage">
<property name="width_request">32</property>
<property name="height_request">32</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">view-list-symbolic</property>
</object>
</child>
<style>
<class name="circular"/>
<class name="image-button"/>
</style>
</object>
</child>
</object>
</child>
<style>
<class name="ttl-action-bar"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkFlowBox">
<property name="can_focus">False</property>
<property name="homogeneous">True</property>
<property name="column_spacing">6</property>
<property name="min_children_per_line">3</property>
<property name="max_children_per_line">3</property>
<property name="selection_mode">none</property>
<property name="activate_on_single_click">False</property>
<child>
<object class="GtkFlowBoxChild">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">POSTS</property>
<style>
<class name="caption"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">1K</property>
<style>
<class name="title-4"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkFlowBoxChild">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">FOLLOWING</property>
<style>
<class name="caption"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">64</property>
<style>
<class name="title-4"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkFlowBoxChild">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">FOLLOWERS</property>
<style>
<class name="caption"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">24</property>
<style>
<class name="title-4"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkSeparator">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_bottom">4</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkModelButton" id="item_refresh">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="text" translatable="yes">Refresh</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">5</property>
</packing>
</child>
<child>
<object class="GtkModelButton" id="item_prefs">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="text" translatable="yes">Preferences</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">6</property>
</packing>
</child>
<child>
<object class="GtkModelButton" id="item_about">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="action_name">app.about</property>
<property name="text" translatable="yes">About</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">7</property>
</packing>
</child>
</object>
<packing>
<property name="name">menu</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="width_request">350</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">12</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkModelButton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="text" translatable="yes">Accounts</property>
<property name="menu_name">menu</property>
<property name="inverted">True</property>
<property name="centered">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="vexpand">True</property>
<property name="max_content_height">300</property>
<property name="propagate_natural_height">True</property>
<child>
<object class="GtkViewport">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkListBox" id="account_list">
<property name="visible">True</property>
<property name="can_focus">False</property>
<style>
<class name="content"/>
</style>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="name">accounts</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<style>
<class name="ttl-view"/>
</style>
</object>
<template class="TootleWidgetsAccountsButton" parent="GtkMenuButton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="popover">popover</property>
<child>
<object class="GtkOverlay">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="TootleWidgetsAvatar" id="avatar">
<property name="visible">True</property>
<property name="size">24</property>
<property name="valign">center</property>
</object>
<packing>
<property name="pass_through">True</property>
<property name="index">-1</property>
</packing>
</child>
<child type="overlay">
<object class="GtkSpinner" id="spinner">
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="active">True</property>
</object>
<packing>
<property name="pass_through">True</property>
<property name="index">-1</property>
</packing>
</child>
</object>
</child>
</template>
</interface>

0
data/ui/widgets/accounts_button_item.ui Normal file → Executable file
View File

View File

@ -1,59 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.2 -->
<interface>
<requires lib="gtk+" version="3.14"/>
<requires lib="libhandy" version="0.0"/>
<object class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">hjghjg</property>
</object>
<object class="GtkImage" id="image2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-missing-image</property>
</object>
<template class="TootleWidgetsAdaptiveButton" parent="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<child>
<object class="HdySqueezer">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkButton" id="full">
<property name="label">Follow</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="image">image1</property>
<property name="always_show_image">True</property>
<style>
<class name="image-button"/>
<class name="text-button"/>
</style>
</object>
</child>
<child>
<object class="GtkButton" id="mini">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="halign">end</property>
<property name="image">image2</property>
<property name="always_show_image">True</property>
<style>
<class name="image-button"/>
</style>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</template>
</interface>

View File

@ -1,112 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.2 -->
<interface>
<requires lib="gtk+" version="3.22"/>
<template class="TootleWidgetsAttachmentSlot" parent="GtkFlowBoxChild">
<property name="height_request">180</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<child>
<object class="GtkButton" id="button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="on_clicked" swapped="no"/>
<child>
<object class="GtkGrid" id="overlay">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<child>
<object class="GtkImage" id="play_icon">
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="margin_left">16</property>
<property name="margin_right">16</property>
<property name="margin_start">16</property>
<property name="margin_end">16</property>
<property name="margin_top">16</property>
<property name="margin_bottom">16</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="pixel_size">48</property>
<property name="icon_name">media-playback-start-symbolic</property>
<property name="icon_size">0</property>
<style>
<class name="chip"/>
<class name="osd"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="chip">
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="valign">start</property>
<property name="margin_left">6</property>
<property name="margin_right">6</property>
<property name="margin_start">6</property>
<property name="margin_end">6</property>
<property name="margin_top">6</property>
<property name="margin_bottom">6</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<style>
<class name="osd"/>
<class name="chip"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkStack" id="stack">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="transition_type">crossfade</property>
<property name="interpolate_size">True</property>
<child>
<object class="GtkSpinner" id="loading">
<property name="width_request">32</property>
<property name="height_request">32</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="opacity">0.50196078431372548</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="active">True</property>
</object>
<packing>
<property name="name">loading</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
</object>
</child>
<style>
<class name="flat"/>
<class name="ttl-flat-button"/>
</style>
</object>
</child>
<style>
<class name="attachment"/>
</style>
</template>
</interface>

0
data/ui/widgets/compose_attachment.ui Normal file → Executable file
View File

View File

@ -1,15 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.36.0 -->
<interface>
<requires lib="gtk+" version="3.22"/>
<requires lib="gtk" version="4.0"/>
<template class="TootleDialogsListEditorItem" parent="GtkListBoxRow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="activatable">False</property>
<child>
<property name="activatable">0</property>
<property name="child">
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="visible">0</property>
<property name="margin_start">8</property>
<property name="margin_end">8</property>
<property name="margin_top">8</property>
@ -25,13 +21,13 @@
<property name="ellipsize">end</property>
<property name="xalign">0</property>
<attributes>
<attribute name="weight" value="bold"/>
<attribute name="weight" value="bold"></attribute>
</attributes>
<layout>
<property name="column">0</property>
<property name="row">0</property>
</layout>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="TootleWidgetsRichLabel" id="handle">
@ -40,39 +36,37 @@
<property name="hexpand">True</property>
<property name="label">@handle</property>
<property name="xalign">0</property>
<layout>
<property name="column">0</property>
<property name="row">1</property>
</layout>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkToggleButton" id="status">
<property name="visible">0</property>
<property name="width_request">32</property>
<property name="height_request">32</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="sensitive">0</property>
<property name="receives_default">1</property>
<signal name="toggled" handler="on_toggled" swapped="no"/>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="visible">0</property>
<property name="icon_name">object-select-symbolic</property>
</object>
</child>
<style>
<class name="flat"/>
</style>
<layout>
<property name="column">1</property>
<property name="row">0</property>
<property name="row-span">2</property>
</layout>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
<property name="height">2</property>
</packing>
</child>
</object>
</child>
</property>
</template>
</interface>

View File

@ -1,120 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.36.0 -->
<interface>
<requires lib="gtk+" version="3.22"/>
<requires lib="gtk" version="4.0"/>
<template class="TootleViewsListsRow" parent="GtkListBoxRow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="selectable">False</property>
<child>
<property name="selectable">0</property>
<property name="child">
<object class="GtkStack" id="stack">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_start">6</property>
<property name="margin_end">6</property>
<property name="margin_top">6</property>
<property name="margin_bottom">6</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="title">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Untitled</property>
<property name="wrap">True</property>
<property name="wrap_mode">word-char</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="edit_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Edit</property>
<property name="relief">none</property>
<signal name="clicked" handler="on_edit_clicked" swapped="no"/>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">6</property>
<property name="margin_right">6</property>
<property name="margin_start">6</property>
<property name="margin_end">6</property>
<property name="margin_top">6</property>
<property name="margin_bottom">6</property>
<property name="icon_name">document-edit-symbolic</property>
</object>
</child>
<style>
<class name="image-button"/>
<class name="flat"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="remove_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Delete</property>
<property name="relief">none</property>
<signal name="clicked" handler="on_remove_clicked" swapped="no"/>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">6</property>
<property name="margin_right">6</property>
<property name="margin_start">6</property>
<property name="margin_end">6</property>
<property name="margin_top">6</property>
<property name="margin_bottom">6</property>
<property name="icon_name">user-trash-symbolic</property>
</object>
</child>
<style>
<class name="image-button"/>
<class name="flat"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<object class="GtkStackPage">
<property name="name">item</property>
</packing>
<property name="child">
<object class="GtkBox">
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="title">
<property name="hexpand">1</property>
<property name="label" translatable="yes">Untitled</property>
<property name="wrap">1</property>
<property name="wrap_mode">word-char</property>
<property name="xalign">0</property>
</object>
</child>
<child>
<object class="GtkButton" id="edit_button">
<property name="receives_default">1</property>
<property name="tooltip_text" translatable="yes">Edit</property>
<signal name="clicked" handler="on_edit_clicked" swapped="no"/>
<child>
<object class="GtkImage">
<property name="margin-start">6</property>
<property name="margin-end">6</property>
<property name="margin_start">6</property>
<property name="margin_end">6</property>
<property name="margin_top">6</property>
<property name="margin_bottom">6</property>
<property name="icon_name">document-edit-symbolic</property>
</object>
</child>
<style>
<class name="image-button"/>
<class name="flat"/>
</style>
</object>
</child>
<child>
<object class="GtkButton" id="remove_button">
<property name="receives_default">1</property>
<property name="tooltip_text" translatable="yes">Delete</property>
<signal name="clicked" handler="on_remove_clicked" swapped="no"/>
<child>
<object class="GtkImage">
<property name="margin-start">6</property>
<property name="margin-end">6</property>
<property name="margin_start">6</property>
<property name="margin_end">6</property>
<property name="margin_top">6</property>
<property name="margin_bottom">6</property>
<property name="icon_name">user-trash-symbolic</property>
</object>
</child>
<style>
<class name="image-button"/>
<class name="flat"/>
</style>
</object>
</child>
</object>
</property>
</object>
</child>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">list-add-symbolic</property>
</object>
<packing>
<object class="GtkStackPage">
<property name="name">add</property>
<property name="position">1</property>
</packing>
<property name="child">
<object class="GtkImage">
<property name="icon_name">list-add-symbolic</property>
</object>
</property>
</object>
</child>
</object>
</child>
</property>
</template>
</interface>

0
data/ui/widgets/profile_field_row.ui Normal file → Executable file
View File

448
data/ui/widgets/status.ui Normal file → Executable file
View File

@ -1,78 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.2 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">user-bookmarks-symbolic</property>
</object>
<object class="GtkImage" id="image2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">non-starred-symbolic</property>
</object>
<object class="GtkImage" id="reblog_icon">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">media-playlist-repeat-symbolic</property>
</object>
<object class="GtkImage" id="reply_button_icon">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">mail-reply-sender-symbolic</property>
</object>
<requires lib="gtk" version="4.0"/>
<template class="TootleWidgetsStatus" parent="GtkListBoxRow">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<property name="can_focus">0</property>
<property name="child">
<object class="GtkGrid" id="grid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">8</property>
<property name="margin_right">8</property>
<property name="can_focus">0</property>
<property name="margin-start">8</property>
<property name="margin-end">8</property>
<property name="margin_top">8</property>
<property name="margin_bottom">8</property>
<property name="hexpand">True</property>
<property name="hexpand">1</property>
<property name="orientation">vertical</property>
<property name="column_spacing">8</property>
<child>
<object class="GtkImage" id="header_icon">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="visible">0</property>
<property name="halign">end</property>
<property name="margin_bottom">8</property>
<property name="icon_name">oops</property>
<property name="icon_size">1</property>
<layout>
<property name="column">0</property>
<property name="row">0</property>
</layout>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="TootleWidgetsRichLabel" id="header_label">
<property name="visible">True</property>
<property name="visible">0</property>
<property name="ellipsize">end</property>
<property name="xalign">0</property>
<property name="margin-bottom">8</property>
<property name="track_visited_links">false</property>
<property name="markup">trust</property>
<style>
<class name="title-4"/>
</style>
<layout>
<property name="column">1</property>
<property name="row">0</property>
</layout>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="vexpand">True</property>
<property name="row_homogeneous">True</property>
<property name="can_focus">0</property>
<property name="vexpand">1</property>
<property name="row_homogeneous">1</property>
<child>
<object class="TootleWidgetsRichLabel" id="name_label">
<property name="visible">True</property>
@ -84,70 +56,59 @@
<style>
<class name="title-4"/>
</style>
<layout>
<property name="column">0</property>
<property name="row">0</property>
<property name="column-span">3</property>
</layout>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="handle_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can_focus">0</property>
<property name="label" translatable="no">Handle</property>
<property name="opacity">0.5</property>
<property name="ellipsize">end</property>
<property name="single_line_mode">True</property>
<property name="single_line_mode">1</property>
<property name="xalign">0</property>
<style>
<class name="body"/>
</style>
<layout>
<property name="column">0</property>
<property name="row">1</property>
<property name="column-span">4</property>
</layout>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">4</property>
</packing>
</child>
<child>
<object class="GtkBox" id="indicators">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can_focus">0</property>
<property name="halign">end</property>
<property name="valign">start</property>
<property name="margin_start">8</property>
<property name="spacing">8</property>
<property name="margin_start">6</property>
<property name="spacing">6</property>
<child>
<object class="GtkImage" id="pin_indicator">
<property name="can_focus">False</property>
<property name="visible">0</property>
<property name="can_focus">0</property>
<property name="opacity">0.5</property>
<property name="icon_name">view-pin-symbolic</property>
<property name="icon_size">1</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkImage" id="indicator">
<property name="can_focus">False</property>
<property name="visible">0</property>
<property name="can_focus">0</property>
<property name="opacity">0.5</property>
<property name="icon_name">unknown</property>
<property name="icon_size">1</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="date_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can_focus">0</property>
<property name="label" translatable="no">Yesterday</property>
<property name="opacity">0.5</property>
<property name="xalign">0</property>
@ -155,283 +116,136 @@
<class name="body"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<layout>
<property name="column">2</property>
<property name="row">0</property>
<property name="column-span">2</property>
</layout>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">0</property>
<property name="width">2</property>
</packing>
</child>
<layout>
<property name="column">1</property>
<property name="row">1</property>
</layout>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="content_column">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">8</property>
<property name="can_focus">0</property>
<property name="margin_top">6</property>
<property name="orientation">vertical</property>
<property name="spacing">8</property>
<property name="spacing">6</property>
<child>
<object class="GtkStack" id="spoiler_stack">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="vhomogeneous">False</property>
<property name="can_focus">0</property>
<property name="vhomogeneous">0</property>
<property name="transition_type">crossfade</property>
<property name="interpolate_size">True</property>
<property name="interpolate_size">1</property>
<child>
<object class="GtkButton" id="spoiler_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="toggle_spoiler" swapped="no"/>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">12</property>
<property name="margin_right">12</property>
<property name="margin_top">12</property>
<property name="margin_bottom">12</property>
<object class="GtkStackPage">
<property name="name">spoiler</property>
<property name="child">
<object class="GtkButton" id="spoiler_button">
<property name="receives_default">1</property>
<signal name="clicked" handler="toggle_spoiler" swapped="no"/>
<child>
<object class="GtkBox">
<property name="can_focus">0</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="margin_top">12</property>
<property name="margin_bottom">12</property>
<property name="spacing">6</property>
<child>
<object class="GtkImage">
<property name="can_focus">0</property>
<property name="icon_name">dialog-warning-symbolic</property>
</object>
</child>
<child>
<object class="TootleWidgetsRichLabel" id="spoiler_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">Spoiler Text Here</property>
</object>
</child>
</object>
</child>
<style>
<class name="spoiler"/>
</style>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">content</property>
<property name="child">
<object class="GtkBox" id="content_box">
<property name="can_focus">0</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkImage">
<object class="TootleWidgetsMarkupView" id="content">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">dialog-warning-symbolic</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="TootleWidgetsRichLabel" id="spoiler_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="text">Spoiler Text Here</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
<object class="TootleWidgetsAttachmentBox" id="attachments"/>
</child>
</object>
</child>
<style>
<class name="spoiler"/>
</style>
</property>
</object>
<packing>
<property name="name">spoiler</property>
</packing>
</child>
<child>
<object class="GtkBox" id="content_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">8</property>
<child>
<object class="TootleWidgetsMarkupView" id="content">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="TootleWidgetsAttachmentBox" id="attachments">
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="name">content</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="actions">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">8</property>
<child>
<object class="GtkButton" id="reply_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="image">reply_button_icon</property>
<property name="always_show_image">True</property>
<style>
<class name="flat"/>
</style>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkToggleButton" id="reblog_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="image">reblog_icon</property>
<property name="always_show_image">True</property>
<style>
<class name="flat"/>
</style>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkToggleButton" id="favorite_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="image">image2</property>
<property name="always_show_image">True</property>
<style>
<class name="flat"/>
</style>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkToggleButton" id="bookmark_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="image">image1</property>
<property name="relief">none</property>
<property name="always_show_image">True</property>
<style>
<class name="flat"/>
</style>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkButton" id="menu_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">view-more-symbolic</property>
</object>
</child>
<style>
<class name="flat"/>
</style>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
<property name="homogeneous">1</property>
<property name="spacing">6</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<layout>
<property name="column">1</property>
<property name="row">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkImage" id="thread_line">
<property name="visible">0</property>
<property name="width_request">4</property>
<property name="height_request">32</property>
<property name="halign">center</property>
<property name="pixel-size">4</property>
<style>
<class name="ttl-thread-line"/>
</style>
<layout>
<property name="column">0</property>
<property name="row">0</property>
<property name="row-span">3</property>
</layout>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="avatar_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="halign">start</property>
<property name="valign">start</property>
<signal name="clicked" handler="on_avatar_clicked" swapped="no"/>
<child>
<object class="TootleWidgetsAvatar" id="avatar">
<property name="size">48</property>
<property name="valign">start</property>
<property name="visible">true</property>
<signal name="clicked" handler="on_avatar_clicked" swapped="no"/>
<layout>
<property name="column">0</property>
<property name="row">1</property>
</layout>
</object>
</child>
<style>
<class name="flat"/>
<class name="image-button"/>
<class name="circular"/>
<class name="ttl-flat-button"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkImage" id="thread_line">
<property name="width_request">4</property>
<property name="height_request">32</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="icon_size">0</property>
<style>
<class name="ttl-thread-line"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="height">3</property>
</packing>
</child>
</object>
</child>
</property>
<style>
<class name="ttl-post"/>
</style>

0
data/ui/widgets/timeline_footer.ui Normal file → Executable file
View File

0
data/ui/widgets/timeline_menu.ui Normal file → Executable file
View File

View File

@ -1,5 +1,5 @@
set -e
meson build
meson build --prefix=/usr
cd build
ninja
sudo ninja install

91
meson.build Normal file → Executable file
View File

@ -1,4 +1,4 @@
project('com.github.bleakgrey.tootle', 'vala', 'c', version: '1.0.0')
project('com.github.bleakgrey.tootle', 'vala', 'c', version: '2.0-alpha1')
add_global_arguments([
'-DGETTEXT_PACKAGE="@0@"'.format(meson.project_name()),
@ -6,25 +6,6 @@ add_global_arguments([
language: 'c',
)
libhandy_dep = dependency('libhandy-1', version: '>= 1.0', required: false)
if not libhandy_dep.found()
libhandy = subproject(
'libhandy',
default_options: [
'examples=false',
'glade_catalog=disabled',
'tests=false',
]
)
libhandy_dep = declare_dependency(
dependencies: [
libhandy.get_variable('libhandy_dep'),
libhandy.get_variable('libhandy_vapi'),
]
)
endif
config = configuration_data()
config.set('EXEC_NAME', meson.project_name())
config.set('GETTEXT_PACKAGE', meson.project_name())
@ -34,8 +15,7 @@ config.set('PREFIX', get_option('prefix'))
config.set('NAME', 'Tootle')
config.set('WEBSITE', 'https://github.com/bleakgrey/tootle')
config.set('SUPPORT_WEBSITE', 'https://github.com/bleakgrey/tootle/issues')
config.set('COPYRIGHT', '© 2018-2020 bleak_grey')
config.set('ACCOUNT_STORE', 'FileAccountStore')
config.set('COPYRIGHT', '© 2018-2021 bleak_grey')
gnome = import('gnome')
i18n = import('i18n')
@ -46,61 +26,66 @@ asresources = gnome.compile_resources(
c_name: 'as'
)
libgtk_dep = dependency('gtk4', version: '>=4.3.0', required: true)
libadwaita_dep = dependency('libadwaita-1', version: '>=1.0.0', required: true)
sources = files(
'src/Application.vala',
'src/Desktop.vala',
'src/Drawing.vala',
'src/Html.vala',
'src/Request.vala',
'src/DateTime.vala',
'src/Utils/Host.vala',
'src/Utils/Html.vala',
'src/Utils/DateTime.vala',
'src/Services/Accounts/InstanceAccount.vala',
'src/Services/Accounts/AccountStore.vala',
'src/Services/Accounts/FileAccountStore.vala',
'src/Services/Accounts/IAccountHolder.vala',
'src/Services/Accounts/Mastodon/MastodonAccount.vala',
'src/Services/Streams.vala',
'src/Services/Accounts/SecretAccountStore.vala',
'src/Services/Accounts/AccountHolder.vala',
'src/Services/Accounts/Mastodon/Account.vala',
'src/Services/Cache/AbstractCache.vala',
'src/Services/Cache/EntityCache.vala',
'src/Services/Cache/ImageCache.vala',
'src/Services/Network/Network.vala',
'src/Services/Network/Request.vala',
'src/Services/Network/Streams.vala',
'src/Services/Network/Streamable.vala',
'src/Services/Settings.vala',
'src/Services/IStreamListener.vala',
'src/Services/Cache.vala',
'src/Services/Network.vala',
'src/API/Account.vala',
'src/API/AccountField.vala',
'src/API/Relationship.vala',
'src/API/Mention.vala',
'src/API/Tag.vala',
'src/API/Status.vala',
'src/API/Visibility.vala',
'src/API/Notification.vala',
'src/API/NotificationType.vala',
'src/API/Attachment.vala',
'src/API/Conversation.vala',
'src/API/List.vala',
'src/API/SearchResults.vala',
'src/API/Entity.vala',
'src/Widgets/Widgetizable.vala',
'src/Widgets/Background.vala',
'src/Widgets/Avatar.vala',
'src/Widgets/AccountsButton.vala',
'src/Widgets/TimelineMenu.vala',
'src/Widgets/RichLabel.vala',
'src/Widgets/Status.vala',
'src/Widgets/Notification.vala',
'src/Widgets/Conversation.vala',
'src/Widgets/VisibilityPopover.vala',
'src/Widgets/Attachment/Box.vala',
'src/Widgets/Attachment/Slot.vala',
'src/Widgets/Attachment/Picture.vala',
'src/Widgets/AdaptiveButton.vala',
'src/Widgets/MarkupPolicy.vala',
'src/Widgets/Attachment/Item.vala',
'src/Widgets/Attachment/Image.vala',
'src/Widgets/LockableToggleButton.vala',
'src/Widgets/StatusActionButton.vala',
'src/Widgets/MarkupView.vala',
'src/Dialogs/ISavedWindow.vala',
'src/Dialogs/Saveable.vala',
'src/Dialogs/NewAccount.vala',
'src/Dialogs/MainWindow.vala',
'src/Dialogs/About.vala',
'src/Dialogs/Compose.vala',
'src/Dialogs/Preferences.vala',
'src/Dialogs/ListEditor.vala',
'src/Dialogs/Composer/Dialog.vala',
'src/Dialogs/Composer/Page.vala',
'src/Dialogs/Composer/EditorPage.vala',
'src/Dialogs/Composer/AttachmentsPage.vala',
'src/Dialogs/Composer/PollPage.vala',
'src/Views/Base.vala',
'src/Views/ContentBase.vala',
'src/Views/TabbedBase.vala',
'src/Views/Sidebar.vala',
'src/Views/Main.vala',
'src/Views/Timeline.vala',
'src/Views/Home.vala',
@ -118,14 +103,6 @@ sources = files(
'src/Views/List.vala',
)
libsecret_dep = dependency('libsecret-1', required: false)
if not libsecret_dep.found()
warning('Keyring support disabled. Accounts will be stored in a text file.')
else
config.set('ACCOUNT_STORE','SecretAccountStore')
sources += 'src/Services/Accounts/'+config.get('ACCOUNT_STORE')+'.vala'
endif
build_file = configure_file(
input: 'src/Build.vala.in',
output: 'Build.vala',
@ -138,14 +115,14 @@ executable(
build_file,
sources,
dependencies: [
dependency('gtk+-3.0', version: '>=3.22.0'),
dependency('glib-2.0', version: '>=2.30.0'),
dependency('gee-0.8', version: '>=0.8.5'),
dependency('libsoup-2.4'),
dependency('json-glib-1.0', version: '>=1.4.4'),
dependency('libxml-2.0'),
libhandy_dep,
libsecret_dep,
dependency('libsecret-1', required: true),
libgtk_dep,
libadwaita_dep,
],
install: true,
)

0
po/LINGUAS Normal file → Executable file
View File

0
po/POTFILES Normal file → Executable file
View File

0
po/com.github.bleakgrey.tootle.pot Normal file → Executable file
View File

0
po/de_DE.po Normal file → Executable file
View File

0
po/es.po Normal file → Executable file
View File

0
po/meson.build Normal file → Executable file
View File

0
po/nb-NO.po Normal file → Executable file
View File

0
po/ru_RU.po Normal file → Executable file
View File

5
src/.editorconfig Normal file → Executable file
View File

@ -8,3 +8,8 @@ charset = utf-8
[*.sh]
indent_size = 4
indent_style = tab
[*.vala]
indent_size = 4
indent_style = tab
insert_final_newline = false

2
src/API/Account.vala Normal file → Executable file
View File

@ -53,7 +53,7 @@ public class Tootle.API.Account : Entity, Widgetizable {
public override void open () {
var view = new Views.Profile (this);
window.open_view (view);
app.main_window.open_view (view);
}
public override void resolve_open (InstanceAccount account) {

0
src/API/AccountField.vala Normal file → Executable file
View File

36
src/API/Attachment.vala Normal file → Executable file
View File

@ -1,4 +1,4 @@
public class Tootle.API.Attachment : Entity {
public class Tootle.API.Attachment : Entity, Widgetizable {
// https://github.com/tootsuite/mastodon/blob/master/app/models/media_attachment.rb
public const string[] SUPPORTED_MIMES = {
@ -29,7 +29,7 @@ public class Tootle.API.Attachment : Entity {
};
public string id { get; set; }
public string kind { get; set; }
public string kind { get; set; default = "unknown"; }
public string url { get; set; }
public string? description { get; set; }
public string? _preview_url { get; set; }
@ -38,10 +38,6 @@ public class Tootle.API.Attachment : Entity {
get { return (this._preview_url == null || this._preview_url == "") ? url : _preview_url; }
}
public static Attachment from (Json.Node node) throws Error {
return Entity.from_json (typeof (API.Attachment), node) as API.Attachment;
}
public static async Attachment upload (string uri, string title, string? descr) throws Error {
message (@"Uploading new media: $(uri)...");
@ -75,13 +71,13 @@ public class Tootle.API.Attachment : Entity {
string? error = null;
network.queue (msg,
(sess, mess) => {
upload.callback ();
},
(code, reason) => {
error = reason;
upload.callback ();
});
(sess, mess) => {
upload.callback ();
},
(code, reason) => {
error = reason;
upload.callback ();
});
yield;
@ -89,10 +85,22 @@ public class Tootle.API.Attachment : Entity {
throw new Oopsie.INSTANCE (error);
else {
var node = network.parse_node (msg);
var entity = API.Attachment.from (node);
var entity = accounts.active.create_entity<API.Attachment> (node);
message (@"OK! ID $(entity.id)");
return entity;
}
}
public override Gtk.Widget to_widget () {
if (preview_url != null) {
return new Widgets.Attachment.Image () {
entity = this
};
}
return new Widgets.Attachment.Item () {
entity = this
};
}
}

2
src/API/Conversation.vala Normal file → Executable file
View File

@ -11,7 +11,7 @@ public class Tootle.API.Conversation : Entity, Widgetizable {
public override void open () {
var view = new Views.Thread (last_status.formal);
window.open_view (view);
app.main_window.open_view (view);
if (unread)
mark_read ();

9
src/API/Entity.vala Normal file → Executable file
View File

@ -25,22 +25,19 @@ public class Tootle.Entity : GLib.Object, Widgetizable, Json.Serializable {
patch_specs (with, with.get_class ().list_properties ());
}
public void patch_specs (GLib.Object with, ParamSpec[] specs) {
public void patch_specs (GLib.Object obj, ParamSpec[] specs) {
foreach (ParamSpec spec in specs) {
var name = spec.get_name ();
var defined = get_class ().find_property (name) != null;
if (defined && is_spec_valid (ref spec)) {
var val = Value (spec.value_type);
with.get_property (name, ref val);
obj.get_property (name, ref val);
base.set_property (name, val);
}
}
}
public static Entity from_json (Type type, Json.Node? node) throws Oopsie {
if (node == null)
throw new Oopsie.PARSING (@"Received Json.Node for $(type.name ()) is null!");
public static Entity from_json (Type type, Json.Node node) throws Error {
var obj = node.get_object ();
if (obj == null)
throw new Oopsie.PARSING (@"Received Json.Node for $(type.name ()) is not a Json.Object!");

0
src/API/List.vala Normal file → Executable file
View File

0
src/API/Mention.vala Normal file → Executable file
View File

55
src/API/Notification.vala Normal file → Executable file
View File

@ -2,37 +2,46 @@ public class Tootle.API.Notification : Entity, Widgetizable {
public string id { get; set; }
public API.Account account { get; set; }
public API.NotificationType kind { get; set; }
public string created_at { get; set; }
public string? kind { get; set; default = null; }
public API.Status? status { get; set; default = null; }
public override Gtk.Widget to_widget () {
return new Widgets.Notification (this);
}
public Soup.Message? dismiss () {
if (kind == NotificationType.FOLLOW_REQUEST)
return reject_follow_request ();
// TODO: notification actions
public virtual GLib.Notification to_toast (InstanceAccount issuer) {
string descr;
issuer.describe_kind (kind, null, out descr, account);
var req = new Request.POST ("/api/v1/notifications/dismiss")
.with_account (accounts.active)
.with_param ("id", id)
.exec ();
return req;
}
var toast = new GLib.Notification ( HtmlUtils.remove_tags (descr) );
if (status != null) {
var body = "";
body += HtmlUtils.remove_tags (status.content);
toast.set_body (body);
}
public Soup.Message accept_follow_request () {
var req = new Request.POST (@"/api/v1/follow_requests/$(account.id)/authorize")
.with_account (accounts.active)
.exec ();
return req;
}
var icon_file = GLib.File.new_for_uri (issuer.avatar);
var icon = new FileIcon (icon_file);
toast.set_icon (icon);
public Soup.Message reject_follow_request () {
var req = new Request.POST (@"/api/v1/follow_requests/$(account.id)/reject")
.with_account (accounts.active)
.exec ();
return req;
}
// toast.add_button_with_target_value (_("Read"), "mastodon.read_notification", id);
return toast;
}
// public Soup.Message accept_follow_request () {
// var req = new Request.POST (@"/api/v1/follow_requests/$(account.id)/authorize")
// .with_account (accounts.active)
// .exec ();
// return req;
// }
// public Soup.Message reject_follow_request () {
// var req = new Request.POST (@"/api/v1/follow_requests/$(account.id)/reject")
// .with_account (accounts.active)
// .exec ();
// return req;
// }
}

View File

@ -1,86 +0,0 @@
public enum Tootle.API.NotificationType {
MENTION,
REBLOG,
REBLOG_REMOTE_USER, // Internal
FAVOURITE,
FOLLOW,
FOLLOW_REQUEST; // Internal
public string to_string () {
switch (this) {
case MENTION:
return "mention";
case REBLOG:
return "reblog";
case REBLOG_REMOTE_USER:
return "reblog_remote";
case FAVOURITE:
return "favourite";
case FOLLOW:
return "follow";
case FOLLOW_REQUEST:
return "follow_request";
default:
warning (@"Unknown notification type: $this");
return "";
}
}
public static NotificationType from_string (string str) throws Oopsie {
switch (str) {
case "mention":
return MENTION;
case "reblog":
return REBLOG;
case "reblog_remote":
return REBLOG_REMOTE_USER;
case "favourite":
return FAVOURITE;
case "follow":
return FOLLOW;
case "follow_request":
return FOLLOW_REQUEST;
default:
throw new Oopsie.INSTANCE (@"Unknown notification type: $str");
}
}
public string get_desc (Account? account) {
switch (this) {
case MENTION:
return _("<span underline=\"none\"><a href=\"%s\">%s</a> mentioned you</span>").printf (account.url, account.display_name);
case REBLOG:
return _("<span underline=\"none\"><a href=\"%s\">%s</a> boosted your status</span>").printf (account.url, account.display_name);
case REBLOG_REMOTE_USER:
return _("<span underline=\"none\"><a href=\"%s\">%s</a> boosted</span>").printf (account.url, account.display_name);
case FAVOURITE:
return _("<span underline=\"none\"><a href=\"%s\">%s</a> favorited your status</span>").printf (account.url, account.display_name);
case FOLLOW:
return _("<span underline=\"none\"><a href=\"%s\">%s</a> now follows you</span>").printf (account.url, account.display_name);
case FOLLOW_REQUEST:
return _("<span underline=\"none\"><a href=\"%s\">%s</a> wants to follow you</span>").printf (account.url, account.display_name);
default:
warning (@"Unknown notification type: $this");
return "";
}
}
public string get_icon () {
switch (this) {
case MENTION:
return "user-available-symbolic";
case REBLOG:
case REBLOG_REMOTE_USER:
return "media-playlist-repeat-symbolic";
case FAVOURITE:
return "starred-symbolic";
case FOLLOW:
case FOLLOW_REQUEST:
return "contact-new-symbolic";
default:
warning (@"Unknown notification type: $this");
return "";
}
}
}

0
src/API/Relationship.vala Normal file → Executable file
View File

0
src/API/SearchResults.vala Normal file → Executable file
View File

27
src/API/Status.vala Normal file → Executable file
View File

@ -2,6 +2,10 @@ using Gee;
public class Tootle.API.Status : Entity, Widgetizable {
~Status () {
message ("[OBJ] Destroyed "+uri);
}
public string id { get; set; }
public API.Account account { get; set; }
public string uri { get; set; }
@ -19,7 +23,7 @@ public class Tootle.API.Status : Entity, Widgetizable {
public bool sensitive { get; set; default = false; }
public bool muted { get; set; default = false; }
public bool pinned { get; set; default = false; }
public API.Visibility visibility { get; set; default = settings.default_post_visibility; }
public string visibility { get; set; default = "public"; } // TODO: Bring back default post visibility preference
public API.Status? reblog { get; set; default = null; }
public ArrayList<API.Mention>? mentions { get; set; default = null; }
public ArrayList<API.Attachment>? media_attachments { get; set; default = null; }
@ -47,14 +51,19 @@ public class Tootle.API.Status : Entity, Widgetizable {
}
}
public bool can_be_boosted {
get {
return this.formal.visibility != "direct";
}
}
public static Status from (Json.Node node) throws Error {
return Entity.from_json (typeof (API.Status), node) as API.Status;
}
public Status.empty () {
Object (
id: "",
visibility: settings.default_post_visibility
id: ""
);
}
@ -79,7 +88,7 @@ public class Tootle.API.Status : Entity, Widgetizable {
public override void open () {
var view = new Views.Thread (formal);
window.open_view (view);
app.main_window.open_view (view);
}
public bool is_owned (){
@ -87,10 +96,10 @@ public class Tootle.API.Status : Entity, Widgetizable {
}
public bool has_media () {
return media_attachments != null && media_attachments.size > 0;
return media_attachments != null && !media_attachments.is_empty;
}
public string get_reply_mentions () {
public virtual string get_reply_mentions () {
var result = "";
if (account.acct != accounts.active.acct)
result = @"$(account.handle) ";
@ -100,7 +109,7 @@ public class Tootle.API.Status : Entity, Widgetizable {
var equals_current = mention.acct == accounts.active.acct;
var already_mentioned = mention.acct in result;
if (!equals_current && ! already_mentioned)
if (!equals_current && !already_mentioned)
result += @"$(mention.handle) ";
}
}
@ -109,7 +118,9 @@ public class Tootle.API.Status : Entity, Widgetizable {
}
public Request action (string action) {
return new Request.POST (@"/api/v1/statuses/$(formal.id)/$action").with_account (accounts.active);
var req = new Request.POST (@"/api/v1/statuses/$(formal.id)/$action").with_account (accounts.active);
req.priority = Soup.MessagePriority.HIGH;
return req;
}
public Request annihilate () {

2
src/API/Tag.vala Normal file → Executable file
View File

@ -12,9 +12,7 @@ public class Tootle.API.Tag : Entity, Widgetizable {
public override Widget to_widget () {
var encoded = Soup.URI.encode (name, null);
var w = new Widgets.RichLabel (@"<a href=\"$(accounts.active.instance)/tags/$encoded\">#$name</a>");
w.use_markup = true;
w.halign = Align.START;
w.margin = 8;
w.show ();
return w;
}

View File

@ -1,76 +0,0 @@
public enum Tootle.API.Visibility {
PUBLIC,
UNLISTED,
PRIVATE,
DIRECT;
public string to_string () {
switch (this) {
case UNLISTED:
return "unlisted";
case PRIVATE:
return "private";
case DIRECT:
return "direct";
default:
return "public";
}
}
public static Visibility from_string (string str) {
switch (str) {
case "unlisted":
return Visibility.UNLISTED;
case "private":
return Visibility.PRIVATE;
case "direct":
return Visibility.DIRECT;
default:
return Visibility.PUBLIC;
}
}
public string get_name () {
switch (this) {
case UNLISTED:
return _("Unlisted");
case PRIVATE:
return _("Followers-only");
case DIRECT:
return _("Direct");
default:
return _("Public");
}
}
public string get_desc () {
switch (this) {
case UNLISTED:
return _("Don\'t post to public timelines");
case PRIVATE:
return _("Post to followers only");
case DIRECT:
return _("Post to mentioned users only");
default:
return _("Post to public timelines");
}
}
public string get_icon () {
switch (this) {
case UNLISTED:
return "changes-allow-symbolic";
case PRIVATE:
return "changes-prevent-symbolic";
case DIRECT:
return "user-available-symbolic";
default:
return "network-workgroup-symbolic";
}
}
public static Visibility[] all () {
return {Visibility.PUBLIC, Visibility.UNLISTED, Visibility.PRIVATE, Visibility.DIRECT};
}
}

105
src/Application.vala Normal file → Executable file
View File

@ -10,32 +10,33 @@ namespace Tootle {
}
public static Application app;
public static Dialogs.MainWindow? window;
public static Dialogs.NewAccount? new_account_window;
public static Window window_dummy;
public static Settings settings;
public static AccountStore accounts;
public static Network network;
public static Cache cache;
public static Streams streams;
public static EntityCache entity_cache;
public static ImageCache image_cache;
public static bool start_hidden = false;
public class Application : Gtk.Application {
public Dialogs.MainWindow? main_window { get; set; }
public Dialogs.NewAccount? add_account_window { get; set; }
// These are used for the GTK Inspector
public Settings app_settings { get {return Tootle.settings; } }
public AccountStore app_accounts { get {return Tootle.accounts; } }
public Network app_network { get {return Tootle.network; } }
public Cache app_cache { get {return Tootle.cache; } }
public Streams app_streams { get {return Tootle.streams; } }
public signal void refresh ();
public signal void toast (string title);
public CssProvider css_provider = new CssProvider ();
public CssProvider zoom_css_provider = new CssProvider ();
public CssProvider zoom_css_provider = new CssProvider (); //FIXME: Zoom not working
public const GLib.OptionEntry[] app_options = {
{ "hidden", 0, 0, OptionArg.NONE, ref start_hidden, "Do not show main window on start", null },
@ -48,7 +49,6 @@ namespace Tootle {
{ "back", back_activated },
{ "refresh", refresh_activated },
{ "search", search_activated },
{ "switch-timeline", switch_timeline_activated, "i" }
};
construct {
@ -61,13 +61,9 @@ namespace Tootle {
public string[] ACCEL_BACK = {"<Alt>BackSpace", "<Alt>Left"};
public string[] ACCEL_REFRESH = {"<Ctrl>R", "F5"};
public string[] ACCEL_SEARCH = {"<Ctrl>F"};
public string[] ACCEL_TIMELINE_0 = {"<Alt>1"};
public string[] ACCEL_TIMELINE_1 = {"<Alt>2"};
public string[] ACCEL_TIMELINE_2 = {"<Alt>3"};
public string[] ACCEL_TIMELINE_3 = {"<Alt>4"};
public static int main (string[] args) {
Gtk.init (ref args);
Gtk.init ();
try {
var opt_context = new OptionContext ("- Options");
opt_context.add_main_entries (app_options, null);
@ -85,21 +81,19 @@ namespace Tootle {
base.startup ();
try {
Build.print_info ();
Hdy.init ();
Adw.init ();
settings = new Settings ();
streams = new Streams ();
network = new Network ();
cache = new Cache ();
accounts = Build.get_account_store ();
entity_cache = new EntityCache ();
image_cache = new ImageCache ();
accounts = new SecretAccountStore();
accounts.init ();
css_provider.load_from_resource (@"$(Build.RESOURCES)app.css");
StyleContext.add_provider_for_screen (Gdk.Screen.get_default (), css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
StyleContext.add_provider_for_screen (Gdk.Screen.get_default (), zoom_css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
window_dummy = new Window ();
add_window (window_dummy);
StyleContext.add_provider_for_display (Gdk.Display.get_default (), css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
StyleContext.add_provider_for_display (Gdk.Display.get_default (), zoom_css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
}
catch (Error e) {
var msg = _("Could not start application: %s").printf (e.message);
@ -112,10 +106,6 @@ namespace Tootle {
set_accels_for_action ("app.back", ACCEL_BACK);
set_accels_for_action ("app.refresh", ACCEL_REFRESH);
set_accels_for_action ("app.search", ACCEL_SEARCH);
set_accels_for_action ("app.switch-timeline(0)", ACCEL_TIMELINE_0); //TODO: There's no action for handling these
set_accels_for_action ("app.switch-timeline(1)", ACCEL_TIMELINE_1);
set_accels_for_action ("app.switch-timeline(2)", ACCEL_TIMELINE_2);
set_accels_for_action ("app.switch-timeline(3)", ACCEL_TIMELINE_3);
add_action_entries (app_entries, this);
}
@ -131,8 +121,8 @@ namespace Tootle {
public override void open (File[] files, string hint) {
foreach (File file in files) {
string uri = file.get_uri ();
if (new_account_window != null)
new_account_window.redirect (uri);
if (add_account_window != null)
add_account_window.redirect (uri);
else
warning (@"Received an unexpected uri to open: $uri");
return;
@ -142,50 +132,66 @@ namespace Tootle {
public void present_window () {
if (accounts.saved.is_empty) {
message ("Presenting NewAccount dialog");
if (new_account_window == null)
if (add_account_window == null)
new Dialogs.NewAccount ();
new_account_window.present ();
add_account_window.present ();
}
else {
message ("Presenting MainWindow");
if (window == null)
window = new Dialogs.MainWindow (this);
window.present ();
if (main_window == null)
main_window = new Dialogs.MainWindow (this);
main_window.present ();
}
}
public bool on_window_closed () {
if (!settings.work_in_background || accounts.saved.is_empty)
app.remove_window (window_dummy);
return false;
}
// TODO: Background mode
// public bool on_window_closed () {
// if (!settings.work_in_background || accounts.saved.is_empty)
// app.remove_window (window_dummy);
// return false;
// }
void compose_activated () {
new Dialogs.Compose ();
}
void back_activated () {
window.back ();
main_window.back ();
}
void search_activated () {
window.open_view (new Views.Search ());
main_window.open_view (new Views.Search ());
}
void refresh_activated () {
refresh ();
}
void switch_timeline_activated (SimpleAction a, Variant? v) {
int32 num = v.get_int32 ();
window.switch_timeline (num);
}
void about_activated () {
new Dialogs.About ();
var dialog = new AboutDialog () {
transient_for = main_window,
modal = true,
logo_icon_name = Build.DOMAIN,
program_name = Build.NAME,
version = Build.VERSION,
website = Build.SUPPORT_WEBSITE,
website_label = _("Report an issue"),
license_type = License.GPL_3_0_ONLY,
copyright = Build.COPYRIGHT,
system_information = Build.SYSTEM_INFO
};
// For some obscure reason, const arrays produce duplicates in the credits.
// Static functions seem to avoid this peculiar behavior.
dialog.authors = Build.get_authors ();
dialog.artists = Build.get_artists ();
dialog.translator_credits = Build.TRANSLATOR != " " ? Build.TRANSLATOR : null;
dialog.present ();
}
public void inform (Gtk.MessageType type, string text, string? msg = null, Gtk.Window? win = window){
public void inform (Gtk.MessageType type, string text, string? msg = null, Gtk.Window? win = main_window){
var dlg = new Gtk.MessageDialog (
win,
Gtk.DialogFlags.MODAL,
@ -196,11 +202,11 @@ namespace Tootle {
dlg.text = text;
dlg.secondary_text = msg;
dlg.transient_for = win;
dlg.run ();
// dlg.run ();
dlg.destroy ();
}
public bool question (string text, string? msg = null, Gtk.Window? win = window) {
public bool question (string text, string? msg = null, Gtk.Window? win = main_window) {
var dlg = new Gtk.MessageDialog (
win,
Gtk.DialogFlags.MODAL,
@ -211,9 +217,10 @@ namespace Tootle {
dlg.text = text;
dlg.secondary_text = msg;
dlg.transient_for = win;
var i = dlg.run ();
// var i = dlg.run ();
dlg.destroy ();
return i == ResponseType.YES;
// return i == ResponseType.YES;
return false;
}
}

28
src/Build.vala.in Normal file → Executable file
View File

@ -9,6 +9,8 @@ public class Build {
public const string COPYRIGHT = "@COPYRIGHT@";
public const string PREFIX = "@PREFIX@";
public static string SYSTEM_INFO;
// Please do not remove the credits below. You may add your own, but keep the existing ones intact.
// TRANSLATORS: Replace this with your name. It will be displayed in the About dialog.
@ -26,20 +28,24 @@ public class Build {
};
}
public static void print_info () {
var os_name = get_os_info ("NAME");
var os_ver = get_os_info ("VERSION");
message (@"$NAME $VERSION");
message (@"Running on: $os_name $os_ver");
message (@"Build prefix: \"$PREFIX\"");
}
public static string print_info () {
var os_name = get_os_info ("NAME");
var os_ver = get_os_info ("VERSION");
SYSTEM_INFO = @"$NAME $VERSION";
SYSTEM_INFO += @"\nRunning on: $os_name $os_ver";
SYSTEM_INFO += @"\nBuild prefix: \"$PREFIX\"";
var lines = SYSTEM_INFO.split ("\n");
foreach (unowned string line in lines) {
message (line);
}
return SYSTEM_INFO;
}
static string get_os_info (string key) {
return GLib.Environment.get_os_info (key) ?? "Unknown";
}
public static Tootle.AccountStore get_account_store () {
return new Tootle.@ACCOUNT_STORE@ ();
}
}

View File

@ -1,35 +0,0 @@
using Gtk;
public class Tootle.Dialogs.About : AboutDialog {
public About () {
Object (
transient_for: window,
modal: true,
logo_icon_name: Build.DOMAIN,
program_name: Build.NAME,
version: Build.VERSION,
website: Build.SUPPORT_WEBSITE,
website_label: _("Report an issue"),
license_type: License.GPL_3_0_ONLY,
copyright: Build.COPYRIGHT
);
// For some obscure reason, const arrays produce duplicates in the credits.
// Static functions seem to avoid this peculiar behavior.
authors = Build.get_authors ();
artists = Build.get_artists ();
translator_credits = Build.TRANSLATOR != " " ? Build.TRANSLATOR : null;
response.connect ((response_id) => {
if (response_id == Gtk.ResponseType.CANCEL ||
response_id == Gtk.ResponseType.DELETE_EVENT) {
hide_on_delete ();
}
});
present ();
}
}

View File

@ -1,314 +0,0 @@
using Gtk;
using Gee;
[GtkTemplate (ui = "/com/github/bleakgrey/tootle/ui/dialogs/compose.ui")]
public class Tootle.Dialogs.Compose : Hdy.Window {
public API.Status? status { get; construct set; }
public string style_class { get; construct set; }
public string label { get; construct set; }
public bool working { get; set; default = false; }
public int char_limit {
get {
return 500;
}
}
[GtkChild]
Hdy.ViewSwitcherTitle mode_switcher;
[GtkChild]
Button commit;
[GtkChild]
Stack commit_stack;
[GtkChild]
Revealer cw_revealer;
[GtkChild]
ToggleButton cw_button;
[GtkChild]
Entry cw;
[GtkChild]
Label counter;
[GtkChild]
MenuButton visibility_button;
[GtkChild]
Image visibility_icon;
Widgets.VisibilityPopover visibility_popover;
[GtkChild]
TextView content;
[GtkChild]
Stack mode;
[GtkChild]
ListBox media_list;
[GtkTemplate (ui = "/com/github/bleakgrey/tootle/ui/widgets/compose_attachment.ui")]
protected class MediaItem : Gtk.ListBoxRow {
Compose dialog;
public API.Attachment? entity { get; set; }
public string? source { get; set; }
[GtkChild]
public Label title_label;
[GtkChild]
public Entry description;
[GtkChild]
public Stack icon;
public MediaItem (Compose dialog, string? source, API.Attachment? entity) {
this.dialog = dialog;
this.source = source;
this.entity = entity;
if (source != null)
message (@"Attached uri: $source");
else {
message (@"Attached immutable $(entity.id)");
description.text = entity.description ?? " ";
description.sensitive = false;
}
dialog.set_media_mode (true);
title_label.label = GLib.Path.get_basename (source ?? entity.url).replace ("%20", " ");
}
[GtkCallback]
void on_remove () {
var remove = app.question (
_(@"Delete \"%s\"?").printf (title_label.label),
_("This action cannot be reverted."),
this.dialog
);
if (remove)
destroy ();
}
}
construct {
transient_for = window;
notify["working"].connect (on_state_change);
mode_switcher.title = label;
commit.get_style_context ().add_class (style_class);
visibility_popover = new Widgets.VisibilityPopover.with_button (visibility_button);
visibility_popover.bind_property ("selected", visibility_icon, "icon-name", BindingFlags.SYNC_CREATE, (b, src, ref target) => {
target.set_string (((API.Visibility)src).get_icon ());
return true;
});
cw_button.bind_property ("active", cw_revealer, "reveal_child", BindingFlags.SYNC_CREATE);
cw.buffer.deleted_text.connect (() => validate ());
cw.buffer.inserted_text.connect (() => validate ());
content.buffer.changed.connect (validate);
if (status.has_spoiler) {
cw.text = status.spoiler_text;
cw_button.active = true;
}
content.buffer.text = HtmlUtils.remove_tags (status.content);
validate ();
set_media_mode (status.has_media ());
show ();
content.grab_focus ();
}
public Compose (API.Status template = new API.Status.empty ()) {
Object (
status: template,
style_class: STYLE_CLASS_SUGGESTED_ACTION,
label: _("Compose")
);
message ("Composing status template");
set_visibility (status.visibility);
}
public Compose.redraft (API.Status status) {
Object (
status: status,
style_class: STYLE_CLASS_DESTRUCTIVE_ACTION,
label: _("Redraft")
);
message (@"Redrafting status $(status.id)");
set_visibility (status.visibility);
status.media_attachments.@foreach (a => {
media_list.insert (new MediaItem (this, null, a), 0);
return true;
});
}
public Compose.reply (API.Status to) {
var template = new API.Status.empty ();
template.in_reply_to_id = to.id.to_string ();
template.in_reply_to_account_id = to.account.id.to_string ();
template.spoiler_text = to.spoiler_text;
template.content = to.formal.get_reply_mentions ();
Object (
status: template,
style_class: STYLE_CLASS_SUGGESTED_ACTION,
label: _("Reply")
);
message (@"Replying to status $(status.in_reply_to_id)");
set_visibility (to.visibility);
}
void set_visibility (API.Visibility v) {
visibility_popover.selected = v;
visibility_popover.invalidate ();
}
void set_media_mode (bool has_media) {
mode_switcher.view_switcher_enabled = has_media;
}
[GtkCallback]
void validate () {
var remain = char_limit - content.buffer.get_char_count ();
if (cw_button.active)
remain -= (int) cw.buffer.get_length ();
counter.label = remain.to_string ();
commit.sensitive = remain >= 0;
}
void on_state_change (ParamSpec? p) {
commit_stack.visible_child_name = working ? "working" : "ready";
commit.sensitive = !working;
media_list.@foreach (w => {
var item = w as MediaItem;
if (item != null)
item.icon.visible_child_name = working ? "upload" : "new";
});
}
[GtkCallback]
void on_select_media () {
var filter = new Gtk.FileFilter ();
foreach (string mime in API.Attachment.SUPPORTED_MIMES)
filter.add_mime_type (mime);
var chooser = new Gtk.FileChooserNative (
_("Select media"),
this,
Gtk.FileChooserAction.OPEN,
_("_Open"),
_("_Cancel")
);
chooser.select_multiple = true;
chooser.set_filter (filter);
if (chooser.run () == Gtk.ResponseType.ACCEPT) {
foreach (unowned string uri in chooser.get_uris ())
media_list.insert (new MediaItem (this, uri, null), 0);
mode.visible_child_name = "media";
}
}
[GtkCallback]
void on_media_list_row_activated (Widget w) {
if (!(w is MediaItem))
on_select_media ();
}
[GtkCallback]
void on_close () {
destroy ();
}
void on_error (int32 code, string reason) { //TODO: display errors
warning (reason);
working = false;
}
[GtkCallback]
void on_commit () {
working = true;
transaction.begin ((obj, res) => {
try {
transaction.end (res);
on_close ();
}
catch (Error e) {
working = false;
on_error (0, e.message);
}
});
}
async void transaction () throws Error {
if (status.id != "") {
message ("Removing old status...");
yield status.annihilate ().await ();
}
Gee.ArrayList<MediaItem> pending_media = new Gee.ArrayList<MediaItem>();
Gee.ArrayList<string> media_ids = new Gee.ArrayList<string>();
media_list.@foreach (w => {
var item = w as MediaItem;
if (item != null)
pending_media.add (item);
});
var media_param = "";
if (!pending_media.is_empty) {
message (@"Processing $(pending_media.size) attachments...");
if (!status.has_media ())
status.media_attachments = new ArrayList<API.Attachment>();
foreach (MediaItem item in pending_media) {
if (item.entity != null) {
message (@"Adding immutable media: $(item.entity.id)...");
media_ids.add (item.entity.id);
}
else {
mode.visible_child_name = "media";
var entity = yield API.Attachment.upload (
item.source,
item.title_label.label,
item.description.text);
media_ids.add (entity.id);
}
item.icon.visible_child_name = "ok";
}
media_param = Request.array2string (media_ids, "media_ids");
media_param += "&";
}
message ("Publishing status...");
status.content = content.buffer.text;
status.spoiler_text = cw.text;
var req = new Request.POST (@"/api/v1/statuses?$media_param")
.with_account (accounts.active)
.with_form_data ("visibility", visibility_popover.selected.to_string ())
.with_form_data ("status", status.content);
if (cw_button.active) {
req.with_form_data ("sensitive", "true");
req.with_form_data ("spoiler_text", cw.text);
}
if (status.in_reply_to_id != null)
req.with_form_data ("in_reply_to_id", status.in_reply_to_id);
if (status.in_reply_to_account_id != null)
req.with_form_data ("in_reply_to_account_id", status.in_reply_to_account_id);
yield req.await ();
var node = network.parse_node (req);
var status = API.Status.from (node);
message (@"OK: Published with ID $(status.id)");
on_close ();
}
}

View File

@ -0,0 +1,10 @@
public class Tootle.AttachmentsPage : ComposerPage {
public AttachmentsPage () {
Object (
title: _("Media"),
icon_name: "mail-attachment-symbolic"
);
}
}

128
src/Dialogs/Composer/Dialog.vala Executable file
View File

@ -0,0 +1,128 @@
using Gtk;
using Gee;
[GtkTemplate (ui = "/com/github/bleakgrey/tootle/ui/dialogs/compose.ui")]
public class Tootle.Dialogs.Compose : Adw.Window {
public API.Status status { get; construct set; }
public string button_label {
set { commit_button.label = value; }
}
public string button_class {
set { commit_button.add_css_class (value); }
}
construct {
transient_for = app.main_window;
title_switcher.stack = stack;
notify["status"].connect (() => {
build ();
present ();
});
}
protected virtual signal void build () {
add_page (new EditorPage ());
add_page (new AttachmentsPage ());
add_page (new PollPage ());
}
[GtkChild] unowned Adw.ViewSwitcherTitle title_switcher;
[GtkChild] unowned Button commit_button;
[GtkChild] unowned Adw.ViewStack stack;
public Compose (API.Status template = new API.Status.empty ()) {
Object (
status: template,
button_label: _("Publish"),
button_class: "suggested-action"
);
}
public Compose.redraft (API.Status status) {
Object (
status: status,
button_label: _("Redraft"),
button_class: "destructive-action"
);
}
public Compose.reply (API.Status to) {
var template = new API.Status.empty () {
in_reply_to_id = to.id.to_string (),
in_reply_to_account_id = to.account.id.to_string (),
spoiler_text = to.spoiler_text,
content = to.formal.get_reply_mentions ()
};
Object (
status: template,
button_label: _("Reply"),
button_class: "suggested-action"
);
}
protected T? get_page<T> () {
var pages = stack.get_pages ();
for (var i = 0; i < pages.get_n_items (); i++) {
var page = pages.get_object (i);
if (page is T)
return page;
}
return null;
}
protected void add_page (ComposerPage page) {
var wrapper = stack.add (page);
page.on_build (this, this.status);
modify_req.connect (page.on_sync);
modify_req.connect (page.on_modify_req);
page.bind_property ("visible", wrapper, "visible", GLib.BindingFlags.SYNC_CREATE);
page.bind_property ("title", wrapper, "title", GLib.BindingFlags.SYNC_CREATE);
page.bind_property ("icon_name", wrapper, "icon_name", GLib.BindingFlags.SYNC_CREATE);
page.bind_property ("badge_number", wrapper, "badge_number", GLib.BindingFlags.SYNC_CREATE);
}
[GtkCallback] void on_close () {
destroy ();
}
[GtkCallback] void on_commit () {
//working = true
transaction.begin ((obj, res) => {
try {
transaction.end (res);
// on_close ();
}
catch (Error e) {
// working = false;
// on_error (0, e.message);
warning (e.message);
}
});
}
protected signal void modify_req (Request req);
protected virtual async void transaction () throws Error {
var publish_req = new Request () {
method = "POST",
url = "/api/v1/statuses",
account = accounts.active
};
modify_req (publish_req);
yield publish_req.await ();
var node = network.parse_node (publish_req);
var status = API.Status.from (node);
message (@"Published post with id $(status.id)");
on_close ();
}
}

View File

@ -0,0 +1,150 @@
using Gtk;
public class Tootle.EditorPage : ComposerPage {
protected uint char_limit { get; set; default = 500; } //TODO: Ask the instance to get this value
protected int remaining_chars { get; set; default = 0; }
construct {
title = _("Text");
icon_name = "document-edit-symbolic";
}
public override void on_build (Dialogs.Compose dialog, API.Status status) {
base.on_build (dialog, status);
install_editor ();
populate_editor ();
install_visibility ();
install_cw ();
validate ();
}
protected virtual signal void recount_chars () {}
protected void validate () {
recount_chars ();
}
public override void on_sync () {
warning ("syncing");
status.content = editor.buffer.text;
status.sensitive = cw_button.active;
if (status.sensitive) {
status.spoiler_text = cw_entry.text;
}
status.visibility = (visibility_button.selected_item as InstanceAccount.Visibility).id;
}
public override void on_modify_req (Request req) {
req.with_form_data ("status", status.content);
req.with_form_data ("visibility", status.visibility);
if (dialog.status.in_reply_to_id != null)
req.with_form_data ("in_reply_to_id", dialog.status.in_reply_to_id);
if (dialog.status.in_reply_to_account_id != null)
req.with_form_data ("in_reply_to_account_id", dialog.status.in_reply_to_account_id);
if (cw_button.active) {
req.with_form_data ("sensitive", "true");
req.with_form_data ("spoiler_text", status.spoiler_text);
}
}
protected TextView editor;
protected Label char_counter;
protected void install_editor () {
recount_chars.connect (() => {
remaining_chars = (int) char_limit;
});
recount_chars.connect_after (() => {
char_counter.label = remaining_chars.to_string ();
if (remaining_chars < 0)
char_counter.add_css_class ("error");
else
char_counter.remove_css_class ("error");
});
editor = new TextView () {
vexpand = true,
hexpand = true,
top_margin = 6,
right_margin = 6,
bottom_margin = 6,
left_margin = 6,
pixels_below_lines = 6,
accepts_tab = false,
wrap_mode = WrapMode.WORD_CHAR
};
recount_chars.connect (() => {
remaining_chars -= editor.buffer.get_char_count ();
});
content.prepend (editor);
char_counter = new Label (char_limit.to_string ()) {
margin_end = 6
};
char_counter.add_css_class ("heading");
bottom_bar.pack_end (char_counter);
editor.buffer.changed.connect (validate);
}
protected void populate_editor () {
editor.buffer.text = dialog.status.content;
}
protected ToggleButton cw_button;
protected Entry cw_entry;
protected void install_cw () {
cw_entry = new Gtk.Entry () {
placeholder_text = _("Write your warning here"),
margin_top = 6,
margin_end = 6,
margin_start = 6
};
cw_entry.buffer.inserted_text.connect (validate);
cw_entry.buffer.deleted_text.connect (validate);
var revealer = new Gtk.Revealer () {
child = cw_entry
};
revealer.add_css_class ("view");
content.prepend (revealer);
cw_button = new ToggleButton () {
icon_name = "dialog-warning-symbolic",
tooltip_text = _("Spoiler Warning")
};
cw_button.toggled.connect (validate);
cw_button.bind_property ("active", revealer, "reveal_child", GLib.BindingFlags.SYNC_CREATE);
add_button (cw_button);
recount_chars.connect (() => {
if (cw_button.active)
remaining_chars -= (int) cw_entry.buffer.length;
});
}
protected DropDown visibility_button;
protected void install_visibility () {
visibility_button = new DropDown (accounts.active.visibility_list, null) {
expression = new PropertyExpression (typeof (InstanceAccount.Visibility), null, "name"),
factory = new BuilderListItemFactory.from_resource (null, Build.RESOURCES+"gtk/dropdown/icon.ui"),
list_factory = new BuilderListItemFactory.from_resource (null, Build.RESOURCES+"gtk/dropdown/full.ui")
};
add_button (visibility_button);
add_button (new Gtk.Separator (Orientation.VERTICAL));
}
}

View File

@ -0,0 +1,54 @@
using Gtk;
public class Tootle.ComposerPage : Gtk.Box {
public string title { get; set; }
public string icon_name { get; set; }
public uint badge_number { get; set; default = 0; }
protected weak Dialogs.Compose dialog;
protected weak API.Status status;
ScrolledWindow scroller;
protected Box content;
protected ActionBar bottom_bar;
construct {
orientation = Orientation.VERTICAL;
scroller = new ScrolledWindow () {
hexpand = true,
vexpand = true
};
append (scroller);
content = new Box (Orientation.VERTICAL, 0);
scroller.child = content;
bottom_bar = new ActionBar () {
visible = false
};
append (bottom_bar);
}
protected void add_button (Widget widget) {
bottom_bar.pack_start (widget);
widget.add_css_class ("flat");
for (var w = widget.get_first_child (); w != null; w = w.get_next_sibling ()) {
w.add_css_class ("flat");
}
bottom_bar.show ();
}
// This is used to populate the UI with the status entity data
public virtual void on_build (Dialogs.Compose dialog, API.Status status) {
this.dialog = dialog;
this.status = status;
}
// This is used to push data back to the status entity
public virtual void on_sync () {}
public virtual void on_modify_req (Request req) {}
}

View File

@ -0,0 +1,11 @@
public class Tootle.PollPage : ComposerPage {
public PollPage () {
Object (
title: _("Options"),
icon_name: "view-list-bullet-symbolic",
visible: false
);
}
}

View File

@ -1,38 +0,0 @@
using Gtk;
public interface Tootle.Dialogs.ISavedWindow : Window {
public void restore_state () {
var settings = new Settings ();
configure_window (settings);
configure_event.connect ((ev) => on_configure (ev, settings));
}
public bool on_configure (Gdk.EventConfigure event, Settings settings) {
int x, y, w, h;
get_position (out x, out y);
get_size (out w, out h);
settings.window_x = x;
settings.window_y = y;
settings.window_w = w;
settings.window_h = h;
return false;
}
public void configure_window (Settings settings) {
var x = settings.window_x;
var y = settings.window_y;
var w = settings.window_w;
var h = settings.window_h;
if (x + y > 0)
this.move (x, y);
if (h + w > 0) {
this.default_width = w;
this.default_height = h;
}
}
}

62
src/Dialogs/ListEditor.vala Normal file → Executable file
View File

@ -1,7 +1,7 @@
using Gtk;
[GtkTemplate (ui = "/com/github/bleakgrey/tootle/ui/dialogs/list_editor.ui")]
public class Tootle.Dialogs.ListEditor: Hdy.Window {
public class Tootle.Dialogs.ListEditor: Adw.Window {
[GtkTemplate (ui = "/com/github/bleakgrey/tootle/ui/widgets/list_editor_item.ui")]
class Item : ListBoxRow {
@ -10,12 +10,9 @@ public class Tootle.Dialogs.ListEditor: Hdy.Window {
public API.Account acc { get; construct set; }
public bool committed { get; construct set; }
[GtkChild]
Widgets.RichLabel label;
[GtkChild]
Widgets.RichLabel handle;
[GtkChild]
ToggleButton status;
[GtkChild] unowned Widgets.RichLabel label;
[GtkChild] unowned Widgets.RichLabel handle;
[GtkChild] unowned ToggleButton status;
public Item (ListEditor editor, API.Account acc, bool committed) {
this.editor = editor;
@ -59,26 +56,19 @@ public class Tootle.Dialogs.ListEditor: Hdy.Window {
public Gee.ArrayList<string> to_add = new Gee.ArrayList<string> ();
public Gee.ArrayList<string> to_remove = new Gee.ArrayList<string> ();
[GtkChild]
Button save_btn;
[GtkChild]
Stack save_btn_stack;
[GtkChild]
Entry name_entry;
[GtkChild]
SearchEntry search_entry;
[GtkChild]
ListBox listbox;
[GtkChild] unowned Button save_btn;
[GtkChild] unowned Stack save_btn_stack;
[GtkChild] unowned Entry name_entry;
[GtkChild] unowned SearchEntry search_entry;
[GtkChild] unowned ListBox listbox;
[GtkChild]
InfoBar infobar;
[GtkChild]
Label infobar_label;
[GtkChild] unowned InfoBar infobar;
[GtkChild] unowned Label infobar_label;
public signal void done ();
construct {
transient_for = window;
transient_for = app.main_window;
show ();
}
@ -163,13 +153,13 @@ public class Tootle.Dialogs.ListEditor: Hdy.Window {
void add_account (API.Account acc, bool added, int order = -1) {
var exists = false;
listbox.@foreach (w => {
var i = w as Item;
if (i != null) {
if (i.acc.id == acc.id)
exists = true;
}
});
// listbox.@foreach (w => {
// var i = w as Item;
// if (i != null) {
// if (i.acc.id == acc.id)
// exists = true;
// }
// });
if (!exists) {
var item = new Item (this, acc, added);
@ -178,13 +168,13 @@ public class Tootle.Dialogs.ListEditor: Hdy.Window {
}
void invalidate () {
listbox.@foreach (w => {
var i = w as Item;
if (i != null) {
if (!i.committed)
i.destroy ();
}
});
// listbox.@foreach (w => {
// var i = w as Item;
// if (i != null) {
// if (!i.committed)
// i.destroy ();
// }
// });
}

74
src/Dialogs/MainWindow.vala Normal file → Executable file
View File

@ -2,24 +2,25 @@ using Gtk;
using Gdk;
[GtkTemplate (ui = "/com/github/bleakgrey/tootle/ui/dialogs/main.ui")]
public class Tootle.Dialogs.MainWindow: Hdy.Window, ISavedWindow {
public class Tootle.Dialogs.MainWindow: Adw.ApplicationWindow, Saveable {
public const string ZOOM_CLASS = "ttl-scalable";
[GtkChild]
Hdy.Deck deck;
[GtkChild] public unowned Adw.Flap flap;
[GtkChild] unowned Adw.Leaflet leaflet;
[GtkChild] unowned Views.Sidebar sidebar;
Views.Base? last_view = null;
construct {
construct_saveable (settings);
var gtk_settings = Gtk.Settings.get_default ();
settings.bind_property ("dark-theme", gtk_settings, "gtk-application-prefer-dark-theme", BindingFlags.SYNC_CREATE);
settings.notify["post-text-size"].connect (() => on_zoom_level_changed ());
on_zoom_level_changed ();
deck.notify["visible-child"].connect (on_view_changed);
button_press_event.connect (on_button_press);
restore_state ();
// button_press_event.connect (on_button_press);
}
public MainWindow (Gtk.Application app) {
@ -27,47 +28,36 @@ public class Tootle.Dialogs.MainWindow: Hdy.Window, ISavedWindow {
application: app,
icon_name: Build.DOMAIN,
title: Build.NAME,
resizable: true,
window_position: WindowPosition.CENTER
resizable: true
);
open_view (new Views.Main ());
}
public Views.Base open_view (Views.Base view) {
deck.add (view);
deck.visible_child = view;
leaflet.append (view);
leaflet.visible_child = view;
return view;
}
public bool back () {
deck.navigate (Hdy.NavigationDirection.BACK);
leaflet.navigate (Adw.NavigationDirection.BACK);
return true;
}
[GtkCallback]
void on_child_transition () {
if (deck.transition_running)
return;
// public override bool delete_event (Gdk.EventAny event) {
// window = null;
// return app.on_window_closed ();
// }
Widget unused_child;
while ((unused_child = deck.get_adjacent_child (Hdy.NavigationDirection.FORWARD)) != null)
unused_child.destroy ();
}
//FIXME: switch timelines with 1-4. Should be moved to Views.TabbedBase
public void switch_timeline (int32 num) {}
public override bool delete_event (Gdk.EventAny event) {
window = null;
return app.on_window_closed ();
}
[Deprecated]
public void switch_timeline (int32 num) {
}
bool on_button_press (EventButton ev) {
if (ev.button == 8)
return back ();
return false;
}
//FIXME: Handle back mouse button
// bool on_button_press (EventButton ev) {
// if (ev.button == 8)
// return back ();
// return false;
// }
void on_zoom_level_changed () {
try {
@ -82,15 +72,17 @@ public class Tootle.Dialogs.MainWindow: Hdy.Window, ISavedWindow {
""".printf (ZOOM_CLASS, scale);
}
app.zoom_css_provider.load_from_data (css);
// app.zoom_css_provider.load_from_data (css.data);
}
catch (Error e) {
warning (@"Can't set zoom level: $(e.message)");
}
}
[GtkCallback]
void on_view_changed () {
var view = deck.visible_child as Views.Base;
var view = leaflet.visible_child as Views.Base;
on_child_transition ();
if (last_view != null) {
last_view.current = false;
@ -105,4 +97,16 @@ public class Tootle.Dialogs.MainWindow: Hdy.Window, ISavedWindow {
last_view = view;
}
[GtkCallback]
void on_child_transition () {
if (leaflet.child_transition_running)
return;
Widget unused_child = null;
while ((unused_child = leaflet.get_adjacent_child (Adw.NavigationDirection.FORWARD)) != null) {
leaflet.remove (unused_child);
unused_child.dispose ();
}
}
}

85
src/Dialogs/NewAccount.vala Normal file → Executable file
View File

@ -1,7 +1,7 @@
using Gtk;
[GtkTemplate (ui = "/com/github/bleakgrey/tootle/ui/dialogs/new_account.ui")]
public class Tootle.Dialogs.NewAccount: Hdy.Window {
public class Tootle.Dialogs.NewAccount: Adw.Window {
const string scopes = "read write follow";
@ -10,42 +10,31 @@ public class Tootle.Dialogs.NewAccount: Hdy.Window {
protected bool use_auto_auth { get; set; default = true; }
protected InstanceAccount account { get; set; default = new InstanceAccount.empty (""); }
[GtkChild]
Button back_button;
[GtkChild]
Button next_button;
[GtkChild] unowned Adw.Leaflet deck;
[GtkChild] unowned Box instance_step;
[GtkChild] unowned Box code_step;
[GtkChild] unowned Box done_step;
[GtkChild]
Stack stack;
[GtkChild]
Box instance_step;
[GtkChild]
Box code_step;
[GtkChild]
Box done_step;
[GtkChild]
Entry instance_entry;
[GtkChild]
Entry code_entry;
[GtkChild]
Label code_label;
[GtkChild]
Label hello_label;
[GtkChild] unowned Entry instance_entry;
[GtkChild] unowned Entry code_entry;
[GtkChild] unowned Label code_label;
[GtkChild] unowned Adw.StatusPage done_page;
public NewAccount () {
Object (transient_for: window);
StyleContext.add_provider_for_screen (Gdk.Screen.get_default (), app.css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
Object (transient_for: app.main_window);
app.add_account_window = this;
app.add_window (this);
// StyleContext.add_provider_for_screen (Gdk.Screen.get_default (), app.css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
reset ();
present ();
new_account_window = this;
bind_property ("use-auto-auth", code_label, "visible", BindingFlags.SYNC_CREATE);
}
public override bool delete_event (Gdk.EventAny event) {
new_account_window = null;
return app.on_window_closed ();
public override bool close_request () {
warning ("CLose Request");
app.add_account_window = null;
return base.close_request ();
}
string setup_redirect_uri () {
@ -75,15 +64,7 @@ public class Tootle.Dialogs.NewAccount: Hdy.Window {
void reset () {
message ("Reset state");
account = new InstanceAccount.empty (account.instance);
stack.visible_child = instance_step;
invalidate ();
}
void invalidate () {
next_button.sensitive = !is_working;
next_button.label = stack.visible_child == done_step ? _("Done") : _("Next");
back_button.label = stack.visible_child == done_step ? _("Add Another") : _("Back");
back_button.visible = stack.visible_child != instance_step;
deck.visible_child = instance_step;
}
void oopsie (string title, string msg = "") {
@ -92,13 +73,13 @@ public class Tootle.Dialogs.NewAccount: Hdy.Window {
}
async void step () throws Error {
if (stack.visible_child == done_step) {
if (deck.visible_child == done_step) {
app.present_window ();
destroy ();
return;
}
if (stack.visible_child == instance_step) {
if (deck.visible_child == instance_step) {
setup_instance ();
yield accounts.guess_backend (account);
}
@ -112,7 +93,7 @@ public class Tootle.Dialogs.NewAccount: Hdy.Window {
}
void setup_instance () throws Error {
message ("Checking instance");
message ("Checking instance URL");
var str = instance_entry.text
.replace ("/", "")
@ -132,9 +113,9 @@ public class Tootle.Dialogs.NewAccount: Hdy.Window {
var msg = new Request.POST (@"/api/v1/apps")
.with_account (account)
.with_form_data ("client_name", Build.NAME)
.with_form_data ("website", Build.WEBSITE)
.with_form_data ("redirect_uris", redirect_uri = setup_redirect_uri ())
.with_form_data ("scopes", scopes)
.with_form_data ("redirect_uris", redirect_uri = setup_redirect_uri ());
.with_form_data ("website", Build.WEBSITE);
yield msg.await ();
var root = network.parse (msg);
@ -142,7 +123,7 @@ public class Tootle.Dialogs.NewAccount: Hdy.Window {
account.client_secret = root.get_string_member ("client_secret");
message ("OK: Instance registered client");
stack.visible_child = code_step;
deck.visible_child = code_step;
open_confirmation_page ();
}
@ -151,11 +132,11 @@ public class Tootle.Dialogs.NewAccount: Hdy.Window {
var pars = @"scope=$scopes&response_type=code&redirect_uri=$redirect_uri&client_id=$(account.client_id)";
var url = @"$(account.instance)/oauth/authorize?$pars";
Desktop.open_uri (url);
Host.open_uri (url);
}
async void request_token () throws Error {
if (code_entry.text.char_count () <= 1)
if (code_entry.text.char_count () <= 10)
throw new Oopsie.USER (_("Please enter a valid authorization code"));
message ("Requesting access token");
@ -181,8 +162,8 @@ public class Tootle.Dialogs.NewAccount: Hdy.Window {
message ("Saving account");
accounts.add (account);
hello_label.label = _("Hello, %s!").printf (account.handle);
stack.visible_child = done_step;
done_page.title = _("Hello, %s!").printf (account.handle);
deck.visible_child = done_step;
message ("Switching to account");
accounts.activate (account);
@ -206,7 +187,6 @@ public class Tootle.Dialogs.NewAccount: Hdy.Window {
if (is_working) return;
is_working = true;
invalidate ();
step.begin ((obj, res) => {
try {
step.end (res);
@ -218,7 +198,6 @@ public class Tootle.Dialogs.NewAccount: Hdy.Window {
oopsie (e.message);
}
is_working = false;
invalidate ();
});
}
@ -227,5 +206,13 @@ public class Tootle.Dialogs.NewAccount: Hdy.Window {
reset ();
}
[GtkCallback]
void on_visible_child_notify () {
if (!deck.child_transition_running && deck.visible_child == instance_step)
reset ();
deck.can_swipe_back = deck.visible_child != done_step;
}
}

45
src/Dialogs/Preferences.vala Normal file → Executable file
View File

@ -1,34 +1,26 @@
using Gtk;
[GtkTemplate (ui = "/com/github/bleakgrey/tootle/ui/dialogs/preferences.ui")]
public class Tootle.Dialogs.Preferences : Hdy.PreferencesWindow {
public class Tootle.Dialogs.Preferences : Adw.PreferencesWindow {
[GtkChild]
Switch dark_theme;
[GtkChild]
Switch autostart;
[GtkChild]
Switch work_in_background;
[GtkChild]
Hdy.ComboRow default_post_visibility;
[GtkChild]
SpinButton timeline_page_size;
[GtkChild]
SpinButton post_text_size;
[GtkChild]
Switch live_updates;
[GtkChild]
Switch public_live_updates;
[GtkChild] unowned Switch dark_theme;
[GtkChild] unowned Switch autostart;
[GtkChild] unowned Switch work_in_background;
[GtkChild] unowned SpinButton timeline_page_size;
[GtkChild] unowned SpinButton post_text_size;
[GtkChild] unowned Switch live_updates;
[GtkChild] unowned Switch public_live_updates;
construct {
transient_for = window;
transient_for = app.main_window;
default_post_visibility.set_for_enum (typeof (API.Visibility), e => {
var i = e.get_value ();
var vis = API.Visibility.all ()[i];
default_post_visibility.subtitle = vis.get_desc ();
return vis.get_name ();
});
// TODO: default_post_visibility options
// default_post_visibility.set_for_enum (typeof (API.Visibility), e => {
// var i = e.get_value ();
// var vis = API.Visibility.all ()[i];
// default_post_visibility.subtitle = vis.get_desc ();
// return vis.get_name ();
// });
bind ();
show ();
@ -42,11 +34,6 @@ public class Tootle.Dialogs.Preferences : Hdy.PreferencesWindow {
settings.bind ("dark-theme", dark_theme, "active", SettingsBindFlags.DEFAULT);
settings.bind ("autostart", autostart, "active", SettingsBindFlags.DEFAULT);
settings.bind ("work-in-background", work_in_background, "active", SettingsBindFlags.DEFAULT);
default_post_visibility.selected_index = (int) settings.default_post_visibility;
default_post_visibility.notify["selected-index"].connect (p => {
var i = default_post_visibility.selected_index;
settings.default_post_visibility = (API.Visibility) i;
});
settings.bind ("timeline-page-size", timeline_page_size.adjustment, "value", SettingsBindFlags.DEFAULT);
settings.bind ("post-text-size", post_text_size.adjustment, "value", SettingsBindFlags.DEFAULT);
settings.bind ("live-updates", live_updates, "active", SettingsBindFlags.DEFAULT);

10
src/Dialogs/Saveable.vala Executable file
View File

@ -0,0 +1,10 @@
using Gtk;
public interface Tootle.Dialogs.Saveable : Window {
protected void construct_saveable (GLib.Settings settings) {
settings.bind ("window-w", this, "default-width", SettingsBindFlags.DEFAULT);
settings.bind ("window-h", this, "default-height", SettingsBindFlags.DEFAULT);
}
}

View File

@ -1,16 +0,0 @@
using Gdk;
using GLib;
public class Tootle.Drawing {
public static void draw_rounded_rect (Cairo.Context ctx, double x, double y, double w, double h, double r) {
double degr = Math.PI / 180.0;
ctx.new_sub_path ();
ctx.arc (x + w - r, y + r, r, -90 * degr, 0 * degr);
ctx.arc (x + w - r, y + h - r, r, 0 * degr, 90 * degr);
ctx.arc (x + r, y + h - r, r, 90 * degr, 180 * degr);
ctx.arc (x + r, y + r, r, 180 * degr, 270 * degr);
ctx.close_path ();
}
}

View File

@ -0,0 +1,22 @@
public interface Tootle.AccountHolder : GLib.Object {
protected abstract InstanceAccount? account { get; set; default = null; }
protected void construct_account_holder () {
accounts.switched.connect (on_account_changed);
accounts.changed.connect (on_accounts_changed);
on_account_changed (accounts.active);
on_accounts_changed (accounts.saved);
}
protected void destruct_account_holder () {
accounts.switched.disconnect (on_account_changed);
accounts.changed.disconnect (on_accounts_changed);
}
protected virtual void on_account_changed (InstanceAccount? acc) {
this.account = acc;
}
protected virtual void on_accounts_changed (Gee.ArrayList<InstanceAccount> accounts) {}
}

8
src/Services/Accounts/AccountStore.vala Normal file → Executable file
View File

@ -47,14 +47,14 @@ public abstract class Tootle.AccountStore : GLib.Object {
public virtual void add (InstanceAccount account) throws GLib.Error {
message (@"Adding new account: $(account.handle)");
saved.add (account);
changed (saved);
save ();
account.subscribe ();
ensure_active_account ();
}
public virtual void remove (InstanceAccount account) throws GLib.Error {
message (@"Removing account: $(account.handle)");
account.unsubscribe ();
account.removed ();
saved.remove (account);
changed (saved);
save ();
@ -74,6 +74,9 @@ public abstract class Tootle.AccountStore : GLib.Object {
}
public void activate (InstanceAccount? account) {
if (active != null)
active.deactivated ();
if (account == null) {
message ("Reset active account");
return;
@ -95,6 +98,7 @@ public abstract class Tootle.AccountStore : GLib.Object {
}
accounts.active = account;
active.activated ();
switched (active);
}

View File

@ -1,66 +0,0 @@
using Gee;
public class Tootle.FileAccountStore : AccountStore {
string dir_path;
string file_path;
construct {
dir_path = @"$(GLib.Environment.get_user_config_dir ())/$(app.application_id)";
file_path = @"$dir_path/accounts.json";
}
public override void load () throws GLib.Error {
uint8[] data;
string etag;
var file = File.new_for_path (file_path);
file.load_contents (null, out data, out etag);
var contents = (string) data;
var parser = new Json.Parser ();
parser.load_from_data (contents, -1);
var array = parser.get_root ().get_array ();
array.foreach_element ((arr, i, node) => {
try {
var account = accounts.create_account (node);
saved.add (account);
}
catch (Error e) {
warning (@"Couldn't load account $i: $(e.message)");
}
});
message (@"Loaded $(saved.size) accounts");
}
public override void save () throws GLib.Error {
var dir = File.new_for_path (dir_path);
if (!dir.query_exists ())
dir.make_directory_with_parents ();
var file = File.new_for_path (file_path);
var builder = new Json.Builder ();
builder.begin_array ();
saved.foreach ((acc) => {
var node = acc.to_json ();
builder.add_value (node);
return true;
});
builder.end_array ();
var generator = new Json.Generator ();
generator.set_root (builder.get_root ());
var data = generator.to_data (null);
if (file.query_exists ())
file.@delete ();
FileOutputStream stream = file.create (FileCreateFlags.PRIVATE);
stream.write (data.data);
message (@"Saved $(saved.size) accounts");
}
}

View File

@ -1,18 +0,0 @@
public interface Tootle.IAccountHolder : GLib.Object {
protected abstract InstanceAccount? account { get; set; default = null; }
protected void account_listener_init () {
accounts.switched.connect (on_account_changed);
accounts.changed.connect (on_accounts_changed);
on_account_changed (accounts.active);
}
protected void account_listener_free () {
accounts.switched.disconnect (on_account_changed);
accounts.changed.disconnect (on_accounts_changed);
}
public virtual void on_account_changed (InstanceAccount? account) {}
public virtual void on_accounts_changed (Gee.ArrayList<InstanceAccount> accounts) {}
}

180
src/Services/Accounts/InstanceAccount.vala Normal file → Executable file
View File

@ -1,51 +1,90 @@
using GLib;
using Gee;
public class Tootle.InstanceAccount : API.Account, IStreamListener {
public class Tootle.InstanceAccount : API.Account, Streamable {
public const string EVENT_NEW_POST = "update";
public const string EVENT_DELETE_POST = "delete";
public const string EVENT_NOTIFICATION = "notification";
public string? backend { set; get; }
public string? instance { get; set; }
public string? client_id { get; set; }
public string? client_secret { get; set; }
public string? access_token { get; set; }
public Error? error { get; set; }
public int64 last_seen_notification { get; set; default = 0; }
public bool has_unread_notifications { get; set; default = false; }
public ArrayList<API.Notification> cached_notifications { get; set; default = new ArrayList<API.Notification> (); }
protected string? stream;
public Error? error { get; set; } //TODO: use this field when server invalidates the auth token
public new string handle {
owned get { return @"@$username@$domain"; }
}
public bool is_active {
get { return accounts.active.access_token == access_token; }
}
public HashMap<Type,Type> type_overrides = new HashMap<Type,Type> ();
public virtual signal void activated () {}
public virtual signal void deactivated () {}
public virtual signal void added () {
subscribed = true;
check_notifications ();
}
public virtual signal void removed () {
subscribed = false;
}
construct {
on_notification.connect (show_notification);
construct_streamable ();
stream_event[EVENT_NOTIFICATION].connect (on_notification_event);
}
~InstanceAccount () {
destruct_streamable ();
}
public InstanceAccount.empty (string instance){
Object (id: "", instance: instance);
}
~InstanceAccount () {
unsubscribe ();
Object (
id: "",
instance: instance
);
}
public bool is_current () {
return accounts.active.access_token == access_token;
// Visibility options
public class Visibility : Object {
public string id { get; construct set; }
public string name { get; construct set; }
public string icon_name { get; construct set; }
public string description { get; construct set; }
}
public HashMap<string,Visibility> visibility = new HashMap<string,Visibility> ();
public ListStore visibility_list = new ListStore (typeof (Visibility));
public void set_visibility (Visibility obj) {
this.visibility[obj.id] = obj;
visibility_list.append (obj);
}
// TODO: This should be IStreamable
public string get_stream_url () {
return @"$instance/api/v1/streaming/?stream=user&access_token=$access_token";
// Core functions
public T create_entity<T> (Json.Node node) throws Error {
var type = typeof (T);
if (type_overrides.has_key (type))
type = type_overrides[type];
return Entity.from_json (type, node);
}
public void subscribe () {
streams.subscribe (get_stream_url (), this, out stream);
}
public Entity create_dynamic_entity (Type type, Json.Node node) throws Error {
if (type_overrides.has_key (type))
type = type_overrides[type];
public void unsubscribe () {
streams.unsubscribe (stream, this);
return Entity.from_json (type, node);
}
public async void verify_credentials () throws Error {
@ -67,19 +106,92 @@ public class Tootle.InstanceAccount : API.Account, IStreamListener {
return entity;
}
// TODO: notification actions
void show_notification (API.Notification obj) {
var title = HtmlUtils.remove_tags (obj.kind.get_desc (obj.account));
var notification = new GLib.Notification (title);
if (obj.status != null) {
var body = "";
body += domain;
body += "\n";
body += HtmlUtils.remove_tags (obj.status.content);
notification.set_body (body);
public virtual void populate_user_menu (GLib.ListStore model) {}
public virtual void describe_kind (string kind, out string? icon, out string? descr, API.Account account) {
icon = null;
descr = null;
}
// Notifications
public int unread_count { get; set; default = 0; }
public int last_read_id { get; set; default = 0; }
public int last_received_id { get; set; default = 0; }
public HashMap<int,GLib.Notification> unread_toasts { get; set; default = new HashMap<int,GLib.Notification> (); }
public ArrayList<Object> notification_inhibitors { get; set; default = new ArrayList<Object> (); }
public virtual void check_notifications () {
new Request.GET ("/api/v1/markers?timeline[]=notifications")
.with_account (this)
.then ((sess, msg) => {
var root = network.parse (msg);
var notifications = root.get_object_member ("notifications");
last_read_id = int.parse (notifications.get_string_member ("last_read_id") );
})
.exec ();
}
public void read_notifications (int up_to_id) {
message (@"Reading notifications up to id $up_to_id");
if (up_to_id > last_read_id) {
last_read_id = up_to_id;
// TODO: Actually send read req to the instance
}
app.send_notification (app.application_id + ":" + obj.id.to_string (), notification);
unread_toasts.@foreach (entry => {
var id = entry.key;
read_notification (id);
return true;
});
}
public void read_notification (int id) {
if (id <= last_read_id) {
message (@"Read notification with id: $id");
app.withdraw_notification (id.to_string ());
unread_toasts.unset (id);
}
unread_count = unread_toasts.size;
}
public void send_toast (API.Notification obj) {
var toast = obj.to_toast (this);
var id = obj.id;
app.send_notification (id, toast);
unread_toasts.set (int.parse (id), toast);
}
// Streamable
public string? _connection_url { get; set; }
public bool subscribed { get; set; }
public virtual string? get_stream_url () {
return @"$instance/api/v1/streaming/?stream=user&access_token=$access_token";
}
public virtual void on_notification_event (Streamable.Event ev) {
var entity = create_entity<API.Notification> (ev.get_node ());
var id = int.parse (entity.id);
if (id > last_received_id) {
last_received_id = id;
if (notification_inhibitors.is_empty) {
unread_count++;
send_toast (entity);
}
else {
read_notifications (last_received_id);
}
}
}
}

View File

@ -0,0 +1,149 @@
public class Tootle.Mastodon.Account : InstanceAccount {
public const string BACKEND = "Mastodon";
public const string KIND_MENTION = "mention";
public const string KIND_REBLOG = "reblog";
public const string KIND_FAVOURITE = "favourite";
public const string KIND_FOLLOW = "follow";
public const string KIND_POLL = "poll";
public const string KIND_FOLLOW_REQUEST = "__follow-request";
public const string KIND_REMOTE_REBLOG = "__remote-reblog";
class Test : AccountStore.BackendTest {
public override string? get_backend (Json.Object obj) {
return BACKEND; // Always treat instances as compatible with Mastodon
}
}
public static void register (AccountStore store) {
store.backend_tests.add (new Test ());
store.create_for_backend[BACKEND].connect ((node) => {
var account = Entity.from_json (typeof (Account), node) as Account;
account.backend = BACKEND;
return account;
});
}
public Views.Sidebar.Item notifications_item;
construct {
notifications_item = new Views.Sidebar.Item () {
label = "Notifications",
icon = "bell-symbolic",
on_activated = () => {
app.main_window.open_view (new Views.Notifications ());
}
};
bind_property ("unread_count", notifications_item, "badge", BindingFlags.SYNC_CREATE);
// Populate possible visibility variants
set_visibility (new Visibility () {
id = "public",
name = _("Public"),
icon_name = "globe-symbolic",
description = _("Post to public timelines")
});
set_visibility (new Visibility () {
id = "unlisted",
name = _("Unlisted"),
icon_name = "changes-allow-symbolic",
description = _("Don\'t post to public timelines")
});
set_visibility (new Visibility () {
id = "private",
name = _("Followers-only"),
icon_name = "changes-prevent-symbolic",
description = _("Post to followers only")
});
set_visibility (new Visibility () {
id = "direct",
name = _("Direct"),
icon_name = "mail-unread-symbolic",
description = _("Post to mentioned users only")
});
}
public override void populate_user_menu (GLib.ListStore model) {
// model.append (new Views.Sidebar.Item () {
// label = "Timelines",
// icon = "user-home-symbolic"
// });
model.append (notifications_item);
model.append (new Views.Sidebar.Item () {
label = "Direct Messages",
icon = "mail-unread-symbolic",
on_activated = () => {
app.main_window.open_view (new Views.Conversations ());
}
});
model.append (new Views.Sidebar.Item () {
label = "Bookmarks",
icon = "user-bookmarks-symbolic",
on_activated = () => {
app.main_window.open_view (new Views.Bookmarks ());
}
});
model.append (new Views.Sidebar.Item () {
label = "Favorites",
icon = "non-starred-symbolic",
on_activated = () => {
app.main_window.open_view (new Views.Favorites ());
}
});
model.append (new Views.Sidebar.Item () {
label = "Lists",
icon = "view-list-symbolic",
on_activated = () => {
app.main_window.open_view (new Views.Lists ());
}
});
model.append (new Views.Sidebar.Item () {
label = "Search",
icon = "system-search-symbolic",
on_activated = () => {
app.main_window.open_view (new Views.Search ());
}
});
}
public override void describe_kind (string kind, out string? icon, out string? descr, API.Account account) {
switch (kind) {
case KIND_MENTION:
icon = "user-available-symbolic";
descr = _("<span underline=\"none\"><a href=\"%s\">%s</a> mentioned you</span>").printf (account.url, account.display_name);
break;
case KIND_REBLOG:
icon = "media-playlist-repeat-symbolic";
descr = _("<span underline=\"none\"><a href=\"%s\">%s</a> boosted your status</span>").printf (account.url, account.display_name);
break;
case KIND_REMOTE_REBLOG:
icon = "media-playlist-repeat-symbolic";
descr = _("<span underline=\"none\"><a href=\"%s\">%s</a> boosted</span>").printf (account.url, account.display_name);
break;
case KIND_FAVOURITE:
icon = "starred-symbolic";
descr = _("<span underline=\"none\"><a href=\"%s\">%s</a> favorited your status</span>").printf (account.url, account.display_name);
break;
case KIND_FOLLOW:
icon = "contact-new-symbolic";
descr = _("<span underline=\"none\"><a href=\"%s\">%s</a> now follows you</span>").printf (account.url, account.display_name);
break;
case KIND_FOLLOW_REQUEST:
icon = "contact-new-symbolic";
descr = _("<span underline=\"none\"><a href=\"%s\">%s</a> wants to follow you</span>").printf (account.url, account.display_name);
break;
case KIND_POLL:
icon = "emblem-default-symbolic";
descr = _("Poll results");
break;
default:
icon = null;
descr = null;
break;
}
}
}

View File

@ -1,22 +0,0 @@
public class Tootle.Mastodon.Account : InstanceAccount {
public const string BACKEND = "Mastodon";
class Test : AccountStore.BackendTest {
public override string? get_backend (Json.Object obj) {
return BACKEND; // Always treat instances as compatible with Mastodon
}
}
public static void register (AccountStore store) {
store.backend_tests.add (new Test ());
store.create_for_backend[BACKEND].connect ((node) => {
var account = Entity.from_json (typeof (Account), node) as Account;
account.backend = BACKEND;
return account;
});
}
}

5
src/Services/Accounts/SecretAccountStore.vala Normal file → Executable file
View File

@ -35,9 +35,12 @@ public class Tootle.SecretAccountStore : AccountStore {
secrets.foreach (item => {
var account = secret_to_account (item);
if (account != null)
if (account != null) {
saved.add (account);
account.added ();
}
});
changed (saved);
message (@"Loaded $(saved.size) accounts");
}

Some files were not shown because too many files have changed in this diff Show More