summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVivien Kraus <vivien@planete-kraus.eu>2021-10-06 18:06:12 +0200
committerVivien Kraus <vivien@planete-kraus.eu>2021-10-12 22:27:38 +0200
commit3ba93ce1fccbc54d4695d55011ce856018c1b2cd (patch)
treeb3668d95661643c55a2d6bf663ab58b5e3889a18
parentf53954f07104237497e9c121bffe0a3814116691 (diff)
gui: add a primitive browser widget
-rw-r--r--po/POTFILES.in14
-rw-r--r--po/disfluid.pot131
-rw-r--r--po/fr.po172
-rw-r--r--src/scm/webid-oidc/client/application.scm313
-rw-r--r--src/ui/Makefile.am8
-rw-r--r--src/ui/error-page.glade108
-rw-r--r--src/ui/link-widget.glade79
-rw-r--r--src/ui/loaded-page.glade99
-rw-r--r--src/ui/loading-page.glade34
-rw-r--r--src/ui/new-page.glade37
-rw-r--r--src/ui/updated-page.glade121
11 files changed, 998 insertions, 118 deletions
diff --git a/po/POTFILES.in b/po/POTFILES.in
index bde8044..a55dcd4 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -38,11 +38,11 @@ src/scm/webid-oidc/client/accounts.scm
src/scm/webid-oidc/client/application.scm
src/scm/webid-oidc/client/client.scm
src/scm/webid-oidc/client/gui.scm
-src/scm/webid-oidc/client/gui/application.scm
-src/scm/webid-oidc/client/gui/application-hooks.scm
src/scm/webid-oidc/client/gui/account-widget.scm
-src/scm/webid-oidc/client/gui/accounts-widget.scm
src/scm/webid-oidc/client/gui/accounts-widget-logic.scm
+src/scm/webid-oidc/client/gui/accounts-widget.scm
+src/scm/webid-oidc/client/gui/application-hooks.scm
+src/scm/webid-oidc/client/gui/application.scm
src/scm/webid-oidc/client/gui/authorization-prompt.scm
src/scm/webid-oidc/client/gui/authorizations-widget.scm
src/scm/webid-oidc/client/gui/client-widget.scm
@@ -84,4 +84,10 @@ src/scm/webid-oidc/web-i18n.scm
src/ui/account-widget.glade
src/ui/authorization-prompt.glade
src/ui/client-widget.glade
-src/ui/main-window.glade \ No newline at end of file
+src/ui/error-page.glade
+src/ui/link-widget.glade
+src/ui/loaded-page.glade
+src/ui/loading-page.glade
+src/ui/main-window.glade
+src/ui/new-page.glade
+src/ui/updated-page.glade \ No newline at end of file
diff --git a/po/disfluid.pot b/po/disfluid.pot
index c8e9654..274f6b3 100644
--- a/po/disfluid.pot
+++ b/po/disfluid.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: disfluid SNAPSHOT\n"
"Report-Msgid-Bugs-To: vivien@planete-kraus.eu\n"
-"POT-Creation-Date: 2021-10-12 18:30+0200\n"
+"POT-Creation-Date: 2021-10-12 22:25+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -345,7 +345,7 @@ msgid "The application you are trying to authorize behaved unexpectedly."
msgstr ""
#: src/scm/webid-oidc/authorization-page-unsafe.scm:126
-#: src/scm/webid-oidc/resource-server.scm:316
+#: src/scm/webid-oidc/resource-server.scm:317
msgid "reason-phrase|Found"
msgstr ""
@@ -491,7 +491,7 @@ msgstr ""
msgid "#:grant-types should be a list of symbols"
msgstr ""
-#: src/scm/webid-oidc/client.scm:283 src/scm/webid-oidc/resource-server.scm:176
+#: src/scm/webid-oidc/client.scm:283 src/scm/webid-oidc/resource-server.scm:177
msgid "reason-phrase|Not Modified"
msgstr ""
@@ -615,22 +615,37 @@ msgstr ""
msgid "The issuer should be a string or URI."
msgstr ""
-#: src/scm/webid-oidc/client/application.scm:242
+#: src/scm/webid-oidc/client/application.scm:259
#, scheme-format
msgid "Add an account on ~a"
msgstr ""
-#: src/scm/webid-oidc/client/application.scm:257
+#: src/scm/webid-oidc/client/application.scm:274
#, scheme-format
msgid ""
"You already have an account for ~a issued by ~a and it is currently selected."
msgstr ""
-#: src/scm/webid-oidc/client/application.scm:276
+#: src/scm/webid-oidc/client/application.scm:293
#, scheme-format
msgid "You already have an account for ~a issued by ~a."
msgstr ""
+#: src/scm/webid-oidc/client/application.scm:493
+#, scheme-format
+msgid "Loading ~a..."
+msgstr ""
+
+#: src/scm/webid-oidc/client/application.scm:572
+#, scheme-format
+msgid "Updating ~a (expected ETag ~a)"
+msgstr ""
+
+#: src/scm/webid-oidc/client/application.scm:619
+#, scheme-format
+msgid "Deleting ~a (expected ETag ~a)"
+msgstr ""
+
#: src/scm/webid-oidc/client/client.scm:91
msgid ""
"Client ID and redirect URIs should be URIs, and key pair should be a key "
@@ -642,16 +657,16 @@ msgstr ""
msgid "The application state changed: it is now ~a.\n"
msgstr ""
-#: src/scm/webid-oidc/client/gui/application.scm:116
-msgid "Coming soon!"
+#: src/scm/webid-oidc/client/gui/accounts-widget-logic.scm:66
+msgid "Stub: please enter an URI or a host name...\n"
msgstr ""
#: src/scm/webid-oidc/client/gui/accounts-widget.scm:87
msgid "Please add an account."
msgstr ""
-#: src/scm/webid-oidc/client/gui/accounts-widget-logic.scm:66
-msgid "Stub: please enter an URI or a host name...\n"
+#: src/scm/webid-oidc/client/gui/application.scm:116
+msgid "Coming soon!"
msgstr ""
#: src/scm/webid-oidc/client/gui/authorization-prompt.scm:75
@@ -1027,7 +1042,7 @@ msgid "The port should be a number between 0 and 65535.\n"
msgstr ""
#: src/scm/webid-oidc/hello-world.scm:159
-#: src/scm/webid-oidc/resource-server.scm:337
+#: src/scm/webid-oidc/resource-server.scm:338
msgid "reason-phrase|Unauthorized"
msgstr ""
@@ -1040,7 +1055,7 @@ msgid "<p>This page requires authentication with Solid.</p>"
msgstr ""
#: src/scm/webid-oidc/hello-world.scm:179
-#: src/scm/webid-oidc/resource-server.scm:345
+#: src/scm/webid-oidc/resource-server.scm:346
msgid "reason-phrase|Method Not Allowed"
msgstr ""
@@ -2079,64 +2094,64 @@ msgstr ""
msgid "the refresh token is bound to key ~s, which is not that one"
msgstr ""
-#: src/scm/webid-oidc/resource-server.scm:58
+#: src/scm/webid-oidc/resource-server.scm:59
msgid ""
"You need to pass #:server-uri URI where URI is the public URI of the server, "
"as a (web uri)."
msgstr ""
-#: src/scm/webid-oidc/resource-server.scm:85
+#: src/scm/webid-oidc/resource-server.scm:86
#, scheme-format
msgid "~a: authentication failure: ~a\n"
msgstr ""
-#: src/scm/webid-oidc/resource-server.scm:89
+#: src/scm/webid-oidc/resource-server.scm:90
#, scheme-format
msgid "~a: authentication failure\n"
msgstr ""
-#: src/scm/webid-oidc/resource-server.scm:161
-#: src/scm/webid-oidc/resource-server.scm:368
+#: src/scm/webid-oidc/resource-server.scm:162
+#: src/scm/webid-oidc/resource-server.scm:369
msgid "reason-phrase|Precondition Failed"
msgstr ""
-#: src/scm/webid-oidc/resource-server.scm:198
+#: src/scm/webid-oidc/resource-server.scm:199
msgid "The owner is not defined."
msgstr ""
-#: src/scm/webid-oidc/resource-server.scm:248
-#: src/scm/webid-oidc/resource-server.scm:271
+#: src/scm/webid-oidc/resource-server.scm:249
+#: src/scm/webid-oidc/resource-server.scm:272
msgid "Bad Request"
msgstr ""
-#: src/scm/webid-oidc/resource-server.scm:282
+#: src/scm/webid-oidc/resource-server.scm:283
msgid "reason-phrase|Created"
msgstr ""
-#: src/scm/webid-oidc/resource-server.scm:305
+#: src/scm/webid-oidc/resource-server.scm:306
#, scheme-format
msgid "~a: ignoring a group that cannot be fetched: ~a\n"
msgstr ""
-#: src/scm/webid-oidc/resource-server.scm:309
+#: src/scm/webid-oidc/resource-server.scm:310
#, scheme-format
msgid "~a: ignoring a group that cannot be fetched\n"
msgstr ""
-#: src/scm/webid-oidc/resource-server.scm:333
+#: src/scm/webid-oidc/resource-server.scm:334
#: src/scm/webid-oidc/token-endpoint.scm:104
msgid "reason-phrase|Forbidden"
msgstr ""
-#: src/scm/webid-oidc/resource-server.scm:354
+#: src/scm/webid-oidc/resource-server.scm:355
msgid "reason-phrase|Conflict"
msgstr ""
-#: src/scm/webid-oidc/resource-server.scm:361
+#: src/scm/webid-oidc/resource-server.scm:362
msgid "reason-phrase|Unsupported Media Type"
msgstr ""
-#: src/scm/webid-oidc/resource-server.scm:375
+#: src/scm/webid-oidc/resource-server.scm:376
msgid "reason-phrase|Not Acceptable"
msgstr ""
@@ -2333,10 +2348,54 @@ msgstr ""
msgid "Undo"
msgstr ""
-#: src/ui/client-widget.glade:149
+#: src/ui/client-widget.glade:149 src/ui/updated-page.glade:102
msgid "Update"
msgstr ""
+#: src/ui/error-page.glade:45
+msgid "The request failed:"
+msgstr ""
+
+#: src/ui/error-page.glade:57
+msgid "404"
+msgstr ""
+
+#: src/ui/error-page.glade:73
+msgid "Not Found"
+msgstr ""
+
+#: src/ui/link-widget.glade:20
+msgid "https://example.com"
+msgstr ""
+
+#: src/ui/link-widget.glade:39
+msgid "rel"
+msgstr ""
+
+#: src/ui/link-widget.glade:51
+msgid "="
+msgstr ""
+
+#: src/ui/link-widget.glade:63
+msgid "type"
+msgstr ""
+
+#: src/ui/loaded-page.glade:40
+msgid "text/turtle"
+msgstr ""
+
+#: src/ui/loaded-page.glade:52
+msgid "@prefix rdf: ..."
+msgstr ""
+
+#: src/ui/loaded-page.glade:67
+msgid "Delete"
+msgstr ""
+
+#: src/ui/loaded-page.glade:80
+msgid "Update…"
+msgstr ""
+
#: src/ui/main-window.glade:29
msgid "Explore"
msgstr ""
@@ -2352,3 +2411,19 @@ msgstr ""
#: src/ui/main-window.glade:73
msgid "Settings"
msgstr ""
+
+#: src/ui/new-page.glade:27
+msgid "Enter an URI in the URI bar above to start your journey."
+msgstr ""
+
+#: src/ui/updated-page.glade:20
+msgid "Content type:"
+msgstr ""
+
+#: src/ui/updated-page.glade:55
+msgid "Content:"
+msgstr ""
+
+#: src/ui/updated-page.glade:89
+msgid "Discard edits"
+msgstr ""
diff --git a/po/fr.po b/po/fr.po
index 18026ee..1ea4749 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: webid-oidc 0.0.0\n"
"Report-Msgid-Bugs-To: vivien@planete-kraus.eu\n"
-"POT-Creation-Date: 2021-10-12 18:30+0200\n"
-"PO-Revision-Date: 2021-10-11 16:45+0200\n"
+"POT-Creation-Date: 2021-10-12 22:25+0200\n"
+"PO-Revision-Date: 2021-10-12 22:26+0200\n"
"Last-Translator: Vivien Kraus <vivien@planete-kraus.eu>\n"
"Language-Team: French <vivien@planete-kraus.eu>\n"
"Language: fr\n"
@@ -377,7 +377,7 @@ msgstr ""
"L’application que vous essayez d’autoriser se comporte de façon inattendue."
#: src/scm/webid-oidc/authorization-page-unsafe.scm:126
-#: src/scm/webid-oidc/resource-server.scm:316
+#: src/scm/webid-oidc/resource-server.scm:317
msgid "reason-phrase|Found"
msgstr "Trouvé"
@@ -533,7 +533,7 @@ msgstr "#:response-types doit être une liste de symboles"
msgid "#:grant-types should be a list of symbols"
msgstr "#:grant-types doit être une liste de symboles"
-#: src/scm/webid-oidc/client.scm:283 src/scm/webid-oidc/resource-server.scm:176
+#: src/scm/webid-oidc/client.scm:283 src/scm/webid-oidc/resource-server.scm:177
msgid "reason-phrase|Not Modified"
msgstr "Non Modifié"
@@ -664,12 +664,12 @@ msgstr "Le sujet doit être une chaîne de caractères ou une URI."
msgid "The issuer should be a string or URI."
msgstr "L’émetteur doit être une chaîne de caractères ou une URI."
-#: src/scm/webid-oidc/client/application.scm:242
+#: src/scm/webid-oidc/client/application.scm:259
#, scheme-format
msgid "Add an account on ~a"
msgstr "Ajouter un compte sur ~a"
-#: src/scm/webid-oidc/client/application.scm:257
+#: src/scm/webid-oidc/client/application.scm:274
#, scheme-format
msgid ""
"You already have an account for ~a issued by ~a and it is currently selected."
@@ -677,11 +677,26 @@ msgstr ""
"Vous avez déjà un compte pour ~a émis par ~a et il est actuellement "
"sélectionné."
-#: src/scm/webid-oidc/client/application.scm:276
+#: src/scm/webid-oidc/client/application.scm:293
#, scheme-format
msgid "You already have an account for ~a issued by ~a."
msgstr "Vous avez déjà un compte pour ~a émis par ~a."
+#: src/scm/webid-oidc/client/application.scm:493
+#, scheme-format
+msgid "Loading ~a..."
+msgstr "Chargement de ~a…"
+
+#: src/scm/webid-oidc/client/application.scm:572
+#, scheme-format
+msgid "Updating ~a (expected ETag ~a)"
+msgstr "Mise à jour de ~a (ETag attendu ~a)"
+
+#: src/scm/webid-oidc/client/application.scm:619
+#, scheme-format
+msgid "Deleting ~a (expected ETag ~a)"
+msgstr "Suppression de ~a (ETag attendu ~a)"
+
#: src/scm/webid-oidc/client/client.scm:91
msgid ""
"Client ID and redirect URIs should be URIs, and key pair should be a key "
@@ -695,17 +710,17 @@ msgstr ""
msgid "The application state changed: it is now ~a.\n"
msgstr "L’état de l’application a changé : c’est maintenant ~a.\n"
-#: src/scm/webid-oidc/client/gui/application.scm:116
-msgid "Coming soon!"
-msgstr "C’est pour bientôt !"
+#: src/scm/webid-oidc/client/gui/accounts-widget-logic.scm:66
+msgid "Stub: please enter an URI or a host name...\n"
+msgstr "Bouchon : veuillez entrer une URI ou un nom d’hôte…\n"
#: src/scm/webid-oidc/client/gui/accounts-widget.scm:87
msgid "Please add an account."
msgstr "Veuillez ajouter un compte."
-#: src/scm/webid-oidc/client/gui/accounts-widget-logic.scm:66
-msgid "Stub: please enter an URI or a host name...\n"
-msgstr "Bouchon : veuillez entrer une URI ou un nom d’hôte…\n"
+#: src/scm/webid-oidc/client/gui/application.scm:116
+msgid "Coming soon!"
+msgstr "C’est pour bientôt !"
#: src/scm/webid-oidc/client/gui/authorization-prompt.scm:75
#, scheme-format
@@ -1130,7 +1145,7 @@ msgid "The port should be a number between 0 and 65535.\n"
msgstr "Le port doit être un nombre entre 0 et 65535.\n"
#: src/scm/webid-oidc/hello-world.scm:159
-#: src/scm/webid-oidc/resource-server.scm:337
+#: src/scm/webid-oidc/resource-server.scm:338
msgid "reason-phrase|Unauthorized"
msgstr "Non Autorisé"
@@ -1143,7 +1158,7 @@ msgid "<p>This page requires authentication with Solid.</p>"
msgstr "<p>Cette page requiert une authentification avec Solid.</p>"
#: src/scm/webid-oidc/hello-world.scm:179
-#: src/scm/webid-oidc/resource-server.scm:345
+#: src/scm/webid-oidc/resource-server.scm:346
msgid "reason-phrase|Method Not Allowed"
msgstr "Méthode Non Autorisée"
@@ -2458,7 +2473,7 @@ msgid "the refresh token is bound to key ~s, which is not that one"
msgstr ""
"le jeton de rafraîchissement est lié à la clé ~s, ce n’est pas celle utilisée"
-#: src/scm/webid-oidc/resource-server.scm:58
+#: src/scm/webid-oidc/resource-server.scm:59
msgid ""
"You need to pass #:server-uri URI where URI is the public URI of the server, "
"as a (web uri)."
@@ -2466,60 +2481,58 @@ msgstr ""
"Vous devez passer #:server-uri URI où URI est l’URI publique du serveur, "
"comme dans (web uri)."
-#: src/scm/webid-oidc/resource-server.scm:85
+#: src/scm/webid-oidc/resource-server.scm:86
#, scheme-format
msgid "~a: authentication failure: ~a\n"
msgstr "~a : échec d’authentificationn : ~a\n"
-#: src/scm/webid-oidc/resource-server.scm:89
+#: src/scm/webid-oidc/resource-server.scm:90
#, scheme-format
msgid "~a: authentication failure\n"
msgstr "~a : échec d’authentification\n"
-#: src/scm/webid-oidc/resource-server.scm:161
-#: src/scm/webid-oidc/resource-server.scm:368
+#: src/scm/webid-oidc/resource-server.scm:162
+#: src/scm/webid-oidc/resource-server.scm:369
msgid "reason-phrase|Precondition Failed"
msgstr "Échec de Précondition"
-#: src/scm/webid-oidc/resource-server.scm:198
+#: src/scm/webid-oidc/resource-server.scm:199
msgid "The owner is not defined."
msgstr "Le propriétaire n’est pas défini."
-#: src/scm/webid-oidc/resource-server.scm:248
-#: src/scm/webid-oidc/resource-server.scm:271
-#, fuzzy
-#| msgid "Bad request"
+#: src/scm/webid-oidc/resource-server.scm:249
+#: src/scm/webid-oidc/resource-server.scm:272
msgid "Bad Request"
msgstr "Requête invalide"
-#: src/scm/webid-oidc/resource-server.scm:282
+#: src/scm/webid-oidc/resource-server.scm:283
msgid "reason-phrase|Created"
msgstr "Créé"
-#: src/scm/webid-oidc/resource-server.scm:305
+#: src/scm/webid-oidc/resource-server.scm:306
#, scheme-format
msgid "~a: ignoring a group that cannot be fetched: ~a\n"
msgstr "~a : j’ignore un groupe qui n’a pas pu être téléchargé : ~a\n"
-#: src/scm/webid-oidc/resource-server.scm:309
+#: src/scm/webid-oidc/resource-server.scm:310
#, scheme-format
msgid "~a: ignoring a group that cannot be fetched\n"
msgstr "~a : j’ignore un groupe qui ne peut pas être téléchargé\n"
-#: src/scm/webid-oidc/resource-server.scm:333
+#: src/scm/webid-oidc/resource-server.scm:334
#: src/scm/webid-oidc/token-endpoint.scm:104
msgid "reason-phrase|Forbidden"
msgstr "Interdit"
-#: src/scm/webid-oidc/resource-server.scm:354
+#: src/scm/webid-oidc/resource-server.scm:355
msgid "reason-phrase|Conflict"
msgstr "Conflit"
-#: src/scm/webid-oidc/resource-server.scm:361
+#: src/scm/webid-oidc/resource-server.scm:362
msgid "reason-phrase|Unsupported Media Type"
msgstr "Type de Média Non Supporté"
-#: src/scm/webid-oidc/resource-server.scm:375
+#: src/scm/webid-oidc/resource-server.scm:376
msgid "reason-phrase|Not Acceptable"
msgstr "Inacceptable"
@@ -2725,10 +2738,54 @@ msgstr "Générer une paire de clés"
msgid "Undo"
msgstr "Annuler"
-#: src/ui/client-widget.glade:149
+#: src/ui/client-widget.glade:149 src/ui/updated-page.glade:102
msgid "Update"
msgstr "Mettre à jour"
+#: src/ui/error-page.glade:45
+msgid "The request failed:"
+msgstr "La requête a échoué :"
+
+#: src/ui/error-page.glade:57
+msgid "404"
+msgstr "404"
+
+#: src/ui/error-page.glade:73
+msgid "Not Found"
+msgstr "Non Trouvé"
+
+#: src/ui/link-widget.glade:20
+msgid "https://example.com"
+msgstr "https://exemple.com"
+
+#: src/ui/link-widget.glade:39
+msgid "rel"
+msgstr "rel"
+
+#: src/ui/link-widget.glade:51
+msgid "="
+msgstr "="
+
+#: src/ui/link-widget.glade:63
+msgid "type"
+msgstr "type"
+
+#: src/ui/loaded-page.glade:40
+msgid "text/turtle"
+msgstr "text/turtle"
+
+#: src/ui/loaded-page.glade:52
+msgid "@prefix rdf: ..."
+msgstr "@prefix rdf: ..."
+
+#: src/ui/loaded-page.glade:67
+msgid "Delete"
+msgstr "Supprimer"
+
+#: src/ui/loaded-page.glade:80
+msgid "Update…"
+msgstr "Mise à jour…"
+
#: src/ui/main-window.glade:29
msgid "Explore"
msgstr "Explorer"
@@ -2745,6 +2802,55 @@ msgstr "Comptes"
msgid "Settings"
msgstr "Paramètres"
+#: src/ui/new-page.glade:27
+msgid "Enter an URI in the URI bar above to start your journey."
+msgstr "Entrez une URI dans la bare d’URI pour commencer votre voyage."
+
+#: src/ui/updated-page.glade:20
+msgid "Content type:"
+msgstr "Type de contenu :"
+
+#: src/ui/updated-page.glade:55
+msgid "Content:"
+msgstr "Contenu :"
+
+#: src/ui/updated-page.glade:89
+msgid "Discard edits"
+msgstr "Rejeter les modifications"
+
+#~ msgid "the page URI (#:uri) should be a string encoding an URI or an URI"
+#~ msgstr ""
+#~ "l’URI de la page doit être une chaîne de caractères encodant une URI ou "
+#~ "une URI"
+
+#~ msgid ""
+#~ "the error code (#:code) should be an integer and the reason phrase (#:"
+#~ "reason-phrase) should be a string"
+#~ msgstr ""
+#~ "le code d’erreur (#:code) doit être un entier et l’explication (#:reason-"
+#~ "phrase) doit être une chaîne de caractères"
+
+#~ msgid ""
+#~ "the etag (#:etag) should be a string, the links (#:links) should be a "
+#~ "list of links, the content-type (#:content-type) should be a symbol, and "
+#~ "the content (#:content) should be a string or a bytevector"
+#~ msgstr ""
+#~ "l’etag (#:etag) doit être une chaîne de caractères, les liens (#:links) "
+#~ "doivent être une liste de liens, le type de contenu (#:content-type) doit "
+#~ "être un symbole, et le contenu (#:content) doit être une chaîne de "
+#~ "caractères ou un vecteur d’octets"
+
+#~ msgid ""
+#~ "the desired links (#:desired-links) should be an alist from URI to "
+#~ "alists, the desired content-type (#:desired-content-type) should be a "
+#~ "symbol, and the desired content (#:desired-content) should be a string or "
+#~ "a bytevector"
+#~ msgstr ""
+#~ "les liens désirés (#:desired-links) doivent être une aliste d’URIs vers "
+#~ "des alistes, le type de contenu désiré (#:desired-content-type) doit être "
+#~ "un symbole, et le ccontenu désiré (#:desired-content-type) doit être unne "
+#~ "chaîne de caractères ou un vecteur d’octets"
+
#~ msgid "Disfluid"
#~ msgstr "Disfluid"
diff --git a/src/scm/webid-oidc/client/application.scm b/src/scm/webid-oidc/client/application.scm
index 5185cfb..58d1dad 100644
--- a/src/scm/webid-oidc/client/application.scm
+++ b/src/scm/webid-oidc/client/application.scm
@@ -28,6 +28,7 @@
#:use-module (srfi srfi-9)
#:use-module (srfi srfi-19)
#:use-module (webid-oidc errors)
+ #:use-module (webid-oidc http-link)
#:use-module ((webid-oidc parameters) #:prefix p:)
#:use-module ((webid-oidc stubs) #:prefix stubs:)
#:use-module ((webid-oidc oidc-id-token) #:prefix id:)
@@ -52,7 +53,15 @@
authorization-uri reason continuation
<application-state>
- main-account other-accounts client error-messages authorization-prompts running-jobs pages
+ main-account other-accounts client error-messages authorization-prompts running-jobs page
+
+ <page>
+ <new-page>
+ <page-with-uri> uri
+ <loading-page>
+ <error-page> code reason-phrase
+ <loaded-page> etag links content-type content
+ <updated-page> desired-links desired-content-type desired-content
add-account
choose-account
@@ -60,9 +69,15 @@
set-accounts
set-client
fold-authorization-prompts
- add-page
set-page-uri
- close-page
+ edit-page
+ remove-link
+ add-link
+ change-content-type
+ change-content
+ discard-updates
+ commit-updates
+ delete-page
)
#:declarative? #t)
@@ -120,10 +135,12 @@
#:init-keywords #:running-jobs
#:getter running-jobs
#:init-value '())
- (pages
- #:init-keyword #:pages
- #:getter pages
- #:init-value '()))
+ (page
+ #:init-keyword #:page
+ #:getter page
+ #:init-thunk
+ (lambda ()
+ (make <new-page>))))
(define-method (equal? (x <application-state>) (y <application-state>))
(and (equal? (main-account x) (main-account y))
@@ -132,7 +149,7 @@
(equal? (error-messages x) (error-messages y))
(equal? (authorization-prompts x) (authorization-prompts y))
(equal? (running-jobs x) (running-jobs y))
- (equal? (pages x) (pages y))))
+ (equal? (page x) (page y))))
(define-method (display (state <application-state>) port)
(format port "#<<application-state> main-account=~a other-accounts=~a client=~a error-messages=~a authorization-prompts=~a running-jobs=~a>"
@@ -351,8 +368,7 @@
with-unresolved-prompt))))
(iter prompts seed state)))))))
-(define-class <page> ()
- (identifier #:init-keyword #:identifier #:getter identifier))
+(define-class <page> ())
(define-method (equal? (x <page>) (y <page>))
(and (equal? (identifier x) (identifier y))))
@@ -372,64 +388,257 @@
(reason-phrase #:init-keyword #:reason-phrase #:getter reason-phrase))
(define-method (equal? (x <error-page>) (y <error-page>))
- (and (equal? (code x) (code y))
+ (and (equal? (uri x) (uri y))
+ (equal? (code x) (code y))
(equal? (reason-phrase x) (reason-phrase y))))
(define-class <loaded-page> (<page-with-uri>)
(etag #:init-keyword #:etag #:getter etag)
- (links #:init-keyword #:links #:getter links))
+ (links #:init-keyword #:links #:getter links)
+ (content-type #:init-keyword #:content-type #:getter content-type)
+ (content #:init-keyword #:content #:getter content))
(define-method (equal? (x <loaded-page>) (y <loaded-page>))
- (and (equal? (etag x) (etag y))
- (equal? (links x) (links y))))
+ (and (equal? (uri x) (uri y))
+ (equal? (etag x) (etag y))
+ (equal? (links x) (links y))
+ (equal? (content-type x) (content-type y))
+ (equal? (content x) (content y))))
-(define-class <rdf-page> (<loaded-page>)
- (triples #:init-keyword #:triples #:getter triples))
+(define-class <updated-page> (<loaded-page>)
+ (desired-links #:init-keyword #:desired-links #:getter desired-links)
+ (desired-content-type #:init-keyword #:desired-content-type #:getter desired-content-type)
+ (desired-content #:init-keyword #:desired-content #:getter desired-content))
+
+(define-method (equal? (x <updated-page>) (y <updated-page>))
+ (and (equal? (uri x) (uri y))
+ (equal? (etag x) (etag y))
+ (equal? (links x) (links y))
+ (equal? (content-type x) (content-type y))
+ (equal? (content x) (content y))
+ (equal? (desired-links x) (desired-links y))
+ (equal? (desired-content-type x) (desired-content-type y))
+ (equal? (desired-content x) (desired-content y))))
+
+(define-method (edit-page (page <page>))
+ page)
+
+(define-method (edit-page (page <loaded-page>))
+ (make <updated-page>
+ #:uri (uri page)
+ #:etag (etag page)
+ #:links (links page)
+ #:content-type (content-type page)
+ #:content (content page)
+ #:desired-links (links page)
+ #:desired-content-type (content-type page)
+ #:desired-content (content page)))
+
+(define-method (edit-page (page <updated-page>))
+ page)
+
+(define-method (edit-page (state <application-state>))
+ (let ((ret (shallow-clone state)))
+ (slot-set! ret 'page (edit-page (page ret)))
+ ret))
-(define-method (equal? (x <rdf-page>) (y <rdf-page>))
- (and (equal? (triples x) (triples y))))
+(define-method (remove-link (page <page>) target key value)
+ (let ((ret (edit-page page)))
+ (when (is-a? ret <updated-page>)
+ (let ((filtered
+ (map (match-lambda
+ (((? (cute equal? <> target)) attributes ...)
+ `(,target
+ ,(filter
+ (match-lambda
+ ((the-key . the-value)
+ (and (equal? the-key key)
+ (equal? the-value value))))
+ attributes)))
+ (other other))
+ (links ret))))
+ (slot-set! ret 'desired-links
+ (filter (match-lambda
+ (((? uri?) ())
+ #f)
+ (else #t))
+ filtered))))
+ ret))
-(define-class <non-rdf-page> (<loaded-page>)
- (content-type #:init-keyword #:content-type #:getter content-type)
- (content #:init-keyword #:content #:getter content))
+(define-method (remove-link (state <application-state>) target key value)
+ (let ((ret (shallow-clone state)))
+ (slot-set! ret 'page (remove-link (page ret) target key value))
+ ret))
-(define-method (equal? (x <non-rdf-page>) (y <non-rdf-page>))
- (and (equal? (content-type x) (content-type y))
- (equal? (content x) (content y))))
+(define-method (add-link (page <page>) target key value)
+ (let ((ret (edit-page page)))
+ (when (is-a? ret <updated-page>)
+ (slot-set! ret 'desired-links
+ `((,target (,key . ,value))
+ ,@(desired-links page))))
+ ret))
+
+(define-method (add-link (state <application-state>) target key value)
+ (let ((ret (shallow-clone state)))
+ (slot-set! ret 'page (add-link (page ret) (string->uri target) key value))
+ ret))
-(define-method (add-page (state <application-state>) (identifier <string>))
+(define-method (set-page-uri (state <application-state>) uri)
+ (let ((ret (shallow-clone state))
+ (new-page (make <loading-page>
+ #:uri uri)))
+ (slot-set! ret 'page new-page)
+ (add-job
+ ret
+ (format #f (G_ "Loading ~a...") (uri->string uri))
+ (lambda ()
+ (declare-link-header!)
+ (let ((account (main-account state))
+ (client (client state)))
+ (parameterize ((client:client client))
+ (receive (updated-account response response-body)
+ (client:request account (uri new-page))
+ (lambda (previous-state)
+ (let ((ret (shallow-clone previous-state)))
+ ;; If the main client hasn’t changed, update it
+ (when (equal? (main-account previous-state) account)
+ (slot-set! ret 'main-account updated-account))
+ ;; If the page hasn’t changed, update it
+ (when (equal? (page previous-state)
+ new-page)
+ (slot-set! ret 'page
+ (if (eqv? (response-code response) 200)
+ (make <loaded-page>
+ #:uri uri
+ #:etag
+ (match (response-etag response)
+ ((value . #f) value)
+ (else #f))
+ #:links
+ (response-links response)
+ #:content-type
+ (response-content-type response)
+ #:content
+ (or (false-if-exception (bytevector->string response-body))
+ response-body))
+ (make <error-page>
+ #:uri uri
+ #:code (response-code response)
+ #:reason-phrase (response-reason-phrase response)))))
+ ret)))))))))
+
+(define-method (change-content-type (state <application-state>) content-type)
(let ((ret (shallow-clone state)))
- (slot-set! ret 'pages
- `(,(make <new-page> #:identifier identifier)
- ,@(pages state)))
+ (slot-set!
+ ret 'page
+ (let ((p (edit-page (page ret))))
+ (slot-set! p 'desired-content-type content-type)
+ p))
ret))
-(define-method (set-page-uri (state <application-state>) (id <string>) uri)
+(define-method (change-content (state <application-state>) content)
(let ((ret (shallow-clone state)))
- (slot-set! ret 'pages
- (let replace-page ((pages (pages state))
- (untouched-pages '()))
- (match pages
- (()
- (reverse untouched-pages))
- ((hd tl ...)
- (let ((replaced
- (if (equal? (identifier hd) id)
- (make <loading-page>
- #:identifier id
- #:uri uri)
- hd)))
- (replace-page
- tl
- `(,replaced
- ,@(untouched-pages))))))))
- ;; TODO: add a job to load the page…
+ (slot-set!
+ ret 'page
+ (let ((p (edit-page (page ret))))
+ (slot-set! p 'desired-content content)
+ p))
ret))
-(define-method (close-page (state <application-state>) (id <string>))
+(define-method (discard-updates (page <page>))
+ page)
+
+(define-method (discard-updates (page <updated-page>))
+ (make <loaded-page>
+ #:uri (uri page)
+ #:etag (etag page)
+ #:links (links page)
+ #:content-type (content-type page)
+ #:content (content page)))
+
+(define-method (discard-updates (state <application-state>))
(let ((ret (shallow-clone state)))
- (slot-set! ret 'pages
- (filter (lambda (page)
- (not (equal? (identifier page) id)))
- (pages state)))
+ (slot-set! ret 'page (discard-updates (page state)))
ret))
+
+(define-method (commit-updates (state <application-state>))
+ (let ((loading (shallow-clone state)))
+ (slot-set! loading 'page
+ (make <loading-page>
+ #:uri (uri (page state))))
+ (if (is-a? (page state) <updated-page>)
+ (add-job
+ loading
+ (format #f (G_ "Updating ~a (expected ETag ~a)")
+ (uri->string (uri (page state)))
+ (etag (page state)))
+ (lambda ()
+ (let ((account (main-account state))
+ (client (client state)))
+ (parameterize ((client:client client))
+ (receive (updated-account response response-body)
+ (client:request account (uri (page state))
+ #:method 'PUT
+ #:headers `(,@(let ((etag (etag (page state))))
+ (if etag
+ `((if-match . ((,etag . #f))))
+ '()))
+ ,@(map
+ (lambda (link)
+ `(link . ,link))
+ (desired-links (page state)))
+ (content-type . (,(desired-content-type (page state)))))
+ #:body (desired-content (page state)))
+ (lambda (previous-state)
+ (let ((ret (shallow-clone previous-state)))
+ (when (equal? (main-account previous-state) account)
+ (slot-set! ret 'main-account updated-account))
+ (when (equal? (page previous-state)
+ (page loading))
+ (slot-set! ret 'page
+ (if (eqv? (response-code response) 200)
+ (make <loaded-page>
+ #:uri (uri (page state))
+ #:etag (match (response-etag response)
+ ((etag . #f) etag)
+ (else #f))
+ #:links (desired-links (page state))
+ #:content-type (desired-content-type (page state))
+ #:content (desired-content (page state)))
+ (make <error-page>
+ #:uri (uri (page state))
+ #:code (response-code response)
+ #:reason-phrase (response-reason-phrase response)))))
+ ret)))))))
+ state)))
+
+(define-method (delete-page (state <application-state>))
+ (if (is-a? (page state) <page-with-uri>)
+ (add-job
+ state
+ (format #f (G_ "Deleting ~a (expected ETag ~a)")
+ (uri (page state))
+ (and (is-a? (page state) <loaded-page>)
+ (etag (page state))))
+ (lambda ()
+ (let ((account (main-account state))
+ (client (client state)))
+ (parameterize ((client:client client))
+ (receive (updated-account response response-body)
+ (client:request account (uri (page state))
+ #:method 'DELETE
+ #:headers `(,@(let ((etag (and (is-a? (page state) <loaded-page>)
+ (etag (page state)))))
+ (if etag
+ `((if-match . (,(etag (page state)) . #f)))
+ '()))))
+ (lambda (previous-state)
+ (let ((ret (shallow-clone previous-state)))
+ (when (equal? (main-account previous-state) account)
+ (slot-set! ret 'main-account updated-account))
+ (when (equal? (page previous-state)
+ (page state))
+ (slot-set! ret 'page
+ (make <new-page>)))
+ ret)))))))
+ state))
diff --git a/src/ui/Makefile.am b/src/ui/Makefile.am
index cbd7b0f..0d04326 100644
--- a/src/ui/Makefile.am
+++ b/src/ui/Makefile.am
@@ -20,4 +20,10 @@ dist_uipkgdata_DATA = \
%reldir%/account-widget.glade \
%reldir%/accounts-widget.glade \
%reldir%/authorization-prompt.glade \
- %reldir%/main-window.glade
+ %reldir%/main-window.glade \
+ %reldir%/error-page.glade \
+ %reldir%/link-widget.glade \
+ %reldir%/loaded-page.glade \
+ %reldir%/loading-page.glade \
+ %reldir%/new-page.glade \
+ %reldir%/updated-page.glade
diff --git a/src/ui/error-page.glade b/src/ui/error-page.glade
new file mode 100644
index 0000000..a3d7a98
--- /dev/null
+++ b/src/ui/error-page.glade
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface>
+ <requires lib="gtk+" version="3.22"/>
+ <object class="GtkBox" id="error_page">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkEntry" id="uri_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="input_purpose">url</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="orientation">vertical</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</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="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">The request failed:</property>
+ </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">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">404</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ <attribute name="size" value="32768"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="reason_phrase">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Not Found</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ <attribute name="size" value="16384"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/src/ui/link-widget.glade b/src/ui/link-widget.glade
new file mode 100644
index 0000000..cce37c4
--- /dev/null
+++ b/src/ui/link-widget.glade
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface>
+ <requires lib="gtk+" version="3.22"/>
+ <object class="GtkBox" id="link_widget">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLinkButton" id="target_iri">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="relief">none</property>
+ <property name="uri">http://glade.gnome.org</property>
+ <child>
+ <object class="GtkLabel" id="target_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">https://example.com</property>
+ <property name="ellipsize">end</property>
+ </object>
+ </child>
+ </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>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">rel</property>
+ </object>
+ <packing>
+ <property name="expand">True</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">=</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="relation_type">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">type</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/src/ui/loaded-page.glade b/src/ui/loaded-page.glade
new file mode 100644
index 0000000..9517d2f
--- /dev/null
+++ b/src/ui/loaded-page.glade
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface>
+ <requires lib="gtk+" version="3.22"/>
+ <object class="GtkBox" id="loaded_page">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkEntry" id="uri_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="input_purpose">url</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="links_list">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="content_type">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">text/turtle</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="content">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">@prefix rdf: ...</property>
+ <property name="selectable">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkButton" id="button_delete">
+ <property name="label" translatable="yes">Delete</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</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="button_update">
+ <property name="label" translatable="yes">Update…</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</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">4</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/src/ui/loading-page.glade b/src/ui/loading-page.glade
new file mode 100644
index 0000000..203084f
--- /dev/null
+++ b/src/ui/loading-page.glade
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface>
+ <requires lib="gtk+" version="3.22"/>
+ <object class="GtkBox" id="loading_page">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkEntry" id="uri_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="input_purpose">url</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinner">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="active">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/src/ui/new-page.glade b/src/ui/new-page.glade
new file mode 100644
index 0000000..b9703ff
--- /dev/null
+++ b/src/ui/new-page.glade
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface>
+ <requires lib="gtk+" version="3.22"/>
+ <object class="GtkBox" id="new_page">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkEntry" id="uri_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="input_purpose">url</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="margin_start">12</property>
+ <property name="margin_end">12</property>
+ <property name="label" translatable="yes">Enter an URI in the URI bar above to start your journey.</property>
+ <property name="wrap">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/src/ui/updated-page.glade b/src/ui/updated-page.glade
new file mode 100644
index 0000000..e174c55
--- /dev/null
+++ b/src/ui/updated-page.glade
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface>
+ <requires lib="gtk+" version="3.22"/>
+ <object class="GtkTextBuffer" id="content_buffer"/>
+ <object class="GtkBox" id="updated_page">
+ <property name="visible">True</property>
+ <property name="can_focus">False</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>
+ <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">Content type:</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="content_type_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</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>
+ <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">Content:</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkTextView">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="buffer">content_buffer</property>
+ <property name="monospace">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</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">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkButton" id="discard_button">
+ <property name="label" translatable="yes">Discard edits</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</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="update_button">
+ <property name="label" translatable="yes">Update</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</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">4</property>
+ </packing>
+ </child>
+ </object>
+</interface>