Basic loading of blueprints and schema
This commit is contained in:
parent
0bc7d717f6
commit
ce765e30cf
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
/target
|
/target
|
||||||
/Cargo.lock
|
/Cargo.lock
|
||||||
|
.dir-locals.el
|
||||||
|
1
simplelogin-gui/.gitignore
vendored
Normal file
1
simplelogin-gui/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/res/gschemas.compiled
|
@ -6,3 +6,6 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
gtk4 = { version = "0.7.3", features = ["blueprint"] }
|
||||||
|
simplelogin = { version = "0.1.0", path = "../simplelogin" }
|
||||||
|
tokio = { version = "1.33.0", features = ["full"] }
|
||||||
|
29
simplelogin-gui/build.rs
Normal file
29
simplelogin-gui/build.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
use std::{env, io, fs, path::Path, process::Command};
|
||||||
|
|
||||||
|
const SCHEMA_NAME: &'static str = "im.zander.SimpleLogin.gschema.xml";
|
||||||
|
|
||||||
|
fn main() -> io::Result<()> {
|
||||||
|
println!("cargo:rerun-if-changed=data/{}", SCHEMA_NAME);
|
||||||
|
#[cfg(debug_assertions)] {
|
||||||
|
let out_dir = env::var("OUT_DIR").unwrap();
|
||||||
|
let source_path = Path::new("data/").join(SCHEMA_NAME);
|
||||||
|
let compile_dir = Path::new(&out_dir).join("schemas");
|
||||||
|
let compile_path = compile_dir.join(SCHEMA_NAME);
|
||||||
|
eprintln!("Creating \"{}\"...", compile_dir.display());
|
||||||
|
fs::create_dir_all(&compile_dir)?;
|
||||||
|
eprintln!(
|
||||||
|
"Copping \"{}\" to \"{}\"...",
|
||||||
|
source_path.display(),
|
||||||
|
compile_path.display()
|
||||||
|
);
|
||||||
|
fs::copy(source_path, &compile_path)?;
|
||||||
|
eprintln!("Compiling schemas...");
|
||||||
|
let status = Command::new("glib-compile-schemas")
|
||||||
|
.args(["--strict", compile_dir.to_str().unwrap()])
|
||||||
|
.status()?;
|
||||||
|
if !status.success() {
|
||||||
|
panic!("failed to compile schemas");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
13
simplelogin-gui/data/im.zander.SimpleLogin.gschema.xml
Normal file
13
simplelogin-gui/data/im.zander.SimpleLogin.gschema.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<schemalist>
|
||||||
|
<schema id="im.zander.SimpleLogin" path="/im/zander/SimpleLogin/">
|
||||||
|
<key name="api-key" type="s">
|
||||||
|
<default>""</default>
|
||||||
|
<summary>Api key</summary>
|
||||||
|
<description>The api key for the current user</description>
|
||||||
|
</key>
|
||||||
|
<key name="window-size" type="(ii)">
|
||||||
|
<default>(-1,-1)</default>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
</schemalist>
|
240
simplelogin-gui/data/login_window.blp
Normal file
240
simplelogin-gui/data/login_window.blp
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
using Gtk 4.0;
|
||||||
|
|
||||||
|
Popover device_entry_popover {
|
||||||
|
child: Label {
|
||||||
|
accessible-role: tooltip;
|
||||||
|
label: "This is the human readable name that will show up in the API key section of the SimpleLogin website.";
|
||||||
|
max-width-chars: 30;
|
||||||
|
wrap: true;
|
||||||
|
}
|
||||||
|
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
template $LoginWindow : ApplicationWindow {
|
||||||
|
title: "SimpleLogin";
|
||||||
|
|
||||||
|
Box {
|
||||||
|
orientation: vertical;
|
||||||
|
|
||||||
|
Overlay forms_overlay {
|
||||||
|
child: forms_wrapper;
|
||||||
|
valign: end;
|
||||||
|
vexpand: true;
|
||||||
|
|
||||||
|
Box forms_wrapper {
|
||||||
|
valign: end;
|
||||||
|
vexpand: true;
|
||||||
|
|
||||||
|
Grid {
|
||||||
|
halign: end;
|
||||||
|
hexpand: true;
|
||||||
|
margin-bottom: 10;
|
||||||
|
margin-end: 10;
|
||||||
|
margin-start: 10;
|
||||||
|
margin-top: 10;
|
||||||
|
valign: center;
|
||||||
|
|
||||||
|
Label {
|
||||||
|
hexpand: true;
|
||||||
|
label: "Login:";
|
||||||
|
margin-bottom: 5;
|
||||||
|
vexpand: true;
|
||||||
|
|
||||||
|
styles [
|
||||||
|
"login-title-label",
|
||||||
|
]
|
||||||
|
|
||||||
|
layout {
|
||||||
|
column: "0";
|
||||||
|
column-span: "2";
|
||||||
|
row: "0";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label error_label {
|
||||||
|
label: "ERROR";
|
||||||
|
margin-top: 5;
|
||||||
|
|
||||||
|
styles [
|
||||||
|
"error-message-label",
|
||||||
|
]
|
||||||
|
|
||||||
|
layout {
|
||||||
|
column: "0";
|
||||||
|
column-span: "2";
|
||||||
|
row: "4";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Entry device_entry {
|
||||||
|
margin-start: 6;
|
||||||
|
placeholder-text: "My Awesome Computer";
|
||||||
|
secondary-icon-name: "dialog-question-symbolic";
|
||||||
|
truncate-multiline: true;
|
||||||
|
width-chars: 18;
|
||||||
|
|
||||||
|
layout {
|
||||||
|
column: "1";
|
||||||
|
row: "3";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
label: "Device:";
|
||||||
|
xalign: 0.0;
|
||||||
|
|
||||||
|
layout {
|
||||||
|
column: "0";
|
||||||
|
row: "3";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
label: "Email:";
|
||||||
|
xalign: 0.0;
|
||||||
|
|
||||||
|
layout {
|
||||||
|
column: "0";
|
||||||
|
row: "1";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
label: "Password:";
|
||||||
|
xalign: 0.0;
|
||||||
|
|
||||||
|
layout {
|
||||||
|
column: "0";
|
||||||
|
row: "2";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Entry email_entry {
|
||||||
|
hexpand: true;
|
||||||
|
input-purpose: email;
|
||||||
|
margin-start: 6;
|
||||||
|
receives-default: true;
|
||||||
|
truncate-multiline: true;
|
||||||
|
|
||||||
|
styles [
|
||||||
|
]
|
||||||
|
|
||||||
|
layout {
|
||||||
|
column: "1";
|
||||||
|
row: "1";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PasswordEntry password_entry {
|
||||||
|
hexpand: true;
|
||||||
|
margin-start: 6;
|
||||||
|
show-peek-icon: true;
|
||||||
|
|
||||||
|
layout {
|
||||||
|
column: "1";
|
||||||
|
row: "2";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button login_button {
|
||||||
|
halign: center;
|
||||||
|
label: "Login";
|
||||||
|
margin-top: 5;
|
||||||
|
sensitive: false;
|
||||||
|
valign: center;
|
||||||
|
|
||||||
|
layout {
|
||||||
|
column: "0";
|
||||||
|
column-span: "2";
|
||||||
|
row: "5";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
styles [
|
||||||
|
"login-form-warpper",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
halign: center;
|
||||||
|
justify: center;
|
||||||
|
label: "- or -";
|
||||||
|
}
|
||||||
|
|
||||||
|
Box {
|
||||||
|
halign: start;
|
||||||
|
hexpand: true;
|
||||||
|
margin-bottom: 10;
|
||||||
|
margin-end: 10;
|
||||||
|
margin-start: 10;
|
||||||
|
margin-top: 10;
|
||||||
|
orientation: vertical;
|
||||||
|
valign: center;
|
||||||
|
|
||||||
|
Label {
|
||||||
|
hexpand: true;
|
||||||
|
label: "Set API Key:";
|
||||||
|
margin-bottom: 5;
|
||||||
|
|
||||||
|
styles [
|
||||||
|
"login-title-label",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
PasswordEntry api_key_entry {
|
||||||
|
hexpand: true;
|
||||||
|
margin-end: 3;
|
||||||
|
margin-start: 8;
|
||||||
|
show-peek-icon: true;
|
||||||
|
width-chars: 27;
|
||||||
|
}
|
||||||
|
|
||||||
|
Button api_key_button {
|
||||||
|
halign: center;
|
||||||
|
label: "Accept";
|
||||||
|
margin-top: 5;
|
||||||
|
sensitive: false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
label: "Don\'t have an account? You can register <a href=\"https://app.simplelogin.io/auth/register\">here</a>.";
|
||||||
|
margin-bottom: 10;
|
||||||
|
use-markup: true;
|
||||||
|
valign: start;
|
||||||
|
vexpand: true;
|
||||||
|
yalign: 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Box loading_overlay {
|
||||||
|
orientation: vertical;
|
||||||
|
|
||||||
|
Spinner {
|
||||||
|
spinning: true;
|
||||||
|
valign: end;
|
||||||
|
vexpand: true;
|
||||||
|
|
||||||
|
styles [
|
||||||
|
"loading-label",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
label: "Loading...";
|
||||||
|
valign: start;
|
||||||
|
vexpand: true;
|
||||||
|
|
||||||
|
styles [
|
||||||
|
"loading-label",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
styles [
|
||||||
|
"loading-label",
|
||||||
|
]
|
||||||
|
}
|
121
simplelogin-gui/data/totp_window.blp
Normal file
121
simplelogin-gui/data/totp_window.blp
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
using Gtk 4.0;
|
||||||
|
|
||||||
|
template $TotpWindow : Window {
|
||||||
|
modal: true;
|
||||||
|
title: "TOTP Entry";
|
||||||
|
|
||||||
|
Overlay overlay {
|
||||||
|
child: form_wrapper;
|
||||||
|
halign: center;
|
||||||
|
hexpand: true;
|
||||||
|
valign: center;
|
||||||
|
vexpand: true;
|
||||||
|
|
||||||
|
Grid form_wrapper {
|
||||||
|
column-spacing: 5;
|
||||||
|
halign: center;
|
||||||
|
hexpand: true;
|
||||||
|
margin-bottom: 10;
|
||||||
|
margin-end: 10;
|
||||||
|
margin-start: 10;
|
||||||
|
margin-top: 10;
|
||||||
|
row-spacing: 5;
|
||||||
|
valign: center;
|
||||||
|
vexpand: true;
|
||||||
|
|
||||||
|
Box {
|
||||||
|
halign: center;
|
||||||
|
hexpand: true;
|
||||||
|
|
||||||
|
Image {
|
||||||
|
halign: center;
|
||||||
|
icon-name: "dialog-password-symbolic";
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
label: "TOTP";
|
||||||
|
|
||||||
|
styles [
|
||||||
|
"login-title-label",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
layout {
|
||||||
|
column: "0";
|
||||||
|
column-span: "2";
|
||||||
|
row: "0";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button accept_button {
|
||||||
|
label: "Accept";
|
||||||
|
|
||||||
|
layout {
|
||||||
|
column: "1";
|
||||||
|
row: "3";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button cancel_button {
|
||||||
|
label: "Cancel";
|
||||||
|
|
||||||
|
layout {
|
||||||
|
column: "0";
|
||||||
|
row: "3";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Entry code_entry {
|
||||||
|
placeholder-text: "TOTP Code";
|
||||||
|
|
||||||
|
layout {
|
||||||
|
column: "0";
|
||||||
|
column-span: "2";
|
||||||
|
row: "1";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label error_label {
|
||||||
|
label: "ERROR";
|
||||||
|
|
||||||
|
styles [
|
||||||
|
"error-message-label",
|
||||||
|
]
|
||||||
|
|
||||||
|
layout {
|
||||||
|
column: "0";
|
||||||
|
column-span: "2";
|
||||||
|
row: "2";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Box loading_overlay {
|
||||||
|
orientation: vertical;
|
||||||
|
|
||||||
|
Spinner {
|
||||||
|
spinning: true;
|
||||||
|
valign: end;
|
||||||
|
vexpand: true;
|
||||||
|
|
||||||
|
styles [
|
||||||
|
"loading-label",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
label: "Loading...";
|
||||||
|
valign: start;
|
||||||
|
vexpand: true;
|
||||||
|
|
||||||
|
styles [
|
||||||
|
"loading-label",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
styles [
|
||||||
|
"loading-label",
|
||||||
|
]
|
||||||
|
}
|
15
simplelogin-gui/res.old/global.css
Normal file
15
simplelogin-gui/res.old/global.css
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
.login-title-label {
|
||||||
|
font-size: x-large;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-message-label {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-label {
|
||||||
|
font-size: xx-large;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bold {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
188
simplelogin-gui/res.old/main-panel.ui
Normal file
188
simplelogin-gui/res.old/main-panel.ui
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<!-- Created with Cambalache 0.16.0 -->
|
||||||
|
<interface>
|
||||||
|
<!-- interface-name main-window.ui -->
|
||||||
|
<requires lib="gtk" version="4.12"/>
|
||||||
|
<template class="SLMainPanel" parent="GtkBox">
|
||||||
|
<child>
|
||||||
|
<object class="GtkOverlay" id="overlay">
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox" id="content_wrapper">
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<property name="vexpand">True</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<child>
|
||||||
|
<object class="GtkSearchEntry" id="search_box">
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<property name="placeholder-text">Filter by email, description, etc.</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkDropDown" id="view_dropdown">
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<property name="model">
|
||||||
|
<object class="GtkStringList">
|
||||||
|
<items>
|
||||||
|
<item>All aliases</item>
|
||||||
|
<item>Pinned only</item>
|
||||||
|
<item>Enabled only</item>
|
||||||
|
<item>Disabled only</item>
|
||||||
|
</items>
|
||||||
|
</object>
|
||||||
|
</property>
|
||||||
|
<property name="selected">0</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="search_button">
|
||||||
|
<property name="label">Search</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="new_button">
|
||||||
|
<property name="label">New</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="edit_button">
|
||||||
|
<property name="label">Edit</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="delete_button">
|
||||||
|
<property name="label">Delete</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="prev_page_button">
|
||||||
|
<property name="halign">end</property>
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<property name="icon-name">go-previous-symbolic</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkEntry" id="page_label">
|
||||||
|
<property name="has-frame">False</property>
|
||||||
|
<property name="input-hints">no-emoji | no-spellcheck</property>
|
||||||
|
<property name="input-purpose">digits</property>
|
||||||
|
<property name="max-width-chars">0</property>
|
||||||
|
<property name="text">1</property>
|
||||||
|
<property name="truncate-multiline">True</property>
|
||||||
|
<property name="width-chars">5</property>
|
||||||
|
<property name="xalign">0.5</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="next_page_button">
|
||||||
|
<property name="icon-name">go-next-symbolic</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkOverlay" id="scroll_overlay">
|
||||||
|
<child>
|
||||||
|
<object class="GtkScrolledWindow">
|
||||||
|
<property name="vexpand">True</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkListView" id="alias_list_view">
|
||||||
|
<property name="factory">
|
||||||
|
<object class="GtkSignalListItemFactory" id="alias_item_factory"/>
|
||||||
|
</property>
|
||||||
|
<property name="model">
|
||||||
|
<object class="GtkMultiSelection" id="alias_selection_model"/>
|
||||||
|
</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</template>
|
||||||
|
<object class="GtkBox" id="loading_overlay">
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSpinner">
|
||||||
|
<property name="spinning">True</property>
|
||||||
|
<property name="valign">end</property>
|
||||||
|
<property name="vexpand">True</property>
|
||||||
|
<style>
|
||||||
|
<class name="loading-label"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label">Loading...</property>
|
||||||
|
<property name="valign">start</property>
|
||||||
|
<property name="vexpand">True</property>
|
||||||
|
<style>
|
||||||
|
<class name="loading-label"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<style>
|
||||||
|
<class name="loading-label"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<object class="GtkLabel" id="no_content_label">
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<property name="label">No more results</property>
|
||||||
|
<property name="vexpand">True</property>
|
||||||
|
<style>
|
||||||
|
<class name="loading-label"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<object class="GtkBox" id="error_overlay">
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="halign">center</property>
|
||||||
|
<property name="valign">end</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="error_refresh_button">
|
||||||
|
<property name="halign">center</property>
|
||||||
|
<property name="icon-name">view-refresh-symbolic</property>
|
||||||
|
<property name="valign">end</property>
|
||||||
|
<property name="vexpand">True</property>
|
||||||
|
<style>
|
||||||
|
<class name="loading-label"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="error_close_button">
|
||||||
|
<property name="halign">center</property>
|
||||||
|
<property name="icon-name">window-close-symbolic</property>
|
||||||
|
<property name="valign">end</property>
|
||||||
|
<style>
|
||||||
|
<class name="loading-label"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="error_label">
|
||||||
|
<property name="label">ERROR</property>
|
||||||
|
<property name="valign">start</property>
|
||||||
|
<property name="vexpand">True</property>
|
||||||
|
<style>
|
||||||
|
<class name="error-message-label"/>
|
||||||
|
<class name="loading-label"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<!-- Custom fragments -->
|
||||||
|
</interface>
|
263
simplelogin-gui/res.old/settings-panel.ui
Normal file
263
simplelogin-gui/res.old/settings-panel.ui
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<!-- Created with Cambalache 0.16.0 -->
|
||||||
|
<interface>
|
||||||
|
<requires lib="gtk" version="4.12"/>
|
||||||
|
<template class="SLSettingsPanel" parent="GtkBox">
|
||||||
|
<child>
|
||||||
|
<object class="GtkOverlay" id="overlay">
|
||||||
|
<property name="child">content_wrapper</property>
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox" id="content_wrapper">
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<property name="vexpand">True</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkGrid" id="content">
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<property name="row-homogeneous">True</property>
|
||||||
|
<property name="valign">start</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="profile_image_button">
|
||||||
|
<property name="has-frame">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage" id="profile_image">
|
||||||
|
<property name="halign">center</property>
|
||||||
|
<property name="icon-name">user-info-symbolic</property>
|
||||||
|
<property name="icon-size">large</property>
|
||||||
|
<property name="margin-end">5</property>
|
||||||
|
<property name="valign">center</property>
|
||||||
|
<property name="vexpand">True</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<!-- Custom fragments -->
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="column-span">1</property>
|
||||||
|
<property name="row">0</property>
|
||||||
|
<property name="row-span">2</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="remove_picture_button">
|
||||||
|
<property name="icon-name">window-close-symbolic</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkEntry" id="name_label">
|
||||||
|
<property name="editable">False</property>
|
||||||
|
<property name="has-frame">False</property>
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<property name="input-hints">no-emoji | no-spellcheck</property>
|
||||||
|
<property name="text">Testy McTesterface</property>
|
||||||
|
<style>
|
||||||
|
<class name="login-title-label"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="column-span">1</property>
|
||||||
|
<property name="row">0</property>
|
||||||
|
<property name="row-span">1</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="edit_button">
|
||||||
|
<property name="halign">start</property>
|
||||||
|
<property name="label">Edit</property>
|
||||||
|
<property name="valign">center</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="cancel_edit_button">
|
||||||
|
<property name="label">Cancel</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<layout>
|
||||||
|
<property name="column">2</property>
|
||||||
|
<property name="column-span">1</property>
|
||||||
|
<property name="row">0</property>
|
||||||
|
<property name="row-span">1</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="stats_label">
|
||||||
|
<property name="halign">center</property>
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<property name="label">Stats go here</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="column-span">3</property>
|
||||||
|
<property name="row">2</property>
|
||||||
|
<property name="row-span">1</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="email_label">
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<property name="label">mctesterface@test.tld</property>
|
||||||
|
<property name="xalign">0.0</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="row">1</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="logout_button">
|
||||||
|
<property name="halign">start</property>
|
||||||
|
<property name="label">Logout</property>
|
||||||
|
<property name="valign">center</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">2</property>
|
||||||
|
<property name="row">1</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label">Account Status:</property>
|
||||||
|
<property name="margin-end">5</property>
|
||||||
|
<property name="xalign">1.0</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="column-span">1</property>
|
||||||
|
<property name="row">3</property>
|
||||||
|
<property name="row-span">1</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label">Api Key:</property>
|
||||||
|
<property name="margin-end">5</property>
|
||||||
|
<property name="xalign">1.0</property>
|
||||||
|
<attributes/>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">4</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkPasswordEntry" id="api_key_field">
|
||||||
|
<property name="editable">False</property>
|
||||||
|
<property name="enable-undo">False</property>
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<property name="show-peek-icon">True</property>
|
||||||
|
<property name="valign">center</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="row">4</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="status_label">
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<property name="label">Premium</property>
|
||||||
|
<property name="xalign">0.0</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="column-span">1</property>
|
||||||
|
<property name="row">3</property>
|
||||||
|
<property name="row-span">1</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="api_key_clear_button">
|
||||||
|
<property name="halign">start</property>
|
||||||
|
<property name="label">Clear</property>
|
||||||
|
<property name="valign">center</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">2</property>
|
||||||
|
<property name="row">4</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</template>
|
||||||
|
<object class="GtkBox" id="loading_overlay">
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSpinner">
|
||||||
|
<property name="spinning">True</property>
|
||||||
|
<property name="valign">end</property>
|
||||||
|
<property name="vexpand">True</property>
|
||||||
|
<style>
|
||||||
|
<class name="loading-label"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label">Loading...</property>
|
||||||
|
<property name="valign">start</property>
|
||||||
|
<property name="vexpand">True</property>
|
||||||
|
<style>
|
||||||
|
<class name="loading-label"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<style>
|
||||||
|
<class name="loading-label"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<object class="GtkBox" id="error_overlay">
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="halign">center</property>
|
||||||
|
<property name="valign">end</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="error_refresh_button">
|
||||||
|
<property name="halign">center</property>
|
||||||
|
<property name="icon-name">view-refresh-symbolic</property>
|
||||||
|
<property name="valign">end</property>
|
||||||
|
<property name="vexpand">True</property>
|
||||||
|
<style>
|
||||||
|
<class name="loading-label"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="error_close_button">
|
||||||
|
<property name="halign">center</property>
|
||||||
|
<property name="icon-name">window-close-symbolic</property>
|
||||||
|
<property name="valign">end</property>
|
||||||
|
<style>
|
||||||
|
<class name="loading-label"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="error_label">
|
||||||
|
<property name="label">ERROR</property>
|
||||||
|
<property name="valign">start</property>
|
||||||
|
<property name="vexpand">True</property>
|
||||||
|
<style>
|
||||||
|
<class name="error-message-label"/>
|
||||||
|
<class name="loading-label"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</interface>
|
531
simplelogin-gui/res.old/simplelogin.cmb
Normal file
531
simplelogin-gui/res.old/simplelogin.cmb
Normal file
@ -0,0 +1,531 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
|
||||||
|
<!DOCTYPE cambalache-project SYSTEM "cambalache-project.dtd">
|
||||||
|
<cambalache-project version="0.13.1" target_tk="gtk-4.0">
|
||||||
|
<ui>
|
||||||
|
(1,1,"main-window.ui","main-panel.ui",None,None,None,None,None,None,""),
|
||||||
|
(3,18,None,"settings-panel.ui",None,None,None,None,None,None,None),
|
||||||
|
(4,13,None,"login-window.ui",None,None,None,None,None,None,None),
|
||||||
|
(5,1,None,"totp-dialog.ui",None,None,None,None,None,None,None)
|
||||||
|
</ui>
|
||||||
|
<css>
|
||||||
|
(1,"global.css",None,1)
|
||||||
|
</css>
|
||||||
|
<css_ui>
|
||||||
|
(1,1),
|
||||||
|
(1,3),
|
||||||
|
(1,4),
|
||||||
|
(1,5)
|
||||||
|
</css_ui>
|
||||||
|
<object>
|
||||||
|
(1,1,"GtkBox","SLMainPanel",None,None,None,None,None,None),
|
||||||
|
(1,2,"GtkOverlay","overlay",1,None,None,None,None,None),
|
||||||
|
(1,3,"GtkBox","content_wrapper",2,None,None,None,None,None),
|
||||||
|
(1,4,"GtkBox",None,3,None,None,None,None,None),
|
||||||
|
(1,5,"GtkSearchEntry","search_box",4,None,None,None,None,None),
|
||||||
|
(1,8,"GtkDropDown","view_dropdown",4,None,None,None,1,None),
|
||||||
|
(1,9,"GtkStringList",None,8,None,None,None,None,None),
|
||||||
|
(1,10,"GtkButton","search_button",4,None,None,None,2,None),
|
||||||
|
(1,11,"GtkBox",None,3,None,None,None,1,None),
|
||||||
|
(1,12,"GtkButton","new_button",11,None,None,None,None,None),
|
||||||
|
(1,13,"GtkButton","edit_button",11,None,None,None,1,None),
|
||||||
|
(1,14,"GtkButton","delete_button",11,None,None,None,2,None),
|
||||||
|
(1,22,"GtkBox","loading_overlay",None,None,None,None,None,None),
|
||||||
|
(1,23,"GtkSpinner",None,22,None,None,None,None,None),
|
||||||
|
(1,24,"GtkLabel",None,22,None,None,None,1,None),
|
||||||
|
(1,28,"GtkButton","prev_page_button",11,None,None,None,3,None),
|
||||||
|
(1,29,"GtkButton","next_page_button",11,None,None,None,5,None),
|
||||||
|
(1,30,"GtkEntry","page_label",11,None,None,None,4,None),
|
||||||
|
(1,31,"GtkOverlay","scroll_overlay",3,None,None,None,2,None),
|
||||||
|
(1,32,"GtkScrolledWindow",None,31,None,None,None,None,None),
|
||||||
|
(1,33,"GtkListView","alias_list_view",32,None,None,None,None,None),
|
||||||
|
(1,34,"GtkSignalListItemFactory","alias_item_factory",33,None,None,None,None,None),
|
||||||
|
(1,35,"GtkMultiSelection","alias_selection_model",33,None,None,None,None,None),
|
||||||
|
(1,36,"GtkLabel","no_content_label",None,None,None,None,None,None),
|
||||||
|
(1,37,"GtkBox","error_overlay",None,None,None,None,None,None),
|
||||||
|
(1,38,"GtkBox",None,37,None,None,None,None,None),
|
||||||
|
(1,39,"GtkButton","error_refresh_button",38,None,None,None,None,None),
|
||||||
|
(1,40,"GtkButton","error_close_button",38,None,None,None,1,None),
|
||||||
|
(1,41,"GtkLabel","error_label",37,None,None,None,1,None),
|
||||||
|
(3,18,"GtkBox","SLSettingsPanel",None,None,None,None,None,None),
|
||||||
|
(3,19,"GtkOverlay","overlay",18,None,None,None,None,None),
|
||||||
|
(3,30,"GtkBox","loading_overlay",None,None,None,None,None,None),
|
||||||
|
(3,31,"GtkSpinner",None,30,None,None,None,None,None),
|
||||||
|
(3,32,"GtkLabel",None,30,None,None,None,1,None),
|
||||||
|
(3,33,"GtkBox","error_overlay",None,None,None,None,None,None),
|
||||||
|
(3,35,"GtkLabel","error_label",33,None,None,None,1,None),
|
||||||
|
(3,45,"GtkBox",None,33,None,None,None,None,None),
|
||||||
|
(3,46,"GtkButton","error_refresh_button",45,None,None,None,None,None),
|
||||||
|
(3,47,"GtkButton","error_close_button",45,None,None,None,1,None),
|
||||||
|
(3,48,"GtkBox","content_wrapper",19,None,None,None,-1,None),
|
||||||
|
(3,49,"GtkGrid","content",48,None,None,None,None,None),
|
||||||
|
(3,51,"GtkLabel","stats_label",49,None,None,None,1,None),
|
||||||
|
(3,52,"GtkLabel","email_label",49,None,None,None,2,None),
|
||||||
|
(3,53,"GtkButton","logout_button",49,None,None,None,3,None),
|
||||||
|
(3,55,"GtkLabel",None,49,None,None,None,5,None),
|
||||||
|
(3,57,"GtkLabel",None,49,None,None,None,7,None),
|
||||||
|
(3,58,"GtkPasswordEntry","api_key_field",49,None,None,None,8,None),
|
||||||
|
(3,59,"GtkLabel","status_label",49,None,None,None,9,None),
|
||||||
|
(3,60,"GtkButton","api_key_clear_button",49,None,None,None,10,None),
|
||||||
|
(3,63,"GtkButton","profile_image_button",49,None,None,None,None,""),
|
||||||
|
(3,64,"GtkImage","profile_image",63,None,None,None,None,None),
|
||||||
|
(3,65,"GtkBox",None,49,None,None,None,None,None),
|
||||||
|
(3,66,"GtkButton","remove_picture_button",65,None,None,None,None,None),
|
||||||
|
(3,67,"GtkEntry","name_label",65,None,None,None,1,None),
|
||||||
|
(3,68,"GtkBox",None,49,None,None,None,None,None),
|
||||||
|
(3,69,"GtkButton","edit_button",68,None,None,None,None,None),
|
||||||
|
(3,70,"GtkButton","cancel_edit_button",68,None,None,None,1,None),
|
||||||
|
(4,11,"GtkPopover","device_entry_popover",None,None,None,None,None,None),
|
||||||
|
(4,12,"GtkLabel",None,11,None,None,None,None,None),
|
||||||
|
(4,13,"GtkApplicationWindow","LoginWindow",None,None,None,None,None,None),
|
||||||
|
(4,14,"GtkBox",None,13,None,None,None,-1,None),
|
||||||
|
(4,30,"GtkLabel",None,14,None,None,None,1,None),
|
||||||
|
(4,31,"GtkOverlay","forms_overlay",14,None,None,None,None,None),
|
||||||
|
(4,32,"GtkBox","forms_wrapper",31,None,None,None,None,None),
|
||||||
|
(4,33,"GtkGrid",None,32,None,None,None,None,None),
|
||||||
|
(4,34,"GtkLabel",None,33,None,None,None,None,None),
|
||||||
|
(4,35,"GtkLabel","error_label",33,None,None,None,1,None),
|
||||||
|
(4,36,"GtkEntry","device_entry",33,None,None,None,2,None),
|
||||||
|
(4,37,"GtkLabel",None,33,None,None,None,3,None),
|
||||||
|
(4,38,"GtkLabel",None,33,None,None,None,4,None),
|
||||||
|
(4,39,"GtkLabel",None,33,None,None,None,5,None),
|
||||||
|
(4,40,"GtkEntry","email_entry",33,None,None,None,6,None),
|
||||||
|
(4,41,"GtkPasswordEntry","password_entry",33,None,None,None,7,None),
|
||||||
|
(4,42,"GtkButton","login_button",33,None,None,None,8,None),
|
||||||
|
(4,43,"GtkLabel",None,32,None,None,None,1,None),
|
||||||
|
(4,44,"GtkBox",None,32,None,None,None,2,None),
|
||||||
|
(4,45,"GtkLabel",None,44,None,None,None,None,None),
|
||||||
|
(4,46,"GtkPasswordEntry","api_key_entry",44,None,None,None,1,None),
|
||||||
|
(4,47,"GtkButton","api_key_button",44,None,None,None,2,None),
|
||||||
|
(4,48,"GtkBox","loading_overlay",None,None,None,None,None,None),
|
||||||
|
(4,49,"GtkSpinner",None,48,None,None,None,None,None),
|
||||||
|
(4,50,"GtkLabel",None,48,None,None,None,1,None),
|
||||||
|
(5,1,"GtkWindow","SLTotpDialog",None,None,None,None,None,None),
|
||||||
|
(5,2,"GtkOverlay","overlay",1,None,None,None,-1,None),
|
||||||
|
(5,11,"GtkBox","loading_overlay",None,None,None,None,None,None),
|
||||||
|
(5,12,"GtkSpinner",None,11,None,None,None,None,None),
|
||||||
|
(5,13,"GtkLabel",None,11,None,None,None,1,None),
|
||||||
|
(5,14,"GtkGrid","form_wrapper",2,None,None,None,None,None),
|
||||||
|
(5,15,"GtkBox",None,14,None,None,None,None,None),
|
||||||
|
(5,16,"GtkImage",None,15,None,None,None,None,None),
|
||||||
|
(5,17,"GtkLabel",None,15,None,None,None,1,None),
|
||||||
|
(5,19,"GtkButton","accept_button",14,None,None,None,2,None),
|
||||||
|
(5,20,"GtkButton","cancel_button",14,None,None,None,3,None),
|
||||||
|
(5,21,"GtkEntry","code_entry",14,None,None,None,4,None),
|
||||||
|
(5,23,"GtkLabel","error_label",14,None,None,None,4,None)
|
||||||
|
</object>
|
||||||
|
<object_property>
|
||||||
|
(1,3,"GtkOrientable","orientation","vertical",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,3,"GtkWidget","vexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,5,"GtkSearchEntry","placeholder-text","Filter by email, description, etc.",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,5,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,8,"GtkDropDown","model",None,None,None,None,None,9,None,None,None,None),
|
||||||
|
(1,8,"GtkDropDown","selected","0",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,8,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,10,"GtkButton","label","Search",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,12,"GtkButton","label","New",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,13,"GtkButton","label","Edit",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,14,"GtkButton","label","Delete",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,22,"GtkOrientable","orientation","vertical",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,23,"GtkSpinner","spinning","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,23,"GtkWidget","valign","end",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,23,"GtkWidget","vexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,24,"GtkLabel","label","Loading...",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,24,"GtkWidget","valign","start",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,24,"GtkWidget","vexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,28,"GtkButton","icon-name","go-previous-symbolic",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,28,"GtkWidget","halign","end",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,28,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,29,"GtkButton","icon-name","go-next-symbolic",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,30,"GtkEditable","max-width-chars","0",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,30,"GtkEditable","text","1",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,30,"GtkEditable","width-chars","5",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,30,"GtkEditable","xalign","0.5",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,30,"GtkEntry","has-frame","False",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,30,"GtkEntry","input-hints","no-emoji | no-spellcheck",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,30,"GtkEntry","input-purpose","digits",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,30,"GtkEntry","truncate-multiline","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,32,"GtkWidget","vexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,33,"GtkListView","factory",None,None,None,None,None,34,None,None,None,None),
|
||||||
|
(1,33,"GtkListView","model",None,None,None,None,None,35,None,None,None,None),
|
||||||
|
(1,36,"GtkLabel","label","No more results",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,36,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,36,"GtkWidget","vexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,37,"GtkOrientable","orientation","vertical",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,37,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,38,"GtkWidget","halign","center",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,38,"GtkWidget","valign","end",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,39,"GtkButton","icon-name","view-refresh-symbolic",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,39,"GtkWidget","halign","center",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,39,"GtkWidget","valign","end",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,39,"GtkWidget","vexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,40,"GtkButton","icon-name","window-close-symbolic",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,40,"GtkWidget","halign","center",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,40,"GtkWidget","valign","end",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,41,"GtkLabel","label","ERROR",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,41,"GtkWidget","valign","start",None,None,None,None,None,None,None,None,None),
|
||||||
|
(1,41,"GtkWidget","vexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,19,"GtkOverlay","child","48",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,19,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,30,"GtkOrientable","orientation","vertical",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,30,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,31,"GtkSpinner","spinning","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,31,"GtkWidget","valign","end",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,31,"GtkWidget","vexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,32,"GtkLabel","label","Loading...",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,32,"GtkWidget","valign","start",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,32,"GtkWidget","vexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,33,"GtkOrientable","orientation","vertical",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,33,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,35,"GtkLabel","label","ERROR",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,35,"GtkWidget","valign","start",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,35,"GtkWidget","vexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,45,"GtkWidget","halign","center",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,45,"GtkWidget","valign","end",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,46,"GtkButton","icon-name","view-refresh-symbolic",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,46,"GtkWidget","halign","center",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,46,"GtkWidget","valign","end",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,46,"GtkWidget","vexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,47,"GtkButton","icon-name","window-close-symbolic",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,47,"GtkWidget","halign","center",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,47,"GtkWidget","valign","end",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,48,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,48,"GtkWidget","vexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,49,"GtkGrid","row-homogeneous","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,49,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,49,"GtkWidget","valign","start",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,51,"GtkLabel","label","Stats go here",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,51,"GtkWidget","halign","center",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,51,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,52,"GtkLabel","label","mctesterface@test.tld",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,52,"GtkLabel","xalign","0.0",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,52,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,53,"GtkButton","label","Logout",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,53,"GtkWidget","halign","start",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,53,"GtkWidget","valign","center",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,55,"GtkLabel","label","Account Status:",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,55,"GtkLabel","xalign","1.0",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,55,"GtkWidget","margin-end","5",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,57,"GtkLabel","label","Api Key:",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,57,"GtkLabel","xalign","1.0",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,57,"GtkWidget","margin-end","5",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,58,"GtkEditable","editable","False",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,58,"GtkEditable","enable-undo","False",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,58,"GtkPasswordEntry","show-peek-icon","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,58,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,58,"GtkWidget","valign","center",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,59,"GtkLabel","label","Premium",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,59,"GtkLabel","xalign","0.0",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,59,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,60,"GtkButton","label","Clear",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,60,"GtkWidget","halign","start",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,60,"GtkWidget","valign","center",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,63,"GtkButton","has-frame","False",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,64,"GtkImage","icon-name","user-info-symbolic",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,64,"GtkImage","icon-size","large",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,64,"GtkWidget","halign","center",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,64,"GtkWidget","margin-end","5",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,64,"GtkWidget","valign","center",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,64,"GtkWidget","vexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,66,"GtkButton","icon-name","window-close-symbolic",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,67,"GtkEditable","editable","False",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,67,"GtkEditable","text","Testy McTesterface",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,67,"GtkEntry","has-frame","False",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,67,"GtkEntry","input-hints","no-emoji | no-spellcheck",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,67,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,69,"GtkButton","label","Edit",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,69,"GtkWidget","halign","start",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,69,"GtkWidget","valign","center",None,None,None,None,None,None,None,None,None),
|
||||||
|
(3,70,"GtkButton","label","Cancel",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,11,"GtkPopover","child",None,None,None,None,None,12,None,None,None,None),
|
||||||
|
(4,12,"GtkAccessible","accessible-role","tooltip",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,12,"GtkLabel","label","This is the human readable name that will show up in the API key section of the SimpleLogin website.",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,12,"GtkLabel","max-width-chars","30",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,12,"GtkLabel","wrap","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,13,"GtkWindow","title","SimpleLogin",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,14,"GtkOrientable","orientation","vertical",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,30,"GtkLabel","label","Don't have an account? You can register <a href=\"https://app.simplelogin.io/auth/register\">here</a>.",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,30,"GtkLabel","use-markup","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,30,"GtkLabel","yalign","0.0",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,30,"GtkWidget","margin-bottom","10",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,30,"GtkWidget","valign","start",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,30,"GtkWidget","vexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,31,"GtkOverlay","child","32",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,31,"GtkWidget","valign","end",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,31,"GtkWidget","vexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,32,"GtkWidget","valign","end",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,32,"GtkWidget","vexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,33,"GtkWidget","halign","end",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,33,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,33,"GtkWidget","margin-bottom","10",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,33,"GtkWidget","margin-end","10",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,33,"GtkWidget","margin-start","10",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,33,"GtkWidget","margin-top","10",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,33,"GtkWidget","valign","center",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,34,"GtkLabel","label","Login:",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,34,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,34,"GtkWidget","margin-bottom","5",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,34,"GtkWidget","vexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,35,"GtkLabel","label","ERROR",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,35,"GtkWidget","margin-top","5",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,36,"GtkEditable","width-chars","18",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,36,"GtkEntry","placeholder-text","My Awesome Computer",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,36,"GtkEntry","secondary-icon-name","dialog-question-symbolic",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,36,"GtkEntry","truncate-multiline","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,36,"GtkWidget","margin-start","6",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,37,"GtkLabel","label","Device:",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,37,"GtkLabel","xalign","0.0",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,38,"GtkLabel","label","Email:",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,38,"GtkLabel","xalign","0.0",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,39,"GtkLabel","label","Password:",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,39,"GtkLabel","xalign","0.0",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,40,"GtkEntry","input-purpose","email",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,40,"GtkEntry","truncate-multiline","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,40,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,40,"GtkWidget","margin-start","6",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,40,"GtkWidget","receives-default","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,41,"GtkPasswordEntry","show-peek-icon","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,41,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,41,"GtkWidget","margin-start","6",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,42,"GtkButton","label","Login",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,42,"GtkWidget","halign","center",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,42,"GtkWidget","margin-top","5",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,42,"GtkWidget","sensitive","False",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,42,"GtkWidget","valign","center",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,43,"GtkLabel","justify","center",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,43,"GtkLabel","label","- or -",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,43,"GtkWidget","halign","center",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,44,"GtkOrientable","orientation","vertical",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,44,"GtkWidget","halign","start",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,44,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,44,"GtkWidget","margin-bottom","10",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,44,"GtkWidget","margin-end","10",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,44,"GtkWidget","margin-start","10",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,44,"GtkWidget","margin-top","10",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,44,"GtkWidget","valign","center",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,45,"GtkLabel","label","Set API Key:",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,45,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,45,"GtkWidget","margin-bottom","5",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,46,"GtkEditable","width-chars","27",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,46,"GtkPasswordEntry","show-peek-icon","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,46,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,46,"GtkWidget","margin-end","3",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,46,"GtkWidget","margin-start","8",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,47,"GtkButton","label","Accept",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,47,"GtkWidget","halign","center",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,47,"GtkWidget","margin-top","5",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,47,"GtkWidget","sensitive","False",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,48,"GtkOrientable","orientation","vertical",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,49,"GtkSpinner","spinning","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,49,"GtkWidget","valign","end",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,49,"GtkWidget","vexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,50,"GtkLabel","label","Loading...",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,50,"GtkWidget","valign","start",None,None,None,None,None,None,None,None,None),
|
||||||
|
(4,50,"GtkWidget","vexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,1,"GtkWindow","modal","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,1,"GtkWindow","title","TOTP Entry",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,2,"GtkOverlay","child","14",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,2,"GtkWidget","halign","center",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,2,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,2,"GtkWidget","valign","center",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,2,"GtkWidget","vexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,11,"GtkOrientable","orientation","vertical",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,12,"GtkSpinner","spinning","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,12,"GtkWidget","valign","end",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,12,"GtkWidget","vexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,13,"GtkLabel","label","Loading...",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,13,"GtkWidget","valign","start",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,13,"GtkWidget","vexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,14,"GtkGrid","column-spacing","5",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,14,"GtkGrid","row-spacing","5",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,14,"GtkWidget","halign","center",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,14,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,14,"GtkWidget","margin-bottom","10",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,14,"GtkWidget","margin-end","10",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,14,"GtkWidget","margin-start","10",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,14,"GtkWidget","margin-top","10",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,14,"GtkWidget","valign","center",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,14,"GtkWidget","vexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,15,"GtkWidget","halign","center",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,15,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,16,"GtkImage","icon-name","dialog-password-symbolic",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,16,"GtkWidget","halign","center",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,17,"GtkLabel","label","TOTP",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,19,"GtkButton","label","Accept",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,20,"GtkButton","label","Cancel",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,21,"GtkEntry","placeholder-text","TOTP Code",None,None,None,None,None,None,None,None,None),
|
||||||
|
(5,23,"GtkLabel","label","ERROR",None,None,None,None,None,None,None,None,None)
|
||||||
|
</object_property>
|
||||||
|
<object_layout_property>
|
||||||
|
(3,49,51,"GtkGridLayoutChild","column","0",None,None,None,None),
|
||||||
|
(3,49,51,"GtkGridLayoutChild","column-span","3",None,None,None,None),
|
||||||
|
(3,49,51,"GtkGridLayoutChild","row","2",None,None,None,None),
|
||||||
|
(3,49,51,"GtkGridLayoutChild","row-span","1",None,None,None,None),
|
||||||
|
(3,49,52,"GtkGridLayoutChild","column","1",None,None,None,None),
|
||||||
|
(3,49,52,"GtkGridLayoutChild","row","1",None,None,None,None),
|
||||||
|
(3,49,53,"GtkGridLayoutChild","column","2",None,None,None,None),
|
||||||
|
(3,49,53,"GtkGridLayoutChild","row","1",None,None,None,None),
|
||||||
|
(3,49,55,"GtkGridLayoutChild","column","0",None,None,None,None),
|
||||||
|
(3,49,55,"GtkGridLayoutChild","column-span","1",None,None,None,None),
|
||||||
|
(3,49,55,"GtkGridLayoutChild","row","3",None,None,None,None),
|
||||||
|
(3,49,55,"GtkGridLayoutChild","row-span","1",None,None,None,None),
|
||||||
|
(3,49,57,"GtkGridLayoutChild","column","0",None,None,None,None),
|
||||||
|
(3,49,57,"GtkGridLayoutChild","row","4",None,None,None,None),
|
||||||
|
(3,49,58,"GtkGridLayoutChild","column","1",None,None,None,None),
|
||||||
|
(3,49,58,"GtkGridLayoutChild","row","4",None,None,None,None),
|
||||||
|
(3,49,59,"GtkGridLayoutChild","column","1",None,None,None,None),
|
||||||
|
(3,49,59,"GtkGridLayoutChild","column-span","1",None,None,None,None),
|
||||||
|
(3,49,59,"GtkGridLayoutChild","row","3",None,None,None,None),
|
||||||
|
(3,49,59,"GtkGridLayoutChild","row-span","1",None,None,None,None),
|
||||||
|
(3,49,60,"GtkGridLayoutChild","column","2",None,None,None,None),
|
||||||
|
(3,49,60,"GtkGridLayoutChild","row","4",None,None,None,None),
|
||||||
|
(3,49,63,"GtkGridLayoutChild","column","0",None,None,None,None),
|
||||||
|
(3,49,63,"GtkGridLayoutChild","column-span","1",None,None,None,None),
|
||||||
|
(3,49,63,"GtkGridLayoutChild","row-span","2",None,None,None,None),
|
||||||
|
(3,49,65,"GtkGridLayoutChild","column","1",None,None,None,None),
|
||||||
|
(3,49,65,"GtkGridLayoutChild","column-span","1",None,None,None,None),
|
||||||
|
(3,49,65,"GtkGridLayoutChild","row","0",None,None,None,None),
|
||||||
|
(3,49,65,"GtkGridLayoutChild","row-span","1",None,None,None,None),
|
||||||
|
(3,49,68,"GtkGridLayoutChild","column","2",None,None,None,None),
|
||||||
|
(3,49,68,"GtkGridLayoutChild","column-span","1",None,None,None,None),
|
||||||
|
(3,49,68,"GtkGridLayoutChild","row","0",None,None,None,None),
|
||||||
|
(3,49,68,"GtkGridLayoutChild","row-span","1",None,None,None,None),
|
||||||
|
(4,33,34,"GtkGridLayoutChild","column","0",None,None,None,None),
|
||||||
|
(4,33,34,"GtkGridLayoutChild","column-span","2",None,None,None,None),
|
||||||
|
(4,33,34,"GtkGridLayoutChild","row","0",None,None,None,None),
|
||||||
|
(4,33,35,"GtkGridLayoutChild","column","0",None,None,None,None),
|
||||||
|
(4,33,35,"GtkGridLayoutChild","column-span","2",None,None,None,None),
|
||||||
|
(4,33,35,"GtkGridLayoutChild","row","4",None,None,None,None),
|
||||||
|
(4,33,36,"GtkGridLayoutChild","column","1",None,None,None,None),
|
||||||
|
(4,33,36,"GtkGridLayoutChild","row","3",None,None,None,None),
|
||||||
|
(4,33,37,"GtkGridLayoutChild","column","0",None,None,None,None),
|
||||||
|
(4,33,37,"GtkGridLayoutChild","row","3",None,None,None,None),
|
||||||
|
(4,33,38,"GtkGridLayoutChild","column","0",None,None,None,None),
|
||||||
|
(4,33,38,"GtkGridLayoutChild","row","1",None,None,None,None),
|
||||||
|
(4,33,39,"GtkGridLayoutChild","column","0",None,None,None,None),
|
||||||
|
(4,33,39,"GtkGridLayoutChild","row","2",None,None,None,None),
|
||||||
|
(4,33,40,"GtkGridLayoutChild","column","1",None,None,None,None),
|
||||||
|
(4,33,40,"GtkGridLayoutChild","row","1",None,None,None,None),
|
||||||
|
(4,33,41,"GtkGridLayoutChild","column","1",None,None,None,None),
|
||||||
|
(4,33,41,"GtkGridLayoutChild","row","2",None,None,None,None),
|
||||||
|
(4,33,42,"GtkGridLayoutChild","column","0",None,None,None,None),
|
||||||
|
(4,33,42,"GtkGridLayoutChild","column-span","2",None,None,None,None),
|
||||||
|
(4,33,42,"GtkGridLayoutChild","row","5",None,None,None,None),
|
||||||
|
(5,14,15,"GtkGridLayoutChild","column","0",None,None,None,None),
|
||||||
|
(5,14,15,"GtkGridLayoutChild","column-span","2",None,None,None,None),
|
||||||
|
(5,14,15,"GtkGridLayoutChild","row","0",None,None,None,None),
|
||||||
|
(5,14,19,"GtkGridLayoutChild","column","1",None,None,None,None),
|
||||||
|
(5,14,19,"GtkGridLayoutChild","row","3",None,None,None,None),
|
||||||
|
(5,14,20,"GtkGridLayoutChild","column","0",None,None,None,None),
|
||||||
|
(5,14,20,"GtkGridLayoutChild","row","3",None,None,None,None),
|
||||||
|
(5,14,21,"GtkGridLayoutChild","column","0",None,None,None,None),
|
||||||
|
(5,14,21,"GtkGridLayoutChild","column-span","2",None,None,None,None),
|
||||||
|
(5,14,21,"GtkGridLayoutChild","row","1",None,None,None,None),
|
||||||
|
(5,14,23,"GtkGridLayoutChild","column-span","2",None,None,None,None),
|
||||||
|
(5,14,23,"GtkGridLayoutChild","row","2",None,None,None,None)
|
||||||
|
</object_layout_property>
|
||||||
|
<object_data>
|
||||||
|
(4,34,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||||
|
(4,34,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||||
|
(4,35,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||||
|
(4,35,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||||
|
(4,40,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||||
|
(4,33,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||||
|
(4,33,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||||
|
(4,45,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||||
|
(4,45,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||||
|
(1,9,"GtkStringList",2,5,"Disabled only",1,None,None,None,None),
|
||||||
|
(1,9,"GtkStringList",2,4,"Enabled only",1,None,None,None,None),
|
||||||
|
(1,9,"GtkStringList",2,3,"Pinned only",1,None,None,None,None),
|
||||||
|
(1,9,"GtkStringList",2,2,"All aliases",1,None,None,None,None),
|
||||||
|
(1,9,"GtkStringList",1,1,None,None,None,None,None,None),
|
||||||
|
(1,22,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||||
|
(1,22,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||||
|
(1,24,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||||
|
(1,24,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||||
|
(1,23,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||||
|
(1,23,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||||
|
(4,49,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||||
|
(4,49,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||||
|
(4,50,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||||
|
(4,50,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||||
|
(4,48,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||||
|
(4,48,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||||
|
(5,17,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||||
|
(5,17,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||||
|
(5,23,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||||
|
(5,23,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||||
|
(5,13,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||||
|
(5,13,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||||
|
(5,12,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||||
|
(5,12,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||||
|
(5,11,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||||
|
(5,11,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||||
|
(1,36,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||||
|
(1,36,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||||
|
(3,31,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||||
|
(3,31,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||||
|
(3,32,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||||
|
(3,32,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||||
|
(3,30,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||||
|
(3,30,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||||
|
(3,57,"GtkLabel",1,1,None,None,None,None,None,None),
|
||||||
|
(1,39,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||||
|
(1,39,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||||
|
(1,40,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||||
|
(1,40,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||||
|
(1,41,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||||
|
(1,41,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||||
|
(1,41,"GtkWidget",2,3,None,1,None,None,None,None),
|
||||||
|
(3,67,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||||
|
(3,67,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||||
|
(3,47,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||||
|
(3,47,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||||
|
(3,46,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||||
|
(3,46,"GtkWidget",1,1,None,None,None,None,None,None),
|
||||||
|
(3,35,"GtkWidget",2,3,None,1,None,None,None,None),
|
||||||
|
(3,35,"GtkWidget",2,2,None,1,None,None,None,None),
|
||||||
|
(3,35,"GtkWidget",1,1,None,None,None,None,None,None)
|
||||||
|
</object_data>
|
||||||
|
<object_data_arg>
|
||||||
|
(4,34,"GtkWidget",2,2,"name","login-title-label"),
|
||||||
|
(4,35,"GtkWidget",2,2,"name","error-message-label"),
|
||||||
|
(4,33,"GtkWidget",2,2,"name","login-form-warpper"),
|
||||||
|
(4,45,"GtkWidget",2,2,"name","login-title-label"),
|
||||||
|
(1,9,"GtkStringList",2,5,"translatable",None),
|
||||||
|
(1,9,"GtkStringList",2,5,"context",None),
|
||||||
|
(1,9,"GtkStringList",2,5,"comments",None),
|
||||||
|
(1,9,"GtkStringList",2,4,"translatable",None),
|
||||||
|
(1,9,"GtkStringList",2,4,"context",None),
|
||||||
|
(1,9,"GtkStringList",2,4,"comments",None),
|
||||||
|
(1,9,"GtkStringList",2,3,"translatable",None),
|
||||||
|
(1,9,"GtkStringList",2,3,"context",None),
|
||||||
|
(1,9,"GtkStringList",2,3,"comments",None),
|
||||||
|
(1,9,"GtkStringList",2,2,"translatable",None),
|
||||||
|
(1,9,"GtkStringList",2,2,"context",None),
|
||||||
|
(1,9,"GtkStringList",2,2,"comments",None),
|
||||||
|
(1,24,"GtkWidget",2,2,"name","loading-label"),
|
||||||
|
(1,22,"GtkWidget",2,2,"name","loading-label"),
|
||||||
|
(1,23,"GtkWidget",2,2,"name","loading-label"),
|
||||||
|
(4,49,"GtkWidget",2,2,"name","loading-label"),
|
||||||
|
(4,50,"GtkWidget",2,2,"name","loading-label"),
|
||||||
|
(4,48,"GtkWidget",2,2,"name","loading-label"),
|
||||||
|
(5,17,"GtkWidget",2,2,"name","login-title-label"),
|
||||||
|
(5,23,"GtkWidget",2,2,"name","error-message-label"),
|
||||||
|
(5,13,"GtkWidget",2,2,"name","loading-label"),
|
||||||
|
(5,12,"GtkWidget",2,2,"name","loading-label"),
|
||||||
|
(5,11,"GtkWidget",2,2,"name","loading-label"),
|
||||||
|
(1,36,"GtkWidget",2,2,"name","loading-label"),
|
||||||
|
(3,31,"GtkWidget",2,2,"name","loading-label"),
|
||||||
|
(3,32,"GtkWidget",2,2,"name","loading-label"),
|
||||||
|
(3,30,"GtkWidget",2,2,"name","loading-label"),
|
||||||
|
(1,39,"GtkWidget",2,2,"name","loading-label"),
|
||||||
|
(1,40,"GtkWidget",2,2,"name","loading-label"),
|
||||||
|
(1,41,"GtkWidget",2,2,"name","error-message-label"),
|
||||||
|
(1,41,"GtkWidget",2,3,"name","loading-label"),
|
||||||
|
(3,67,"GtkWidget",2,2,"name","login-title-label"),
|
||||||
|
(3,47,"GtkWidget",2,2,"name","loading-label"),
|
||||||
|
(3,46,"GtkWidget",2,2,"name","loading-label"),
|
||||||
|
(3,35,"GtkWidget",2,3,"name","loading-label"),
|
||||||
|
(3,35,"GtkWidget",2,2,"name","error-message-label")
|
||||||
|
</object_data_arg>
|
||||||
|
</cambalache-project>
|
@ -0,0 +1,8 @@
|
|||||||
|
[wrap-git]
|
||||||
|
directory = blueprint-compiler
|
||||||
|
url = https://gitlab.gnome.org/jwestman/blueprint-compiler.git
|
||||||
|
revision = v0.10.0
|
||||||
|
depth = 1
|
||||||
|
|
||||||
|
[provide]
|
||||||
|
program_names = blueprint-compiler
|
124
simplelogin-gui/res.old/totp-dialog.ui
Normal file
124
simplelogin-gui/res.old/totp-dialog.ui
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<!-- Created with Cambalache 0.16.0 -->
|
||||||
|
<interface>
|
||||||
|
<requires lib="gtk" version="4.12"/>
|
||||||
|
<template class="SLTotpDialog" parent="GtkWindow">
|
||||||
|
<property name="modal">True</property>
|
||||||
|
<property name="title">TOTP Entry</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkOverlay" id="overlay">
|
||||||
|
<property name="child">form_wrapper</property>
|
||||||
|
<property name="halign">center</property>
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<property name="valign">center</property>
|
||||||
|
<property name="vexpand">True</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkGrid" id="form_wrapper">
|
||||||
|
<property name="column-spacing">5</property>
|
||||||
|
<property name="halign">center</property>
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<property name="margin-bottom">10</property>
|
||||||
|
<property name="margin-end">10</property>
|
||||||
|
<property name="margin-start">10</property>
|
||||||
|
<property name="margin-top">10</property>
|
||||||
|
<property name="row-spacing">5</property>
|
||||||
|
<property name="valign">center</property>
|
||||||
|
<property name="vexpand">True</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="halign">center</property>
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage">
|
||||||
|
<property name="halign">center</property>
|
||||||
|
<property name="icon-name">dialog-password-symbolic</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label">TOTP</property>
|
||||||
|
<style>
|
||||||
|
<class name="login-title-label"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="column-span">2</property>
|
||||||
|
<property name="row">0</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="accept_button">
|
||||||
|
<property name="label">Accept</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="row">3</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="cancel_button">
|
||||||
|
<property name="label">Cancel</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">3</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkEntry" id="code_entry">
|
||||||
|
<property name="placeholder-text">TOTP Code</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="column-span">2</property>
|
||||||
|
<property name="row">1</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="error_label">
|
||||||
|
<property name="label">ERROR</property>
|
||||||
|
<style>
|
||||||
|
<class name="error-message-label"/>
|
||||||
|
</style>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="column-span">2</property>
|
||||||
|
<property name="row">2</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</template>
|
||||||
|
<object class="GtkBox" id="loading_overlay">
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSpinner">
|
||||||
|
<property name="spinning">True</property>
|
||||||
|
<property name="valign">end</property>
|
||||||
|
<property name="vexpand">True</property>
|
||||||
|
<style>
|
||||||
|
<class name="loading-label"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label">Loading...</property>
|
||||||
|
<property name="valign">start</property>
|
||||||
|
<property name="vexpand">True</property>
|
||||||
|
<style>
|
||||||
|
<class name="loading-label"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<style>
|
||||||
|
<class name="loading-label"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
</interface>
|
50
simplelogin-gui/src/application.rs
Normal file
50
simplelogin-gui/src/application.rs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
use crate::login_window::LoginWindow;
|
||||||
|
|
||||||
|
use gtk4 as gtk;
|
||||||
|
use gtk::{glib, gio, prelude::*, subclass::prelude::*};
|
||||||
|
|
||||||
|
mod imp {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Application {
|
||||||
|
pub settings: gio::Settings,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Application {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
settings: gio::Settings::new(crate::APP_ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[glib::object_subclass]
|
||||||
|
impl ObjectSubclass for Application {
|
||||||
|
const NAME: &'static str = "Application";
|
||||||
|
type Type = super::Application;
|
||||||
|
type ParentType = gtk::Application;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ApplicationImpl for Application {
|
||||||
|
fn activate(&self) {
|
||||||
|
let login_window = LoginWindow::new(&self.obj());
|
||||||
|
login_window.present();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ObjectImpl for Application {}
|
||||||
|
impl GtkApplicationImpl for Application {}
|
||||||
|
}
|
||||||
|
|
||||||
|
glib::wrapper! {
|
||||||
|
pub struct Application(ObjectSubclass<imp::Application>)
|
||||||
|
@extends gtk::Application, gio::Application,
|
||||||
|
@implements gio::ActionMap, gio::ActionGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Application {
|
||||||
|
pub fn new(app_id: &str) -> Self {
|
||||||
|
glib::Object::builder().property("application-id", app_id).build()
|
||||||
|
}
|
||||||
|
}
|
65
simplelogin-gui/src/login_window.rs
Normal file
65
simplelogin-gui/src/login_window.rs
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
use gtk4 as gtk;
|
||||||
|
use gtk::{glib, gio, subclass::prelude::*};
|
||||||
|
|
||||||
|
mod imp {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Debug, Default, gtk::CompositeTemplate)]
|
||||||
|
#[template(file = "data/login_window.blp")]
|
||||||
|
pub struct LoginWindow {
|
||||||
|
#[template_child]
|
||||||
|
pub forms_overlay: TemplateChild<gtk::Overlay>,
|
||||||
|
#[template_child]
|
||||||
|
pub forms_wrapper: TemplateChild<gtk::Box>,
|
||||||
|
#[template_child]
|
||||||
|
pub error_label: TemplateChild<gtk::Label>,
|
||||||
|
#[template_child]
|
||||||
|
pub device_entry: TemplateChild<gtk::Entry>,
|
||||||
|
#[template_child]
|
||||||
|
pub email_entry: TemplateChild<gtk::Entry>,
|
||||||
|
#[template_child]
|
||||||
|
pub password_entry: TemplateChild<gtk::PasswordEntry>,
|
||||||
|
#[template_child]
|
||||||
|
pub login_button: TemplateChild<gtk::Button>,
|
||||||
|
#[template_child]
|
||||||
|
pub api_key_entry: TemplateChild<gtk::PasswordEntry>,
|
||||||
|
#[template_child]
|
||||||
|
pub api_key_button: TemplateChild<gtk::Button>,
|
||||||
|
#[template_child]
|
||||||
|
pub device_entry_popover: TemplateChild<gtk::Popover>,
|
||||||
|
#[template_child]
|
||||||
|
pub loading_overlay: TemplateChild<gtk::Box>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[glib::object_subclass]
|
||||||
|
impl ObjectSubclass for LoginWindow {
|
||||||
|
const NAME: &'static str = "LoginWindow";
|
||||||
|
type Type = super::LoginWindow;
|
||||||
|
type ParentType = gtk::ApplicationWindow;
|
||||||
|
|
||||||
|
fn class_init(class: &mut Self::Class) {
|
||||||
|
class.bind_template();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
|
||||||
|
obj.init_template();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ObjectImpl for LoginWindow {}
|
||||||
|
impl WidgetImpl for LoginWindow {}
|
||||||
|
impl WindowImpl for LoginWindow {}
|
||||||
|
impl ApplicationWindowImpl for LoginWindow {}
|
||||||
|
}
|
||||||
|
|
||||||
|
glib::wrapper! {
|
||||||
|
pub struct LoginWindow(ObjectSubclass<imp::LoginWindow>)
|
||||||
|
@extends gtk::Widget, gtk::Window, gtk::ApplicationWindow,
|
||||||
|
@implements gio::ActionMap, gio::ActionGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LoginWindow {
|
||||||
|
pub fn new(app: &crate::application::Application) -> Self {
|
||||||
|
glib::Object::builder().property("application", app).build()
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,20 @@
|
|||||||
fn main() {
|
mod login_window;
|
||||||
println!("Hello, world!");
|
mod totp_window;
|
||||||
|
mod application;
|
||||||
|
|
||||||
|
use gtk4 as gtk;
|
||||||
|
use gtk::prelude::*;
|
||||||
|
use gtk::glib::{self, g_message};
|
||||||
|
|
||||||
|
const APP_ID: &str = "im.zander.SimpleLogin";
|
||||||
|
|
||||||
|
fn main() -> glib::ExitCode {
|
||||||
|
if cfg!(debug_assertions) {
|
||||||
|
// allow us to use a test schema for debug runs
|
||||||
|
let schema_dir = concat!(env!("OUT_DIR"), "/schemas/");
|
||||||
|
g_message!("SimpleLogin", "Using schema dir: \"{}\"", schema_dir);
|
||||||
|
std::env::set_var("GSETTINGS_SCHEMA_DIR", schema_dir);
|
||||||
|
}
|
||||||
|
let app = application::Application::new(APP_ID);
|
||||||
|
app.run()
|
||||||
}
|
}
|
||||||
|
43
simplelogin-gui/src/totp_window.rs
Normal file
43
simplelogin-gui/src/totp_window.rs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
use gtk4 as gtk;
|
||||||
|
use gtk::{glib, gio, prelude::*, subclass::prelude::*};
|
||||||
|
|
||||||
|
mod imp {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Debug, Default, gtk::CompositeTemplate)]
|
||||||
|
#[template(file = "data/totp_window.blp")]
|
||||||
|
pub struct TotpWindow {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[glib::object_subclass]
|
||||||
|
impl ObjectSubclass for TotpWindow {
|
||||||
|
const NAME: &'static str = "TotpWindow";
|
||||||
|
type Type = super::TotpWindow;
|
||||||
|
type ParentType = gtk::Window;
|
||||||
|
|
||||||
|
fn class_init(class: &mut Self::Class) {
|
||||||
|
class.bind_template();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
|
||||||
|
obj.init_template();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ObjectImpl for TotpWindow {}
|
||||||
|
impl WidgetImpl for TotpWindow {}
|
||||||
|
impl WindowImpl for TotpWindow {}
|
||||||
|
}
|
||||||
|
|
||||||
|
glib::wrapper! {
|
||||||
|
pub struct TotpWindow(ObjectSubclass<imp::TotpWindow>)
|
||||||
|
@extends gtk::Widget, gtk::Window,
|
||||||
|
@implements gio::ActionMap, gio::ActionGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TotpWindow {
|
||||||
|
pub fn new<P: IsA<gtk::Application>>(app: &P) -> Self {
|
||||||
|
glib::Object::builder().property("application", app).build()
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,9 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
use core::fmt;
|
||||||
|
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
struct Context {
|
pub struct Context {
|
||||||
client: reqwest::Client,
|
client: reqwest::Client,
|
||||||
api_key: Option<String>,
|
api_key: Option<String>,
|
||||||
url: String,
|
url: String,
|
||||||
@ -32,12 +34,60 @@ struct LoginResponse {
|
|||||||
api_key: Option<String>,
|
api_key: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Error {
|
#[derive(Serialize)]
|
||||||
FIDO(String),
|
struct MfaRequest<'a> {
|
||||||
Json(String),
|
mfa_token: &'a str,
|
||||||
Auth(String),
|
mfa_key: &'a str,
|
||||||
Http(String),
|
device: &'a str
|
||||||
Internal(String)
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct MfaResponse {
|
||||||
|
name: String,
|
||||||
|
api_key: String,
|
||||||
|
email: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum ErrorKind {
|
||||||
|
State,
|
||||||
|
Json,
|
||||||
|
Http,
|
||||||
|
Auth,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Error {
|
||||||
|
kind: ErrorKind,
|
||||||
|
msg: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error {
|
||||||
|
pub(crate) fn new<T>(
|
||||||
|
kind: ErrorKind, msg: T
|
||||||
|
) -> Self where T: Into<String> {
|
||||||
|
Self {kind, msg: msg.into()}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_state(&self) -> bool {
|
||||||
|
matches!(self.kind, ErrorKind::State)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_http(&self) -> bool {
|
||||||
|
matches!(self.kind, ErrorKind::Http)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_auth(&self) -> bool {
|
||||||
|
matches!(self.kind, ErrorKind::Auth)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_json(&self) -> bool {
|
||||||
|
matches!(self.kind, ErrorKind::Json)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Error {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "{}", self.msg)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const DEFAULT_URL: &str = "https://app.simplelogin.io/";
|
pub const DEFAULT_URL: &str = "https://app.simplelogin.io/";
|
||||||
@ -63,6 +113,14 @@ impl Context {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn api_key(&self) -> Option<&String> {
|
||||||
|
self.api_key.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_api_key(&mut self, api_key: Option<&str>) {
|
||||||
|
self.api_key = api_key.map(|s| s.to_owned());
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_error_json(error_body: &String) -> String {
|
fn parse_error_json(error_body: &String) -> String {
|
||||||
match serde_json::from_str(error_body) {
|
match serde_json::from_str(error_body) {
|
||||||
Ok::<ErrorResponse, _>(obj) => obj.error,
|
Ok::<ErrorResponse, _>(obj) => obj.error,
|
||||||
@ -77,22 +135,43 @@ impl Context {
|
|||||||
Ok(resp) => {
|
Ok(resp) => {
|
||||||
let status = resp.status();
|
let status = resp.status();
|
||||||
let resp_text = resp.text().await
|
let resp_text = resp.text().await
|
||||||
.map_err(|e| Error::Http(e.to_string()))?;
|
.map_err(|e| Error::new(ErrorKind::Http, e.to_string()))?;
|
||||||
return if status.is_success() {
|
return if status.is_success() {
|
||||||
Ok(resp_text)
|
Ok(resp_text)
|
||||||
} else if status.is_client_error() {
|
} else if status.is_client_error() {
|
||||||
Err(Error::Auth(Self::parse_error_json(&resp_text)))
|
Err(Error::new(ErrorKind::Auth, Self::parse_error_json(&resp_text)))
|
||||||
} else {
|
} else {
|
||||||
Err(Error::Http("Unknown error! Response code: ".to_owned()
|
Err(Error::new(ErrorKind::Http, status.to_string()))
|
||||||
+ status.as_str()))
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
Err(Error::Http(err.to_string()))
|
Err(Error::new(ErrorKind::Http, err.to_string()))
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn post_request(
|
||||||
|
&mut self, endpoint: &str, body: &str
|
||||||
|
) -> Result<String, Error> {
|
||||||
|
Self::perform_request(self.client.post(self.url.to_owned() + endpoint)
|
||||||
|
.header("Content-Type", "application/json")
|
||||||
|
.body(body.to_owned())).await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn obj_to_json<T>(
|
||||||
|
obj: &T
|
||||||
|
) -> Result<String, Error> where T: serde::Serialize {
|
||||||
|
serde_json::to_string(obj)
|
||||||
|
.map_err(|e| Error::new(ErrorKind::Json, e.to_string()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn json_to_obj<'a, T>(
|
||||||
|
json: &'a str
|
||||||
|
) -> Result<T, Error> where T: serde::Deserialize<'a> {
|
||||||
|
serde_json::from_str(json)
|
||||||
|
.map_err(|e| Error::new(ErrorKind::Json, e.to_string()))
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn login(
|
pub async fn login(
|
||||||
&mut self,
|
&mut self,
|
||||||
email: &str,
|
email: &str,
|
||||||
@ -100,21 +179,16 @@ impl Context {
|
|||||||
device: &str
|
device: &str
|
||||||
) -> Result<bool, Error> {
|
) -> Result<bool, Error> {
|
||||||
let req_body = LoginRequest {email, password, device};
|
let req_body = LoginRequest {email, password, device};
|
||||||
let response = Self::perform_request(self.client.post(self.url.to_owned())
|
let body = self.post_request("api/auth/login",
|
||||||
.header("Content-Type", "application/json")
|
Self::obj_to_json(&req_body)?.as_str()).await?;
|
||||||
.body(serde_json::to_string(&req_body).unwrap()));
|
let resp_obj: LoginResponse = Self::json_to_obj(body.as_str())?;
|
||||||
let body = response.await?;
|
|
||||||
let resp_obj: LoginResponse = serde_json::from_str(body.as_str())
|
|
||||||
.map_err(|_| Error::Json("Could not parse response json"
|
|
||||||
.to_owned()))?;
|
|
||||||
if resp_obj.mfa_enabled {
|
if resp_obj.mfa_enabled {
|
||||||
if resp_obj.mfa_key.is_some() {
|
if resp_obj.mfa_key.is_some() {
|
||||||
self.device = Some(device.to_owned());
|
self.device = Some(device.to_owned());
|
||||||
self.mfa_key = resp_obj.mfa_key;
|
self.mfa_key = resp_obj.mfa_key;
|
||||||
Ok(true)
|
Ok(true)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::Json("Error response did not contain mfa key"
|
Err(Error::new(ErrorKind::Json, "Error response did not contain mfa key"))
|
||||||
.to_owned()))
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if resp_obj.api_key.is_some() {
|
if resp_obj.api_key.is_some() {
|
||||||
@ -123,13 +197,26 @@ impl Context {
|
|||||||
self.device = None;
|
self.device = None;
|
||||||
Ok(true)
|
Ok(true)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::Json("Response did not contain api key".to_owned()))
|
Err(Error::new(ErrorKind::Json, "Response did not contain api key"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn mfa(&mut self, mfa_token: &str) -> Result<(), Error> {
|
pub async fn mfa(&mut self, mfa_token: &str) -> Result<(), Error> {
|
||||||
// TODO implement
|
if self.mfa_key.is_some() && self.device.is_some() {
|
||||||
Ok(())
|
let req_json = Self::obj_to_json(&MfaRequest {
|
||||||
|
mfa_token,
|
||||||
|
mfa_key: self.mfa_key.as_ref().unwrap().as_str(),
|
||||||
|
device: self.device.as_ref().unwrap().as_str(),
|
||||||
|
})?;
|
||||||
|
let body = self.post_request("api/auth/mfa", req_json.as_str()).await?;
|
||||||
|
let resp_obj: MfaResponse = Self::json_to_obj(body.as_str())?;
|
||||||
|
self.api_key = Some(resp_obj.api_key);
|
||||||
|
self.device = None;
|
||||||
|
self.mfa_key = None;
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(Error::new(ErrorKind::State, "No login operation in progress"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user