From 9a26558e4e2160a8f45953650788221e2e0fe2ba Mon Sep 17 00:00:00 2001
From: Nika Tskhakaia
Date: Fri, 3 Apr 2020 14:14:05 +0000
Subject: [PATCH 01/24] Translated using Weblate (Georgian)
Currently translated at 29.9% (71 of 237 strings)
Translation: Lemmy/lemmy
Translate-URL: http://weblate.yerbamate.dev/projects/lemmy/lemmy/ka/
---
ui/translations/ka.json | 73 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 73 insertions(+)
diff --git a/ui/translations/ka.json b/ui/translations/ka.json
index 2c63c0851..01dbe4ed4 100644
--- a/ui/translations/ka.json
+++ b/ui/translations/ka.json
@@ -1,2 +1,75 @@
{
+ "post": "პოსტი",
+ "remove_post": "პოსტის წაშლა",
+ "no_posts": "0 პოსტები",
+ "create_a_post": "პოსტის შექმნა",
+ "create_post": "პოსტის შექმნა",
+ "number_of_posts": "თარგმნა",
+ "number_of_posts_plural": "თარგმნა",
+ "posts": "პოსტები",
+ "cross_posts": "ეს ლინკი უკვე დადებულია აქ:",
+ "comments": "კომენტარები",
+ "number_of_comments": "კომენტარი",
+ "number_of_comments_plural": "კომანტარები",
+ "remove_comment": "კომენტარის წაშლა",
+ "communities": "თემები",
+ "users": "მომხმარებელი",
+ "create_a_community": "ახალი თემის შექმნა",
+ "create_community": "თემის შექმნა",
+ "remove_community": "თემის წაშლა",
+ "community_reqs": "პატარა ასო, ქვედა ტირე, და გამოტოვების გარეშე.",
+ "create_private_message": "კერძო მესეჯის შექმნა",
+ "send_secure_message": "ინკრიპტული მესეჯის გაგზავნა",
+ "send_message": "მესეჯის გაგზავნა",
+ "message": "მესეჯი",
+ "edit": "რადექტირება",
+ "reply": "პასუხის გაცემა",
+ "more": "მეტი",
+ "cancel": "გაუქება",
+ "upload_image": "სურათის ატვირთვა",
+ "avatar": "ავატარი",
+ "upload_avatar": "ავატარის ატვირთვა",
+ "show_context": "კონტექსტის ნახვა",
+ "sorting_help": "სორტირების დახმარება",
+ "view_source": "view source",
+ "unlock": "გაღება",
+ "lock": "ჩაკეტვა",
+ "sticky": "sticky",
+ "link": "ლინკი",
+ "archive_link": "ლინკის არქივება",
+ "mod": "მოდერატორი",
+ "mods": "მოდერატორები",
+ "moderates": "მოდერატორს",
+ "settings": "პარამეტრები",
+ "appoint_as_mod": "დანიშნე როგორც მოდერატორი",
+ "modlog": "მოდ-ლოგი",
+ "admin": "ადმინი",
+ "admins": "ადმინები",
+ "appoint_as_admin": "დანიშნე როგორც ადმინი",
+ "remove": "მოხსნა",
+ "removed": "მოხსნილია",
+ "locked": "ჩაკეტილი",
+ "stickied": "დაწეპებული",
+ "reason": "მიზეზი",
+ "mark_as_read": "მონიშნე როგორც წაკითხული",
+ "mark_as_unread": "მონიშნე როგორც წაუკითხავი",
+ "delete": "წაშლა",
+ "deleted": "წაშლილია",
+ "delete_account": "ჩემი ანგარიშის წაშლა",
+ "restore": "რასტორაცია",
+ "ban": "გაშავება",
+ "ban_from_site": "გაშავება საიტიდან",
+ "unban": "გაშავების გაუქმნება",
+ "unban_from_site": "სატიდან გაშავების გაუქმნება",
+ "banned": "გაშავებულია",
+ "save": "დამახსოვრება",
+ "unsave": "დამახსოვრების გაუქმნება",
+ "create": "შექმნა",
+ "preview": "წინასწარ ნახვა",
+ "show_avatars": "ავატარები გამოჩენა",
+ "formatting_help": "formatting help",
+ "unsticky": "unsticky",
+ "remove_as_mod": "მოხსენი როგორც მოდერატორი",
+ "remove_as_admin": "მოხსენი როგორც ადმინი",
+ "delete_account_confirm": "გაფთხილება: ეს შენს ყველაფერს წაშლის. პაროლი ჩაწერეთ რომ დაადასტუროთ."
}
From 01f844989880f27de2cbeee4cb12bdbdf26d0b34 Mon Sep 17 00:00:00 2001
From: dessalines
Date: Fri, 3 Apr 2020 14:14:05 +0000
Subject: [PATCH 02/24] Translated using Weblate (French)
Currently translated at 94.0% (223 of 237 strings)
Translation: Lemmy/lemmy
Translate-URL: http://weblate.yerbamate.dev/projects/lemmy/lemmy/fr/
Translated using Weblate (Spanish)
Currently translated at 100.0% (237 of 237 strings)
Translation: Lemmy/lemmy
Translate-URL: http://weblate.yerbamate.dev/projects/lemmy/lemmy/es/
---
ui/translations/es.json | 72 +++++++++++++++++++++++------------------
ui/translations/fr.json | 3 +-
2 files changed, 42 insertions(+), 33 deletions(-)
diff --git a/ui/translations/es.json b/ui/translations/es.json
index 61bebb971..02dac76ed 100644
--- a/ui/translations/es.json
+++ b/ui/translations/es.json
@@ -4,13 +4,15 @@
"no_posts": "Sin publicaciones.",
"create_a_post": "Crear una publicación",
"create_post": "Crear Publicación",
- "number_of_posts": "{{count}} Publicaciones",
+ "number_of_posts": "{{count}} Publicación",
+ "number_of_posts_plural": "{{count}} Publicaciónes",
"posts": "Publicaciones",
"related_posts": "Estas publicaciones podrían estar relacionadas",
"cross_posts": "Este link también ha sido publicado en:",
"cross_post": "cross-post",
"comments": "Comentarios",
- "number_of_comments": "{{count}} Comentarios",
+ "number_of_comments": "{{count}} Comentario",
+ "number_of_comments_plural": "{{count}} Comentarios",
"remove_comment": "Eliminar Comentarios",
"communities": "Comunidades",
"users": "Usuarios",
@@ -20,7 +22,8 @@
"subscribed_to_communities": "Suscrito a <1>comunidades1>",
"trending_communities": "<1>Comunidades1> en tendencia",
"list_of_communities": "Lista de comunidades",
- "number_of_communities": "{{count}} Comunidades",
+ "number_of_communities": "{{count}} Comunidad",
+ "number_of_communities_plural": "{{count}} Comunidades",
"community_reqs": "minúsculas, guión bajo, y sin espacios.",
"create_private_message": "Crear Mensaje Privado",
"send_secure_message": "Enviar Mensaje Seguro",
@@ -63,8 +66,7 @@
"delete": "eliminar",
"deleted": "eliminado",
"delete_account": "Eliminar Cuenta",
- "delete_account_confirm":
- "Aviso: esta acción eliminará permanentemente tu información. Introduce tu contraseña para continuar",
+ "delete_account_confirm": "Aviso: esta acción eliminará permanentemente tu información. Introduce tu contraseña para continuar",
"restore": "restaurar",
"ban": "expulsar",
"ban_from_site": "expulsar del sitio",
@@ -77,10 +79,14 @@
"creator": "creador",
"username": "Nombre de Usuario",
"email_or_username": "Correo o Usuario",
- "number_of_users": "{{count}} Usuarios",
- "number_of_subscribers": "{{count}} Suscriptores",
- "number_of_points": "{{count}} Puntos",
- "number_online": "{{count}} Usuarios En Línea",
+ "number_of_users": "{{count}} Usuario",
+ "number_of_users_plural": "{{count}} Usuarios",
+ "number_of_subscribers": "{{count}} Suscriptor",
+ "number_of_subscribers_plural": "{{count}} Suscriptores",
+ "number_of_points": "{{count}} Punto",
+ "number_of_points_plural": "{{count}} Puntos",
+ "number_online": "{{count}} Usuario En Línea",
+ "number_online_plural": "{{count}} Usuarios En Línea",
"name": "Nombre",
"title": "Titulo",
"category": "Categoría",
@@ -120,8 +126,7 @@
"login_sign_up": "Iniciar sesión / Crear cuenta",
"login": "Iniciar sesión",
"sign_up": "Crear cuenta",
- "notifications_error":
- "Notificaciones de escritorio no disponibles en tu navegador. Prueba Firefox o Chrome.",
+ "notifications_error": "Notificaciones de escritorio no disponibles en tu navegador. Prueba Firefox o Chrome.",
"unread_messages": "Mensajes no leídos",
"messages": "Mensajes",
"password": "Contraseña",
@@ -134,8 +139,7 @@
"no_email_setup": "Este servidor no ha activado correctamente el correo.",
"email": "Correo electrónico",
"matrix_user_id": "Usuario Matricial",
- "private_message_disclaimer":
- "Aviso: Los mensajes privados en Lemmy no son seguros. Por favor cree una cuenta en <1>Riot.im1> para mensajeria segura.",
+ "private_message_disclaimer": "Aviso: Los mensajes privados en Lemmy no son seguros. Por favor cree una cuenta en <1>Riot.im1> para mensajeria segura.",
"send_notifications_to_email": "Enviar notificaciones al correo",
"optional": "Opcional",
"expires": "Expira",
@@ -165,14 +169,12 @@
"theme": "Tema",
"sponsors": "Patrocinadores",
"sponsors_of_lemmy": "Patrocinadores de Lemmy",
- "sponsor_message":
- "Lemmy es software libre y de <1>código abierto1>, lo que significa que no tendrá publicidades, monetización, ni capitales emprendedores, nunca. Tus donaciones apoyan directamente el desarrollo a tiempo completo del proyecto. Muchas gracias a las siguientes personas:",
+ "sponsor_message": "Lemmy es software libre y de <1>código abierto1>, lo que significa que no tendrá publicidades, monetización, ni capitales emprendedores, nunca. Tus donaciones apoyan directamente el desarrollo a tiempo completo del proyecto. Muchas gracias a las siguientes personas:",
"support_on_patreon": "Apoyo en Patreon",
"support_on_liberapay": "Apoyo en Liberapay",
"donate_to_lemmy": "Donar a Lemmy",
"donate": "Donar",
- "general_sponsors":
- "Los Patrocinadores Generales son aquellos que señaron entre $10 y $39 a Lemmy.",
+ "general_sponsors": "Los Patrocinadores Generales son aquellos que señaron entre $10 y $39 a Lemmy.",
"crypto": "Crypto",
"bitcoin": "Bitcoin",
"ethereum": "Ethereum",
@@ -188,8 +190,7 @@
"yes": "sí",
"no": "no",
"powered_by": "Impulsado por",
- "landing_0":
- "Lemmy es un <1>agregador de links1> / alternativa a reddit, con la intención de funcionar en el <2>fediverso2>.<3>3>Es alojable por uno mismo (sin necesidad de grandes compañías), tiene actualización en vivo de cadenas de comentarios, y es pequeño (<4>~80kB4>). Federar con el sistema de redes ActivityPub forma parte de los objetivos del proyecto. <5>5>Esta es una <6>version beta muy prematura6>, y actualmente muchas de las características están rotas o faltan. <7>7>Sugiere nuevas características o reporta errores <8>aquí8>.<9>9>Hecho con <10>Rust10>, <11>Actix11>, <12>Inferno12>, <13>Typescript13>.",
+ "landing_0": "Lemmy es un <1>agregador de links1> / alternativa a reddit, con la intención de funcionar en el <2>fediverso2>.<3>3>Es alojable por uno mismo (sin necesidad de grandes compañías), tiene actualización en vivo de cadenas de comentarios, y es pequeño (<4>~80kB4>). Federar con el sistema de redes ActivityPub forma parte de los objetivos del proyecto. <5>5>Esta es una <6>version beta muy prematura6>, y actualmente muchas de las características están rotas o faltan. <7>7>Sugiere nuevas características o reporta errores <8>aquí8>.<9>9>Hecho con <10>Rust10>, <11>Actix11>, <12>Inferno12>, <13>Typescript13>.",
"not_logged_in": "No has iniciado sesión.",
"logged_in": "Has iniciado sesión.",
"community_ban": "Has sido expulsado de esta comunidad.",
@@ -204,12 +205,9 @@
"couldnt_find_community": "No se pudo encontrar la comunidad.",
"couldnt_update_community": "No se pudo actualizar la comunidad.",
"community_already_exists": "Esta comunidad ya existe.",
- "community_moderator_already_exists":
- "Este moderador de la comunidad ya existe.",
- "community_follower_already_exists":
- "Este seguidor de la comunidad ya existe.",
- "community_user_already_banned":
- "Este usuario de la comunidad ya fue expulsado.",
+ "community_moderator_already_exists": "Este moderador de la comunidad ya existe.",
+ "community_follower_already_exists": "Este seguidor de la comunidad ya existe.",
+ "community_user_already_banned": "Este usuario de la comunidad ya fue expulsado.",
"couldnt_create_post": "No se pudo crear la publicación.",
"couldnt_like_post": "No se pudo gustar la publicación.",
"couldnt_find_post": "No se pudo encontrar la publicación.",
@@ -220,21 +218,31 @@
"not_an_admin": "No es un administrador.",
"site_already_exists": "El sitio ya existe.",
"couldnt_update_site": "No se pudo actualizar el sitio.",
- "couldnt_find_that_username_or_email":
- "No se pudo encontrar ese nombre de usuario o correo electrónico.",
+ "couldnt_find_that_username_or_email": "No se pudo encontrar ese nombre de usuario o correo electrónico.",
"password_incorrect": "Contraseña incorrecta.",
"passwords_dont_match": "Las contraseñas no coinciden.",
"admin_already_created": "Lo sentimos, ya hay un adminisitrador.",
"user_already_exists": "El usuario ya existe.",
"email_already_exists": "El correo ya está en uso.",
"couldnt_update_user": "No se pudo actualizar el usuario.",
- "system_err_login":
- "Error del sistema. Intente cerrar sesión e ingresar de nuevo.",
+ "system_err_login": "Error del sistema. Intente cerrar sesión e ingresar de nuevo.",
"couldnt_create_private_message": "No se pudo crear el mensaje privado.",
- "no_private_message_edit_allowed":
- "Sin permisos para editar el mensaje privado.",
+ "no_private_message_edit_allowed": "Sin permisos para editar el mensaje privado.",
"couldnt_update_private_message": "No se pudo actualizar el mensaje privado.",
"old": "Antiguo",
"time": "Tiempo",
- "action": "Acción"
+ "action": "Acción",
+ "more": "más",
+ "cross_posted_to": "publicado también en:",
+ "sorting_help": "ayuda del orden",
+ "upvote": "Voto Positivo",
+ "number_of_upvotes": "{{count}} Voto Positivo",
+ "number_of_upvotes_plural": "{{count}} Votos Positivos",
+ "downvote": "Voto Negativo",
+ "number_of_downvotes": "{{count}} Voto Negativo",
+ "number_of_downvotes_plural": "{{count}} Votos Negativos",
+ "couldnt_get_comments": "No se pudo obtener los comentarios.",
+ "post_title_too_long": "El título de la publicación es muy largo.",
+ "block_leaving": "¿Está seguro de que desea salir?",
+ "show_context": "Mostrar contexto"
}
diff --git a/ui/translations/fr.json b/ui/translations/fr.json
index 7f61cbfee..96b8c3d1b 100644
--- a/ui/translations/fr.json
+++ b/ui/translations/fr.json
@@ -227,5 +227,6 @@
"no_private_message_edit_allowed": "Pas autorisé à modifier un message privé.",
"couldnt_update_private_message": "Impossible de modifier un message privé.",
"time": "Temps",
- "action": "Action"
+ "action": "Action",
+ "more": "plus"
}
From bfcae13355ea04fec31a6d205a7572d190bb2066 Mon Sep 17 00:00:00 2001
From: Dessalines
Date: Fri, 3 Apr 2020 13:46:25 -0400
Subject: [PATCH 03/24] Adding a text body preview and icon for posts with a
body. Fixes #617
---
ui/src/components/post-listing.tsx | 20 ++++++++++++++++++++
ui/src/components/symbols.tsx | 3 +++
ui/src/utils.ts | 8 ++++++++
3 files changed, 31 insertions(+)
diff --git a/ui/src/components/post-listing.tsx b/ui/src/components/post-listing.tsx
index ff863dcb0..101d18078 100644
--- a/ui/src/components/post-listing.tsx
+++ b/ui/src/components/post-listing.tsx
@@ -20,6 +20,7 @@ import { MomentTime } from './moment-time';
import { PostForm } from './post-form';
import { IFramelyCard } from './iframely-card';
import {
+ md,
mdToHtml,
canMod,
isMod,
@@ -30,6 +31,7 @@ import {
showAvatars,
pictshareImage,
setupTippy,
+ previewLines,
} from '../utils';
import { i18n } from '../i18next';
@@ -459,6 +461,24 @@ export class PostListing extends Component {
+ {post.body && (
+ <>
+ •
+
+ {/* Using a link with tippy doesn't work on touch devices unfortunately */}
+
+
+
+
+
+
+ >
+ )}
•
{this.state.upvotes !== this.state.score && (
<>
diff --git a/ui/src/components/symbols.tsx b/ui/src/components/symbols.tsx
index 16deec3eb..dae734a80 100644
--- a/ui/src/components/symbols.tsx
+++ b/ui/src/components/symbols.tsx
@@ -15,6 +15,9 @@ export class Symbols extends Component {
xmlnsXlink="http://www.w3.org/1999/xlink"
>
+
+
+
diff --git a/ui/src/utils.ts b/ui/src/utils.ts
index 8ecef19b6..d659509c8 100644
--- a/ui/src/utils.ts
+++ b/ui/src/utils.ts
@@ -823,3 +823,11 @@ function hsl(num: number) {
function randomHsl() {
return `hsla(${Math.random() * 360}, 100%, 50%, 1)`;
}
+
+export function previewLines(text: string, lines: number = 3): string {
+ // Use lines * 2 because markdown requires 2 lines
+ return text
+ .split('\n')
+ .slice(0, lines * 2)
+ .join('\n');
+}
From fb4a7f32895d14034b912ac30d0e2c5aeaf3b78f Mon Sep 17 00:00:00 2001
From: Dessalines
Date: Fri, 3 Apr 2020 14:37:44 -0400
Subject: [PATCH 04/24] Adding docs for DB Backup / Restore. Fixes #619
---
docs/src/SUMMARY.md | 1 +
docs/src/about_goals.md | 1 +
docs/src/administration_backup_and_restore.md | 44 +++++++++++++++++++
3 files changed, 46 insertions(+)
create mode 100644 docs/src/administration_backup_and_restore.md
diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md
index 70c423c79..bff5cbf64 100644
--- a/docs/src/SUMMARY.md
+++ b/docs/src/SUMMARY.md
@@ -10,6 +10,7 @@
- [Install with Ansible](administration_install_ansible.md)
- [Install with Kubernetes](administration_install_kubernetes.md)
- [Configuration](administration_configuration.md)
+ - [Backup and Restore](administration_backup_and_restore.md)
- [Contributing](contributing.md)
- [Docker Development](contributing_docker_development.md)
- [Local Development](contributing_local_development.md)
diff --git a/docs/src/about_goals.md b/docs/src/about_goals.md
index caa6948a0..e0427481c 100644
--- a/docs/src/about_goals.md
+++ b/docs/src/about_goals.md
@@ -51,3 +51,4 @@
- [Activitypub implementers guide](https://socialhub.activitypub.rocks/t/draft-guide-for-new-activitypub-implementers/479)
- [Data storage questions](https://socialhub.activitypub.rocks/t/data-storage-questions/579/3)
- [Activitypub as it has been understood](https://flak.tedunangst.com/post/ActivityPub-as-it-has-been-understood)
+- [Asonix http signatures in rust](https://git.asonix.dog/Aardwolf/http-signature-normalization)
diff --git a/docs/src/administration_backup_and_restore.md b/docs/src/administration_backup_and_restore.md
new file mode 100644
index 000000000..fe97cf880
--- /dev/null
+++ b/docs/src/administration_backup_and_restore.md
@@ -0,0 +1,44 @@
+# Backup and Restore Guide
+
+## Docker and Ansible
+
+When using docker or ansible, there should be a `volumes` folder, which contains both the database, and all the pictures. Copy this folder to the new instance to restore your data.
+
+### Incremental Database backup
+
+To incrementally backup the DB to an `.sql` file, you can run:
+
+```bash
+docker exec -t FOLDERNAME_postgres_1 pg_dumpall -c -U lemmy > lemmy_dump_`date +%Y-%m-%d"_"%H_%M_%S`.sql
+```
+### A Sample backup script
+
+```bash
+#!/bin/sh
+# DB Backup
+ssh MY_USER@MY_IP "docker exec -t FOLDERNAME_postgres_1 pg_dumpall -c -U lemmy" > ~/BACKUP_LOCATION/INSTANCE_NAME_dump_`date +%Y-%m-%d"_"%H_%M_%S`.sql
+
+# Volumes folder Backup
+rsync -avP -zz --rsync-path="sudo rsync" MY_USER@MY_IP:/LEMMY_LOCATION/volumes ~/BACKUP_LOCATION/FOLDERNAME
+```
+
+### Restoring the DB
+
+If you need to restore from a `pg_dumpall` file, you need to first clear out your existing database
+
+```bash
+# Drop the existing DB
+docker exec -i FOLDERNAME_postgres_1 psql -U lemmy -c "DROP SCHEMA public CASCADE; CREATE SCHEMA public;"
+
+# Restore from the .sql backup
+cat db_dump.sql | docker exec -i FOLDERNAME_postgres_1 psql -U lemmy # restores the db
+
+# This also might be necessary when doing a db import with a different password.
+docker exec -i FOLDERNAME_postgres_1 psql -U lemmy -c "alter user lemmy with password 'bleh'"
+```
+
+## More resources
+
+- https://stackoverflow.com/questions/24718706/backup-restore-a-dockerized-postgresql-database
+
+
From 542ea23cbb7996303ea0dbad0c7966be073e722d Mon Sep 17 00:00:00 2001
From: Dessalines
Date: Fri, 3 Apr 2020 14:44:10 -0400
Subject: [PATCH 05/24] Fixing deploy script.
---
docker/dev/deploy.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/docker/dev/deploy.sh b/docker/dev/deploy.sh
index db2294fab..09b21b0b7 100755
--- a/docker/dev/deploy.sh
+++ b/docker/dev/deploy.sh
@@ -72,5 +72,5 @@ git push origin $new_tag
git push
# Pushing to any ansible deploys
-cd ../../ansible || exit
-ansible-playbook lemmy.yml --become
+cd ../../../lemmy-ansible || exit
+ansible-playbook -i prod playbooks/site.yml --vault-password-file vault_pass
From 37036e68b50ea20a1fcfc6f6daf9a99c33e60715 Mon Sep 17 00:00:00 2001
From: Dessalines
Date: Fri, 3 Apr 2020 14:44:30 -0400
Subject: [PATCH 06/24] Version v0.6.45
---
ansible/VERSION | 2 +-
docker/prod/docker-compose.yml | 2 +-
server/src/version.rs | 2 +-
ui/src/version.ts | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/ansible/VERSION b/ansible/VERSION
index 83ca525b7..48861fee4 100644
--- a/ansible/VERSION
+++ b/ansible/VERSION
@@ -1 +1 @@
-v0.6.44
+v0.6.45
diff --git a/docker/prod/docker-compose.yml b/docker/prod/docker-compose.yml
index 76f5ae14d..325effa65 100644
--- a/docker/prod/docker-compose.yml
+++ b/docker/prod/docker-compose.yml
@@ -12,7 +12,7 @@ services:
restart: always
lemmy:
- image: dessalines/lemmy:v0.6.44
+ image: dessalines/lemmy:v0.6.45
ports:
- "127.0.0.1:8536:8536"
restart: always
diff --git a/server/src/version.rs b/server/src/version.rs
index 1491a0a2c..c2717a78e 100644
--- a/server/src/version.rs
+++ b/server/src/version.rs
@@ -1 +1 @@
-pub const VERSION: &str = "v0.6.44";
+pub const VERSION: &str = "v0.6.45";
diff --git a/ui/src/version.ts b/ui/src/version.ts
index fdf2c3470..f0847f757 100644
--- a/ui/src/version.ts
+++ b/ui/src/version.ts
@@ -1 +1 @@
-export const version: string = 'v0.6.44';
+export const version: string = 'v0.6.45';
From aa2cabecde44f8b1e06451eae3fa09bfb57eff54 Mon Sep 17 00:00:00 2001
From: Dessalines
Date: Sun, 5 Apr 2020 10:11:16 -0400
Subject: [PATCH 07/24] Try to fix post creation bug.
---
ui/src/components/post.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ui/src/components/post.tsx b/ui/src/components/post.tsx
index f51ba6ff9..de0f0e329 100644
--- a/ui/src/components/post.tsx
+++ b/ui/src/components/post.tsx
@@ -460,7 +460,7 @@ export class Post extends Component {
} else if (res.op == UserOperation.Search) {
let data = res.data as SearchResponse;
this.state.crossPosts = data.posts.filter(
- p => p.id != this.state.post.id
+ p => p.id != Number(this.props.match.params.id)
);
this.setState(this.state);
} else if (res.op == UserOperation.TransferSite) {
From 9424d1d08e37ae5daa2f10fa547e101ceefc6679 Mon Sep 17 00:00:00 2001
From: Dessalines
Date: Thu, 9 Apr 2020 16:11:11 -0400
Subject: [PATCH 08/24] Updating code url references to
https://github.com/LemmyNet/lemmy
---
CODE_OF_CONDUCT.md | 2 +-
README.md | 20 ++++++++++----------
RELEASES.md | 4 ++--
docs/src/about.md | 2 +-
docs/src/administration_install_ansible.md | 4 ++--
docs/src/contributing.md | 5 +++--
docs/src/contributing_docker_development.md | 2 +-
docs/src/contributing_local_development.md | 2 +-
ui/src/components/sponsors.tsx | 3 ++-
ui/src/utils.ts | 2 +-
10 files changed, 24 insertions(+), 22 deletions(-)
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
index 5a6c7d672..e0270d4c7 100644
--- a/CODE_OF_CONDUCT.md
+++ b/CODE_OF_CONDUCT.md
@@ -30,6 +30,6 @@ In the Lemmy community we strive to go the extra step to look out for each other
And if someone takes issue with something you said or did, resist the urge to be defensive. Just stop doing what it was they complained about and apologize. Even if you feel you were misinterpreted or unfairly accused, chances are good there was something you could’ve communicated better — remember that it’s your responsibility to make others comfortable. Everyone wants to get along and we are all here first and foremost because we want to talk about cool technology. You will find that people will be eager to assume good intent and forgive as long as you earn their trust.
-The enforcement policies listed above apply to all official Lemmy venues; including git repositories under [github.com/dessalines/lemmy](https://github.com/dessalines/lemmy) and [yerbamate.dev/dessalines/lemmy](https://yerbamate.dev/dessalines/lemmy), the [Matrix channel](https://matrix.to/#/!BZVTUuEiNmRcbFeLeI:matrix.org?via=matrix.org&via=privacytools.io&via=permaweb.io); and all instances under lemmy.ml. For other projects adopting the Rust Code of Conduct, please contact the maintainers of those projects for enforcement. If you wish to use this code of conduct for your own project, consider explicitly mentioning your moderation policy or making a copy with your own moderation policy so as to avoid confusion.
+The enforcement policies listed above apply to all official Lemmy venues; including git repositories under [github.com/LemmyNet/lemmy](https://github.com/LemmyNet/lemmy) and [yerbamate.dev/dessalines/lemmy](https://yerbamate.dev/dessalines/lemmy), the [Matrix channel](https://matrix.to/#/!BZVTUuEiNmRcbFeLeI:matrix.org?via=matrix.org&via=privacytools.io&via=permaweb.io); and all instances under lemmy.ml. For other projects adopting the Rust Code of Conduct, please contact the maintainers of those projects for enforcement. If you wish to use this code of conduct for your own project, consider explicitly mentioning your moderation policy or making a copy with your own moderation policy so as to avoid confusion.
Adapted from the [Rust Code of Conduct](https://www.rust-lang.org/policies/code-of-conduct), which is based on the [Node.js Policy on Trolling](http://blog.izs.me/post/30036893703/policy-on-trolling) as well as the [Contributor Covenant v1.3.0](https://www.contributor-covenant.org/version/1/3/0/).
diff --git a/README.md b/README.md
index 2adad59c7..d576e5be7 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,12 @@
-![GitHub tag (latest SemVer)](https://img.shields.io/github/tag/dessalines/lemmy.svg)
-[![Build Status](https://travis-ci.org/dessalines/lemmy.svg?branch=master)](https://travis-ci.org/dessalines/lemmy)
-[![GitHub issues](https://img.shields.io/github/issues-raw/dessalines/lemmy.svg)](https://github.com/dessalines/lemmy/issues)
+![GitHub tag (latest SemVer)](https://img.shields.io/github/tag/LemmyNet/lemmy.svg)
+[![Build Status](https://travis-ci.org/LemmyNet/lemmy.svg?branch=master)](https://travis-ci.org/LemmyNet/lemmy)
+[![GitHub issues](https://img.shields.io/github/issues-raw/LemmyNet/lemmy.svg)](https://github.com/LemmyNet/lemmy/issues)
[![Docker Pulls](https://img.shields.io/docker/pulls/dessalines/lemmy.svg)](https://cloud.docker.com/repository/docker/dessalines/lemmy/)
[![Translation status](http://weblate.yerbamate.dev/widgets/lemmy/-/lemmy/svg-badge.svg)](http://weblate.yerbamate.dev/engage/lemmy/)
-[![License](https://img.shields.io/github/license/dessalines/lemmy.svg)](LICENSE)
-![GitHub stars](https://img.shields.io/github/stars/dessalines/lemmy?style=social)
+[![License](https://img.shields.io/github/license/LemmyNet/lemmy.svg)](LICENSE)
+![GitHub stars](https://img.shields.io/github/stars/LemmyNet/lemmy?style=social)
@@ -22,11 +22,11 @@
·
Documentation
·
- Report Bug
+ Report Bug
·
- Request Feature
+ Request Feature
·
- Releases
+ Releases
@@ -36,7 +36,7 @@ Front Page|Post
---|---
![main screen](https://i.imgur.com/kZSRcRu.png)|![chat screen](https://i.imgur.com/4XghNh6.png)
-[Lemmy](https://github.com/dessalines/lemmy) is similar to sites like [Reddit](https://reddit.com), [Lobste.rs](https://lobste.rs), [Raddle](https://raddle.me), or [Hacker News](https://news.ycombinator.com/): you subscribe to forums you're interested in, post links and discussions, then vote, and comment on them. Behind the scenes, it is very different; anyone can easily run a server, and all these servers are federated (think email), and connected to the same universe, called the [Fediverse](https://en.wikipedia.org/wiki/Fediverse).
+[Lemmy](https://github.com/LemmyNet/lemmy) is similar to sites like [Reddit](https://reddit.com), [Lobste.rs](https://lobste.rs), [Raddle](https://raddle.me), or [Hacker News](https://news.ycombinator.com/): you subscribe to forums you're interested in, post links and discussions, then vote, and comment on them. Behind the scenes, it is very different; anyone can easily run a server, and all these servers are federated (think email), and connected to the same universe, called the [Fediverse](https://en.wikipedia.org/wiki/Fediverse).
For a link aggregator, this means a user registered on one server can subscribe to forums on any other server, and can have discussions with users registered elsewhere.
@@ -132,7 +132,7 @@ If you want to help with translating, take a look at [Weblate](https://weblate.y
- [Mastodon](https://mastodon.social/@LemmyDev) - [![Mastodon Follow](https://img.shields.io/mastodon/follow/810572?domain=https%3A%2F%2Fmastodon.social&style=social)](https://mastodon.social/@LemmyDev)
- [Matrix](https://riot.im/app/#/room/#rust-reddit-fediverse:matrix.org) - [![Matrix](https://img.shields.io/matrix/rust-reddit-fediverse:matrix.org.svg?label=matrix-chat)](https://riot.im/app/#/room/#rust-reddit-fediverse:matrix.org)
-- [GitHub](https://github.com/dessalines/lemmy)
+- [GitHub](https://github.com/LemmyNet/lemmy)
- [Gitea](https://yerbamate.dev/dessalines/lemmy)
- [GitLab](https://gitlab.com/dessalines/lemmy)
diff --git a/RELEASES.md b/RELEASES.md
index 4d86f6dab..5a4c7645e 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,6 +1,6 @@
# Lemmy v0.6.0 Release (2020-01-16)
-`v0.6.0` is here, and we've closed [41 issues!](https://github.com/dessalines/lemmy/milestone/15?closed=1)
+`v0.6.0` is here, and we've closed [41 issues!](https://github.com/LemmyNet/lemmy/milestone/15?closed=1)
This is the biggest release by far:
@@ -10,7 +10,7 @@ This is the biggest release by far:
- Can set a custom language.
- Lemmy-wide settings to disable downvotes, and close registration.
- A better documentation system, hosted in lemmy itself.
-- [Huge DB performance gains](https://github.com/dessalines/lemmy/issues/411) (everthing down to < `30ms`) by using materialized views.
+- [Huge DB performance gains](https://github.com/LemmyNet/lemmy/issues/411) (everthing down to < `30ms`) by using materialized views.
- Fixed major issue with similar post URL and title searching.
- Upgraded to Actix `2.0`
- Faster comment / post voting.
diff --git a/docs/src/about.md b/docs/src/about.md
index 33ecb211a..31081f485 100644
--- a/docs/src/about.md
+++ b/docs/src/about.md
@@ -4,7 +4,7 @@ Front Page|Post
---|---
![main screen](https://i.imgur.com/kZSRcRu.png)|![chat screen](https://i.imgur.com/4XghNh6.png)
-[Lemmy](https://github.com/dessalines/lemmy) is similar to sites like [Reddit](https://reddit.com), [Lobste.rs](https://lobste.rs), [Raddle](https://raddle.me), or [Hacker News](https://news.ycombinator.com/): you subscribe to forums you're interested in, post links and discussions, then vote, and comment on them. Behind the scenes, it is very different; anyone can easily run a server, and all these servers are federated (think email), and connected to the same universe, called the [Fediverse](https://en.wikipedia.org/wiki/Fediverse).
+[Lemmy](https://github.com/LemmyNet/lemmy) is similar to sites like [Reddit](https://reddit.com), [Lobste.rs](https://lobste.rs), [Raddle](https://raddle.me), or [Hacker News](https://news.ycombinator.com/): you subscribe to forums you're interested in, post links and discussions, then vote, and comment on them. Behind the scenes, it is very different; anyone can easily run a server, and all these servers are federated (think email), and connected to the same universe, called the [Fediverse](https://en.wikipedia.org/wiki/Fediverse).
For a link aggregator, this means a user registered on one server can subscribe to forums on any other server, and can have discussions with users registered elsewhere.
diff --git a/docs/src/administration_install_ansible.md b/docs/src/administration_install_ansible.md
index bf5e67493..77d901b36 100644
--- a/docs/src/administration_install_ansible.md
+++ b/docs/src/administration_install_ansible.md
@@ -7,7 +7,7 @@ First, you need to [install Ansible on your local computer](https://docs.ansible
Then run the following commands on your local computer:
```bash
-git clone https://github.com/dessalines/lemmy.git
+git clone https://github.com/LemmyNet/lemmy.git
cd lemmy/ansible/
cp inventory.example inventory
nano inventory # enter your server, domain, contact email
@@ -19,4 +19,4 @@ To update to a new version, just run the following in your local Lemmy repo:
git pull origin master
cd ansible
ansible-playbook lemmy.yml --become
-```
\ No newline at end of file
+```
diff --git a/docs/src/contributing.md b/docs/src/contributing.md
index 9a01ad5d9..4eabd6fc7 100644
--- a/docs/src/contributing.md
+++ b/docs/src/contributing.md
@@ -4,13 +4,14 @@ Information about contributing to Lemmy, whether it is translating, testing, des
## Issue tracking / Repositories
-- [GitHub (for issues)](https://github.com/dessalines/lemmy)
+- [GitHub (for issues)](https://github.com/LemmyNet/lemmy)
- [Gitea](https://yerbamate.dev/dessalines/lemmy)
- [GitLab](https://gitlab.com/dessalines/lemmy)
## Translating
-Go [here](https://github.com/dessalines/lemmy#translations) for translation instructions.
+Check out [Lemmy's Weblate](https://weblate.yerbamate.dev/projects/lemmy/) for translations.
+
## Architecture
diff --git a/docs/src/contributing_docker_development.md b/docs/src/contributing_docker_development.md
index d5ab58293..092398219 100644
--- a/docs/src/contributing_docker_development.md
+++ b/docs/src/contributing_docker_development.md
@@ -3,7 +3,7 @@
## Running
```bash
-git clone https://github.com/dessalines/lemmy
+git clone https://github.com/LemmyNet/lemmy
cd lemmy/docker/dev
./docker_update.sh # This builds and runs it, updating for your changes
```
diff --git a/docs/src/contributing_local_development.md b/docs/src/contributing_local_development.md
index 175b000c7..e823c9d1b 100644
--- a/docs/src/contributing_local_development.md
+++ b/docs/src/contributing_local_development.md
@@ -22,7 +22,7 @@ export LEMMY_DATABASE_URL=postgres://lemmy:password@localhost:5432/lemmy
#### Running
```bash
-git clone https://github.com/dessalines/lemmy
+git clone https://github.com/LemmyNet/lemmy
cd lemmy
./install.sh
# For live coding, where both the front and back end, automagically reload on any save, do:
diff --git a/ui/src/components/sponsors.tsx b/ui/src/components/sponsors.tsx
index 347cb718c..643153e68 100644
--- a/ui/src/components/sponsors.tsx
+++ b/ui/src/components/sponsors.tsx
@@ -2,6 +2,7 @@ import { Component } from 'inferno';
import { WebSocketService } from '../services';
import { i18n } from '../i18next';
import { T } from 'inferno-i18next';
+import { repoUrl } from '../utils';
let general = [
'Nathan J. Goode',
@@ -44,7 +45,7 @@ export class Sponsors extends Component {
{i18n.t('donate_to_lemmy')}
- ##
+ ##
diff --git a/ui/src/utils.ts b/ui/src/utils.ts
index d659509c8..ceb05764d 100644
--- a/ui/src/utils.ts
+++ b/ui/src/utils.ts
@@ -44,7 +44,7 @@ import emojiShortName from 'emoji-short-name';
import Toastify from 'toastify-js';
import tippy from 'tippy.js';
-export const repoUrl = 'https://github.com/dessalines/lemmy';
+export const repoUrl = 'https://github.com/LemmyNet/lemmy';
export const helpGuideUrl = '/docs/about_guide.html';
export const markdownHelpUrl = `${helpGuideUrl}#markdown-guide`;
export const sortingHelpUrl = `${helpGuideUrl}#sorting`;
From dec757eb9e95b356431d51a49335a447fbaf4e58 Mon Sep 17 00:00:00 2001
From: Nika Tskhakaia
Date: Fri, 10 Apr 2020 14:40:20 +0000
Subject: [PATCH 09/24] Translated using Weblate (Georgian)
Currently translated at 67.5% (160 of 237 strings)
Translation: Lemmy/lemmy
Translate-URL: http://weblate.yerbamate.dev/projects/lemmy/lemmy/ka/
Translated using Weblate (Georgian)
Currently translated at 62.8% (149 of 237 strings)
Translation: Lemmy/lemmy
Translate-URL: http://weblate.yerbamate.dev/projects/lemmy/lemmy/ka/
---
ui/translations/ka.json | 97 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 96 insertions(+), 1 deletion(-)
diff --git a/ui/translations/ka.json b/ui/translations/ka.json
index 01dbe4ed4..21db25ef2 100644
--- a/ui/translations/ka.json
+++ b/ui/translations/ka.json
@@ -71,5 +71,100 @@
"unsticky": "unsticky",
"remove_as_mod": "მოხსენი როგორც მოდერატორი",
"remove_as_admin": "მოხსენი როგორც ადმინი",
- "delete_account_confirm": "გაფთხილება: ეს შენს ყველაფერს წაშლის. პაროლი ჩაწერეთ რომ დაადასტუროთ."
+ "delete_account_confirm": "გაფთხილება: ეს შენს ყველაფერს წაშლის. პაროლი ჩაწერეთ რომ დაადასტუროთ.",
+ "creator": "შემქნელი",
+ "username": "მომხმარებლის სახელი",
+ "email_or_username": "ელ-პოსტა ან მომხმარებლის სახელი",
+ "number_of_users": "მომხმარებელი",
+ "number_of_users_plural": "მომხმარებლები",
+ "number_of_subscribers": "გამომწერი",
+ "number_of_subscribers_plural": "გამომწერები",
+ "number_of_points": "ქულა",
+ "number_of_points_plural": "ქულა",
+ "number_online": "მომხმარებელი საიტზე",
+ "number_online_plural": "მომხმარებელი საიტზე",
+ "name": "სახელი",
+ "title": "სათაური",
+ "category": "კატეგორია",
+ "subscribers": "გამომწერი",
+ "both": "ორივე",
+ "saved": "შანახული",
+ "unsubscribe": "გამოწერის გაუქმნება",
+ "subscribe": "გამოწერა",
+ "subscribed": "გამოწერილია",
+ "prev": "წუნა",
+ "next": "შემდეგი",
+ "sidebar": "Sidebar",
+ "sort_type": "სორტირების ტიპი",
+ "inbox": "Inbox",
+ "inbox_for": "<1>{{user}}1>-s Inbox",
+ "mark_all_as_read": "მონიშვნა ყველასი როგორც წაკითხული",
+ "type": "ტიპი",
+ "unread": "წაუკითხავია",
+ "mentions": "ხსენებები",
+ "reply_sent": "პასუხი გაგზავნილია",
+ "message_sent": "მესეჯი",
+ "search": "ძებმა",
+ "overview": "გადახედვა",
+ "view": "ნახვა",
+ "logout": "გასვლა",
+ "login_sign_up": "შესვლა ან რეგისტრაცია",
+ "login": "შესვლა",
+ "sign_up": "რეგისტრაცია",
+ "unread_messages": "წაუკითხავი მესეჯები",
+ "messages": "მესეჯები",
+ "password": "პაროლი",
+ "verify_password": "პაროლის დადასტურება",
+ "old_password": "ძველი პაროლი",
+ "forgot_password": "აღგდენა",
+ "reset_password_mail_sent": "ელ-პოსტა შეამოწმეთ",
+ "password_change": "პაროლის შეცვლა",
+ "new_password": "ახალი პაროლი",
+ "email": "ელ-პოსტა",
+ "matrix_user_id": "მატრიცული მომხმარებელი",
+ "private_message_disclaimer": ".",
+ "send_notifications_to_email": "შეტყობინების გაგზავნა ელ-პოსტაზე",
+ "optional": "არასავალდებულო",
+ "expires": "ვადა გასდის",
+ "language": "ენა",
+ "browser_default": "Browser Default",
+ "enable_downvotes": "არმოწონების ჩართვა",
+ "upvote": "მოწონება",
+ "downvote": "არ მოწონება",
+ "open_registration": "რეგისტრაციის გახსნა",
+ "registration_closed": "რეგისტრაცია დახურულია",
+ "enable_nsfw": "Enable NSFW",
+ "url": "მისამართი",
+ "body": "ტექსტი",
+ "copy_suggested_title": "დაკოპირება რეკომინდებულის სათაური: {{title}}",
+ "community": "თემა",
+ "expand_here": "Expand here",
+ "subscribe_to_communities": "Subscribe to some <1>communities1>.",
+ "chat": "ჩეტი",
+ "recent_comments": "ბოლო კომენტარები",
+ "no_results": "0 შედეგი",
+ "setup": "Setup",
+ "lemmy_instance_setup": "Lemmy Instance Setup",
+ "setup_admin": "Set Up Site Administrator",
+ "your_site": "შენი გვერდი",
+ "modified": "რედაკტირებული",
+ "nsfw": "NSFW",
+ "notifications_error": "გთხოვთ იხმაღეთ Chome ან Firefox შეტყობინებისთვის",
+ "no_email_setup": "This server hasn't correctly set up email.",
+ "downvotes_disabled": "არმოწონები გამორთულია",
+ "number_of_upvotes": "მოწონება",
+ "number_of_upvotes_plural": "მოწონება",
+ "number_of_downvotes": "არ მოწონება",
+ "number_of_downvotes_plural": "არ მოწონება",
+ "hot": "ცხელი",
+ "new": "ახალი",
+ "old": "ძველი",
+ "top_day": "ტოპ დღეს",
+ "week": "კვირა",
+ "month": "თვე",
+ "year": "წელი",
+ "all": "ყველა",
+ "top": "ტოპ",
+ "api": "API",
+ "show_nsfw": "Show NSFW content"
}
From 09538541dd087390f1cb520791a957ee6ebd90f2 Mon Sep 17 00:00:00 2001
From: nick t
Date: Fri, 10 Apr 2020 14:40:20 +0000
Subject: [PATCH 10/24] Translated using Weblate (Georgian)
Currently translated at 84.3% (200 of 237 strings)
Translation: Lemmy/lemmy
Translate-URL: http://weblate.yerbamate.dev/projects/lemmy/lemmy/ka/
---
ui/translations/ka.json | 57 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 56 insertions(+), 1 deletion(-)
diff --git a/ui/translations/ka.json b/ui/translations/ka.json
index 21db25ef2..ebda8982e 100644
--- a/ui/translations/ka.json
+++ b/ui/translations/ka.json
@@ -166,5 +166,60 @@
"all": "ყველა",
"top": "ტოპ",
"api": "API",
- "show_nsfw": "Show NSFW content"
+ "show_nsfw": "Show NSFW content",
+ "related_posts": "ეს პოსტები შეიძლება ერთმანეც ეხება",
+ "cross_post": "გადაკვეთა-პოსტი",
+ "general_sponsors": "General Sponsors are those that pledged $10 to $39 to Lemmy.",
+ "cross_posted_to": "გადაკვეთა-პოსტი გაკეთდა: ",
+ "subscribed_to_communities": "მიყვები <1>communities1>",
+ "trending_communities": "ტრენდული <1>communities1>",
+ "list_of_communities": "ყველა თემა",
+ "number_of_communities": "თემა",
+ "number_of_communities_plural": "თემები",
+ "landing": "Lemmy is a <1>link aggregator1> / reddit alternative, intended to work in the <2>fediverse2>.<3>3>It's self-hostable, has live-updating comment threads, and is tiny (<4>~80kB4>). Federation into the ActivityPub network is on the roadmap. <5>5>This is a <6>very early beta version6>, and a lot of features are currently broken or missing. <7>7>Suggest new features or report bugs <8>here.8><9>9>Made with <10>Rust10>, <11>Actix11>, <12>Inferno12>, <13>Typescript13>.",
+ "docs": "დოკუმენტაცია",
+ "couldnt_like_comment": "კომენტარის მოწონება ვერ მოხერხდა.",
+ "couldnt_update_comment": "კომენტარის განახლება ვერ მოხერხდა.",
+ "replies": "პასუხები",
+ "theme": "საიტის თემა",
+ "sponsors": "სპონსორები",
+ "sponsors_of_lemmy": "Sponsors",
+ "sponsor_message": "Lemmy is free, <1>open-source1> software, meaning no advertising, monetizing, or venture capital, ever. Your donations directly support full-time development of the project. Thank you to the following people:",
+ "support_on_patreon": "Support on Patreon",
+ "support_on_liberapay": "Support on Liberapay",
+ "donate_to_lemmy": "Donate to Lemmy",
+ "no_comment_edit_allowed": "კომენტარის რედაკტირება არ შეიძლება.",
+ "donate": "Donate",
+ "crypto": "Crypto",
+ "bitcoin": "Bitcoin",
+ "ethereum": "Ethereum",
+ "code": "კოდი",
+ "joined": "დაემატა",
+ "by": "by",
+ "to": "to",
+ "from": "from",
+ "transfer_community": "transfer community",
+ "transfer_site": "transfer site",
+ "are_you_sure": "დარწმუნებული ხარ?",
+ "yes": "კი",
+ "no": "არა",
+ "powered_by": "Powered by",
+ "not_logged_in": "შასული არ ხართ",
+ "logged_in": "შაული ხართ.",
+ "community_ban": "შენ ამ თემისგან გაშავებული ხარ.",
+ "site_ban": "საიტიდან გაშავებული ხარ.",
+ "couldnt_create_comment": "კომენტარის შექმნა ვერ მოხერხდა.",
+ "couldnt_find_community": "ტემა არ მოიძებნა.",
+ "couldnt_save_comment": "კომენტარის შენახვა ვერ მოხერხდა.",
+ "couldnt_get_comments": "კომენტარების ნახვა ვერ მოხერხდა.",
+ "no_post_edit_allowed": "პოსტის რედაკტირება არ შეიძლება.",
+ "no_community_edit_allowed": "თემის რედაკტირება არ შეიძლება.",
+ "couldnt_update_community": "თემა ვერ განახლდა.",
+ "community_already_exists": "ეს თემა უკვე არსებობს.",
+ "community_follower_already_exists": "თემის ფოლოვორი უკვე არსებობს.",
+ "community_user_already_banned": "თემის მომხმარებელი უკვე შავ სიაშია.",
+ "couldnt_like_post": "პოსტის მოწონება ვერ მოხერხდა.",
+ "community_moderator_already_exists": "ამ თემის მოდერატორი უკვე არსებობს.",
+ "couldnt_create_post": "პოსტი ვერ შეიქმნა.",
+ "post_title_too_long": "პოსტის სათაური ძალიან გრძელია."
}
From 0a6da1109d1f43f2010697b4597cc7e480d4a795 Mon Sep 17 00:00:00 2001
From: Dessalines
Date: Fri, 10 Apr 2020 16:55:57 -0400
Subject: [PATCH 11/24] Adding an admin settings page.
- Fixes #620
- Adding a UserListing component. Fixes #627
---
docker/dev/docker-compose.yml | 2 +-
docker/prod/docker-compose.yml | 2 +-
docs/src/contributing_websocket_http_api.md | 99 ++++++--
server/src/api/site.rs | 70 ++++++
server/src/routes/api.rs | 2 +
server/src/routes/index.rs | 1 +
server/src/settings.rs | 12 +
server/src/websocket/mod.rs | 2 +
server/src/websocket/server.rs | 10 +
ui/src/components/admin-settings.tsx | 241 ++++++++++++++++++++
ui/src/components/comment-node.tsx | 27 +--
ui/src/components/main.tsx | 24 +-
ui/src/components/navbar.tsx | 26 +++
ui/src/components/post-listing.tsx | 23 +-
ui/src/components/private-message-form.tsx | 25 +-
ui/src/components/private-message.tsx | 1 +
ui/src/components/search.tsx | 23 +-
ui/src/components/sidebar.tsx | 21 +-
ui/src/components/site-form.tsx | 7 +
ui/src/components/symbols.tsx | 3 +
ui/src/components/user-listing.tsx | 36 +++
ui/src/index.tsx | 116 +++++-----
ui/src/interfaces.ts | 22 +-
ui/src/services/WebSocketService.ts | 13 ++
ui/translations/en.json | 4 +
25 files changed, 633 insertions(+), 179 deletions(-)
create mode 100644 ui/src/components/admin-settings.tsx
create mode 100644 ui/src/components/user-listing.tsx
diff --git a/docker/dev/docker-compose.yml b/docker/dev/docker-compose.yml
index a7d289b21..3c52d1e54 100644
--- a/docker/dev/docker-compose.yml
+++ b/docker/dev/docker-compose.yml
@@ -21,7 +21,7 @@ services:
environment:
- RUST_LOG=debug
volumes:
- - ../lemmy.hjson:/config/config.hjson:ro
+ - ../lemmy.hjson:/config/config.hjson
depends_on:
- postgres
- pictshare
diff --git a/docker/prod/docker-compose.yml b/docker/prod/docker-compose.yml
index 325effa65..a1b361622 100644
--- a/docker/prod/docker-compose.yml
+++ b/docker/prod/docker-compose.yml
@@ -19,7 +19,7 @@ services:
environment:
- RUST_LOG=error
volumes:
- - ./lemmy.hjson:/config/config.hjson:ro
+ - ./lemmy.hjson:/config/config.hjson
depends_on:
- postgres
- pictshare
diff --git a/docs/src/contributing_websocket_http_api.md b/docs/src/contributing_websocket_http_api.md
index a73a1c133..f228f94e0 100644
--- a/docs/src/contributing_websocket_http_api.md
+++ b/docs/src/contributing_websocket_http_api.md
@@ -92,85 +92,93 @@
- [Request](#request-17)
- [Response](#response-17)
- [HTTP](#http-18)
- * [Community](#community)
- + [Get Community](#get-community)
+ + [Get Site Config](#get-site-config)
- [Request](#request-18)
- [Response](#response-18)
- [HTTP](#http-19)
- + [Create Community](#create-community)
+ + [Save Site Config](#save-site-config)
- [Request](#request-19)
- [Response](#response-19)
- [HTTP](#http-20)
- + [List Communities](#list-communities)
+ * [Community](#community)
+ + [Get Community](#get-community)
- [Request](#request-20)
- [Response](#response-20)
- [HTTP](#http-21)
- + [Ban from Community](#ban-from-community)
+ + [Create Community](#create-community)
- [Request](#request-21)
- [Response](#response-21)
- [HTTP](#http-22)
- + [Add Mod to Community](#add-mod-to-community)
+ + [List Communities](#list-communities)
- [Request](#request-22)
- [Response](#response-22)
- [HTTP](#http-23)
- + [Edit Community](#edit-community)
+ + [Ban from Community](#ban-from-community)
- [Request](#request-23)
- [Response](#response-23)
- [HTTP](#http-24)
- + [Follow Community](#follow-community)
+ + [Add Mod to Community](#add-mod-to-community)
- [Request](#request-24)
- [Response](#response-24)
- [HTTP](#http-25)
- + [Get Followed Communities](#get-followed-communities)
+ + [Edit Community](#edit-community)
- [Request](#request-25)
- [Response](#response-25)
- [HTTP](#http-26)
- + [Transfer Community](#transfer-community)
+ + [Follow Community](#follow-community)
- [Request](#request-26)
- [Response](#response-26)
- [HTTP](#http-27)
- * [Post](#post)
- + [Create Post](#create-post)
+ + [Get Followed Communities](#get-followed-communities)
- [Request](#request-27)
- [Response](#response-27)
- [HTTP](#http-28)
- + [Get Post](#get-post)
+ + [Transfer Community](#transfer-community)
- [Request](#request-28)
- [Response](#response-28)
- [HTTP](#http-29)
- + [Get Posts](#get-posts)
+ * [Post](#post)
+ + [Create Post](#create-post)
- [Request](#request-29)
- [Response](#response-29)
- [HTTP](#http-30)
- + [Create Post Like](#create-post-like)
+ + [Get Post](#get-post)
- [Request](#request-30)
- [Response](#response-30)
- [HTTP](#http-31)
- + [Edit Post](#edit-post)
+ + [Get Posts](#get-posts)
- [Request](#request-31)
- [Response](#response-31)
- [HTTP](#http-32)
- + [Save Post](#save-post)
+ + [Create Post Like](#create-post-like)
- [Request](#request-32)
- [Response](#response-32)
- [HTTP](#http-33)
- * [Comment](#comment)
- + [Create Comment](#create-comment)
+ + [Edit Post](#edit-post)
- [Request](#request-33)
- [Response](#response-33)
- [HTTP](#http-34)
- + [Edit Comment](#edit-comment)
+ + [Save Post](#save-post)
- [Request](#request-34)
- [Response](#response-34)
- [HTTP](#http-35)
- + [Save Comment](#save-comment)
+ * [Comment](#comment)
+ + [Create Comment](#create-comment)
- [Request](#request-35)
- [Response](#response-35)
- [HTTP](#http-36)
- + [Create Comment Like](#create-comment-like)
+ + [Edit Comment](#edit-comment)
- [Request](#request-36)
- [Response](#response-36)
- [HTTP](#http-37)
+ + [Save Comment](#save-comment)
+ - [Request](#request-37)
+ - [Response](#response-37)
+ - [HTTP](#http-38)
+ + [Create Comment Like](#create-comment-like)
+ - [Request](#request-38)
+ - [Response](#response-38)
+ - [HTTP](#http-39)
* [RSS / Atom feeds](#rss--atom-feeds)
+ [All](#all)
+ [Community](#community-1)
@@ -779,6 +787,53 @@ Search types are `All, Comments, Posts, Communities, Users, Url`
`POST /site/transfer`
+#### Get Site Config
+##### Request
+```rust
+{
+ op: "GetSiteConfig",
+ data: {
+ auth: String
+ }
+}
+```
+##### Response
+```rust
+{
+ op: "GetSiteConfig",
+ data: {
+ config_hjson: String,
+ }
+}
+```
+##### HTTP
+
+`GET /site/config`
+
+#### Save Site Config
+##### Request
+```rust
+{
+ op: "SaveSiteConfig",
+ data: {
+ config_hjson: String,
+ auth: String
+ }
+}
+```
+##### Response
+```rust
+{
+ op: "SaveSiteConfig",
+ data: {
+ config_hjson: String,
+ }
+}
+```
+##### HTTP
+
+`PUT /site/config`
+
### Community
#### Get Community
##### Request
diff --git a/server/src/api/site.rs b/server/src/api/site.rs
index 6bd90149b..3720a2c4c 100644
--- a/server/src/api/site.rs
+++ b/server/src/api/site.rs
@@ -97,6 +97,22 @@ pub struct TransferSite {
auth: String,
}
+#[derive(Serialize, Deserialize)]
+pub struct GetSiteConfig {
+ auth: String,
+}
+
+#[derive(Serialize, Deserialize)]
+pub struct GetSiteConfigResponse {
+ config_hjson: String,
+}
+
+#[derive(Serialize, Deserialize)]
+pub struct SaveSiteConfig {
+ config_hjson: String,
+ auth: String,
+}
+
impl Perform for Oper {
fn perform(&self, conn: &PgConnection) -> Result {
let _data: &ListCategories = &self.data;
@@ -510,3 +526,57 @@ impl Perform for Oper {
})
}
}
+
+impl Perform for Oper {
+ fn perform(&self, conn: &PgConnection) -> Result {
+ let data: &GetSiteConfig = &self.data;
+
+ let claims = match Claims::decode(&data.auth) {
+ Ok(claims) => claims.claims,
+ Err(_e) => return Err(APIError::err("not_logged_in").into()),
+ };
+
+ let user_id = claims.id;
+
+ // Only let admins read this
+ let admins = UserView::admins(&conn)?;
+ let admin_ids: Vec = admins.into_iter().map(|m| m.id).collect();
+
+ if !admin_ids.contains(&user_id) {
+ return Err(APIError::err("not_an_admin").into());
+ }
+
+ let config_hjson = Settings::read_config_file()?;
+
+ Ok(GetSiteConfigResponse { config_hjson })
+ }
+}
+
+impl Perform for Oper {
+ fn perform(&self, conn: &PgConnection) -> Result {
+ let data: &SaveSiteConfig = &self.data;
+
+ let claims = match Claims::decode(&data.auth) {
+ Ok(claims) => claims.claims,
+ Err(_e) => return Err(APIError::err("not_logged_in").into()),
+ };
+
+ let user_id = claims.id;
+
+ // Only let admins read this
+ let admins = UserView::admins(&conn)?;
+ let admin_ids: Vec = admins.into_iter().map(|m| m.id).collect();
+
+ if !admin_ids.contains(&user_id) {
+ return Err(APIError::err("not_an_admin").into());
+ }
+
+ // Make sure docker doesn't have :ro at the end of the volume, so its not a read-only filesystem
+ let config_hjson = match Settings::save_config_file(&data.config_hjson) {
+ Ok(config_hjson) => config_hjson,
+ Err(_e) => return Err(APIError::err("couldnt_update_site").into()),
+ };
+
+ Ok(GetSiteConfigResponse { config_hjson })
+ }
+}
diff --git a/server/src/routes/api.rs b/server/src/routes/api.rs
index 29a360e4e..36a55f960 100644
--- a/server/src/routes/api.rs
+++ b/server/src/routes/api.rs
@@ -52,6 +52,8 @@ pub fn config(cfg: &mut web::ServiceConfig) {
.route("/api/v1/site", web::post().to(route_post::))
.route("/api/v1/site", web::put().to(route_post::))
.route("/api/v1/site/transfer", web::post().to(route_post::))
+ .route("/api/v1/site/config", web::get().to(route_get::))
+ .route("/api/v1/site/config", web::put().to(route_post::))
.route("/api/v1/admin/add", web::post().to(route_post::))
.route("/api/v1/user/ban", web::post().to(route_post::))
// User account actions
diff --git a/server/src/routes/index.rs b/server/src/routes/index.rs
index c1c363c98..45ce204e8 100644
--- a/server/src/routes/index.rs
+++ b/server/src/routes/index.rs
@@ -33,6 +33,7 @@ pub fn config(cfg: &mut web::ServiceConfig) {
.route("/modlog/community/{community_id}", web::get().to(index))
.route("/modlog", web::get().to(index))
.route("/setup", web::get().to(index))
+ .route("/admin", web::get().to(index))
.route(
"/search/q/{q}/type/{type}/sort/{sort}/page/{page}",
web::get().to(index),
diff --git a/server/src/settings.rs b/server/src/settings.rs
index 875323e96..216c057e4 100644
--- a/server/src/settings.rs
+++ b/server/src/settings.rs
@@ -1,6 +1,8 @@
use config::{Config, ConfigError, Environment, File};
+use failure::Error;
use serde::Deserialize;
use std::env;
+use std::fs;
use std::net::IpAddr;
static CONFIG_FILE_DEFAULTS: &str = "config/defaults.hjson";
@@ -112,4 +114,14 @@ impl Settings {
pub fn api_endpoint(&self) -> String {
format!("{}/api/v1", self.hostname)
}
+
+ pub fn read_config_file() -> Result {
+ Ok(fs::read_to_string(CONFIG_FILE)?)
+ }
+
+ pub fn save_config_file(data: &str) -> Result {
+ fs::write(CONFIG_FILE, data)?;
+ Self::init()?;
+ Self::read_config_file()
+ }
}
diff --git a/server/src/websocket/mod.rs b/server/src/websocket/mod.rs
index a1feede25..c7136423c 100644
--- a/server/src/websocket/mod.rs
+++ b/server/src/websocket/mod.rs
@@ -46,4 +46,6 @@ pub enum UserOperation {
GetPrivateMessages,
UserJoin,
GetComments,
+ GetSiteConfig,
+ SaveSiteConfig,
}
diff --git a/server/src/websocket/server.rs b/server/src/websocket/server.rs
index 831f12ee1..0f2d2d26f 100644
--- a/server/src/websocket/server.rs
+++ b/server/src/websocket/server.rs
@@ -708,6 +708,16 @@ fn parse_json_message(chat: &mut ChatServer, msg: StandardMessage) -> Result {
+ let get_site_config: GetSiteConfig = serde_json::from_str(data)?;
+ let res = Oper::new(get_site_config).perform(&conn)?;
+ to_json_string(&user_operation, &res)
+ }
+ UserOperation::SaveSiteConfig => {
+ let save_site_config: SaveSiteConfig = serde_json::from_str(data)?;
+ let res = Oper::new(save_site_config).perform(&conn)?;
+ to_json_string(&user_operation, &res)
+ }
UserOperation::Search => {
do_user_operation::(user_operation, data, &conn)
}
diff --git a/ui/src/components/admin-settings.tsx b/ui/src/components/admin-settings.tsx
new file mode 100644
index 000000000..56af71149
--- /dev/null
+++ b/ui/src/components/admin-settings.tsx
@@ -0,0 +1,241 @@
+import { Component, linkEvent } from 'inferno';
+import { Subscription } from 'rxjs';
+import { retryWhen, delay, take } from 'rxjs/operators';
+import {
+ UserOperation,
+ SiteResponse,
+ GetSiteResponse,
+ SiteConfigForm,
+ GetSiteConfigResponse,
+ WebSocketJsonResponse,
+} from '../interfaces';
+import { WebSocketService } from '../services';
+import { wsJsonToRes, capitalizeFirstLetter, toast, randomStr } from '../utils';
+import autosize from 'autosize';
+import { SiteForm } from './site-form';
+import { UserListing } from './user-listing';
+import { i18n } from '../i18next';
+
+interface AdminSettingsState {
+ siteRes: GetSiteResponse;
+ siteConfigRes: GetSiteConfigResponse;
+ siteConfigForm: SiteConfigForm;
+ loading: boolean;
+ siteConfigLoading: boolean;
+}
+
+export class AdminSettings extends Component {
+ private siteConfigTextAreaId = `site-config-${randomStr()}`;
+ private subscription: Subscription;
+ private emptyState: AdminSettingsState = {
+ siteRes: {
+ site: {
+ id: null,
+ name: null,
+ creator_id: null,
+ creator_name: null,
+ published: null,
+ number_of_users: null,
+ number_of_posts: null,
+ number_of_comments: null,
+ number_of_communities: null,
+ enable_downvotes: null,
+ open_registration: null,
+ enable_nsfw: null,
+ },
+ admins: [],
+ banned: [],
+ online: null,
+ },
+ siteConfigForm: {
+ config_hjson: null,
+ auth: null,
+ },
+ siteConfigRes: {
+ config_hjson: null,
+ },
+ loading: true,
+ siteConfigLoading: null,
+ };
+
+ constructor(props: any, context: any) {
+ super(props, context);
+
+ this.state = this.emptyState;
+
+ this.subscription = WebSocketService.Instance.subject
+ .pipe(retryWhen(errors => errors.pipe(delay(3000), take(10))))
+ .subscribe(
+ msg => this.parseMessage(msg),
+ err => console.error(err),
+ () => console.log('complete')
+ );
+
+ WebSocketService.Instance.getSite();
+ WebSocketService.Instance.getSiteConfig();
+ }
+
+ componentWillUnmount() {
+ this.subscription.unsubscribe();
+ }
+
+ render() {
+ return (
+
+ {this.state.loading ? (
+
+
+
+
+
+ ) : (
+
+
+
+ {this.admins()}
+ {this.bannedUsers()}
+
+
{this.adminSettings()}
+
+ )}
+
+ );
+ }
+
+ admins() {
+ return (
+ <>
+ {capitalizeFirstLetter(i18n.t('admins'))}
+
+ {this.state.siteRes.admins.map(admin => (
+
+
+
+ ))}
+
+ >
+ );
+ }
+
+ bannedUsers() {
+ return (
+ <>
+ {i18n.t('banned_users')}
+
+ {this.state.siteRes.banned.map(banned => (
+
+
+
+ ))}
+
+ >
+ );
+ }
+
+ adminSettings() {
+ return (
+
+
{i18n.t('admin_settings')}
+
+
+ );
+ }
+
+ handleSiteConfigSubmit(i: AdminSettings, event: any) {
+ event.preventDefault();
+ i.state.siteConfigLoading = true;
+ WebSocketService.Instance.saveSiteConfig(i.state.siteConfigForm);
+ i.setState(i.state);
+ }
+
+ handleSiteConfigHjsonChange(i: AdminSettings, event: any) {
+ i.state.siteConfigForm.config_hjson = event.target.value;
+ i.setState(i.state);
+ }
+
+ parseMessage(msg: WebSocketJsonResponse) {
+ console.log(msg);
+ let res = wsJsonToRes(msg);
+ if (msg.error) {
+ toast(i18n.t(msg.error), 'danger');
+ this.context.router.history.push('/');
+ this.state.loading = false;
+ this.setState(this.state);
+ return;
+ } else if (msg.reconnect) {
+ } else if (res.op == UserOperation.GetSite) {
+ let data = res.data as GetSiteResponse;
+
+ // This means it hasn't been set up yet
+ if (!data.site) {
+ this.context.router.history.push('/setup');
+ }
+ this.state.siteRes = data;
+ this.setState(this.state);
+ document.title = `${i18n.t('admin_settings')} - ${
+ this.state.siteRes.site.name
+ }`;
+ } else if (res.op == UserOperation.EditSite) {
+ let data = res.data as SiteResponse;
+ this.state.siteRes.site = data.site;
+ this.setState(this.state);
+ toast(i18n.t('site_saved'));
+ } else if (res.op == UserOperation.GetSiteConfig) {
+ let data = res.data as GetSiteConfigResponse;
+ this.state.siteConfigRes = data;
+ this.state.loading = false;
+ this.state.siteConfigForm.config_hjson = this.state.siteConfigRes.config_hjson;
+ this.setState(this.state);
+ var textarea: any = document.getElementById(this.siteConfigTextAreaId);
+ autosize(textarea);
+ } else if (res.op == UserOperation.SaveSiteConfig) {
+ let data = res.data as GetSiteConfigResponse;
+ this.state.siteConfigRes = data;
+ this.state.siteConfigForm.config_hjson = this.state.siteConfigRes.config_hjson;
+ this.state.siteConfigLoading = false;
+ toast(i18n.t('site_saved'));
+ this.setState(this.state);
+ }
+ }
+}
diff --git a/ui/src/components/comment-node.tsx b/ui/src/components/comment-node.tsx
index 39f29b5f8..ba4301e16 100644
--- a/ui/src/components/comment-node.tsx
+++ b/ui/src/components/comment-node.tsx
@@ -24,8 +24,6 @@ import {
getUnixTime,
canMod,
isMod,
- pictshareAvatarThumbnail,
- showAvatars,
setupTippy,
colorList,
} from '../utils';
@@ -33,6 +31,7 @@ import moment from 'moment';
import { MomentTime } from './moment-time';
import { CommentForm } from './comment-form';
import { CommentNodes } from './comment-nodes';
+import { UserListing } from './user-listing';
import { i18n } from '../i18next';
interface CommentNodeState {
@@ -148,20 +147,14 @@ export class CommentNode extends Component {
'ml-2'}`}
>
-
- {node.comment.creator_avatar && showAvatars() && (
-
- )}
-
{node.comment.creator_name}
-
+
+
+
{this.isMod && (
{i18n.t('mod')}
@@ -191,7 +184,7 @@ export class CommentNode extends Component
{
>
)}
{this.state.collapsed ? (
diff --git a/ui/src/components/main.tsx b/ui/src/components/main.tsx
index 380033127..366d3be8f 100644
--- a/ui/src/components/main.tsx
+++ b/ui/src/components/main.tsx
@@ -33,13 +33,12 @@ import { SortSelect } from './sort-select';
import { ListingTypeSelect } from './listing-type-select';
import { DataTypeSelect } from './data-type-select';
import { SiteForm } from './site-form';
+import { UserListing } from './user-listing';
import {
wsJsonToRes,
repoUrl,
mdToHtml,
fetchLimit,
- pictshareAvatarThumbnail,
- showAvatars,
toast,
getListingTypeFromProps,
getPageFromProps,
@@ -316,20 +315,12 @@ export class Main extends Component
{
{i18n.t('admins')}:
{this.state.siteRes.admins.map(admin => (
-
- {admin.avatar && showAvatars() && (
-
- )}
- {admin.name}
-
+
))}
@@ -619,6 +610,7 @@ export class Main extends Component {
this.state.siteRes.site = data.site;
this.state.showEditSite = false;
this.setState(this.state);
+ toast(i18n.t('site_saved'));
} else if (res.op == UserOperation.GetPosts) {
let data = res.data as GetPostsResponse;
this.state.posts = data.posts;
diff --git a/ui/src/components/navbar.tsx b/ui/src/components/navbar.tsx
index d7f3b5a8a..e0d8aff50 100644
--- a/ui/src/components/navbar.tsx
+++ b/ui/src/components/navbar.tsx
@@ -16,6 +16,7 @@ import {
Comment,
CommentResponse,
PrivateMessage,
+ UserView,
PrivateMessageResponse,
WebSocketJsonResponse,
} from '../interfaces';
@@ -40,6 +41,7 @@ interface NavbarState {
messages: Array;
unreadCount: number;
siteName: string;
+ admins: Array;
}
export class Navbar extends Component {
@@ -53,6 +55,7 @@ export class Navbar extends Component {
messages: [],
expanded: false,
siteName: undefined,
+ admins: [],
};
constructor(props: any, context: any) {
@@ -179,6 +182,19 @@ export class Navbar extends Component {
+ {this.canAdmin && (
+
+
+
+
+
+
+
+ )}
{this.state.isLoggedIn ? (
<>
@@ -298,7 +314,10 @@ export class Navbar extends Component {
if (data.site && !this.state.siteName) {
this.state.siteName = data.site.name;
+ this.state.admins = data.admins;
WebSocketService.Instance.site = data.site;
+ WebSocketService.Instance.admins = data.admins;
+
this.setState(this.state);
}
}
@@ -353,6 +372,13 @@ export class Navbar extends Component {
);
}
+ get canAdmin(): boolean {
+ return (
+ UserService.Instance.user &&
+ this.state.admins.map(a => a.id).includes(UserService.Instance.user.id)
+ );
+ }
+
requestNotificationPermission() {
if (UserService.Instance.user) {
document.addEventListener('DOMContentLoaded', function() {
diff --git a/ui/src/components/post-listing.tsx b/ui/src/components/post-listing.tsx
index 101d18078..d0efa0437 100644
--- a/ui/src/components/post-listing.tsx
+++ b/ui/src/components/post-listing.tsx
@@ -19,6 +19,7 @@ import {
import { MomentTime } from './moment-time';
import { PostForm } from './post-form';
import { IFramelyCard } from './iframely-card';
+import { UserListing } from './user-listing';
import {
md,
mdToHtml,
@@ -27,8 +28,6 @@ import {
isImage,
isVideo,
getUnixTime,
- pictshareAvatarThumbnail,
- showAvatars,
pictshareImage,
setupTippy,
previewLines,
@@ -417,20 +416,12 @@ export class PostListing extends Component {
{i18n.t('by')}
-
- {post.creator_avatar && showAvatars() && (
-
- )}
- {post.creator_name}
-
+
{this.isMod && (
{i18n.t('mod')}
diff --git a/ui/src/components/private-message-form.tsx b/ui/src/components/private-message-form.tsx
index 7e498bae3..6b607654b 100644
--- a/ui/src/components/private-message-form.tsx
+++ b/ui/src/components/private-message-form.tsx
@@ -21,14 +21,13 @@ import {
capitalizeFirstLetter,
markdownHelpUrl,
mdToHtml,
- showAvatars,
- pictshareAvatarThumbnail,
wsJsonToRes,
toast,
randomStr,
setupTribute,
setupTippy,
} from '../utils';
+import { UserListing } from './user-listing';
import Tribute from 'tributejs/src/Tribute.js';
import autosize from 'autosize';
import { i18n } from '../i18next';
@@ -132,22 +131,12 @@ export class PrivateMessageForm extends Component<
{this.state.recipient && (
-
- {this.state.recipient.avatar && showAvatars() && (
-
- )}
-
{this.state.recipient.name}
-
+
)}
diff --git a/ui/src/components/private-message.tsx b/ui/src/components/private-message.tsx
index ef128dd4a..337b16501 100644
--- a/ui/src/components/private-message.tsx
+++ b/ui/src/components/private-message.tsx
@@ -58,6 +58,7 @@ export class PrivateMessage extends Component<
+ {/* TODO refactor this */}
{this.mine ? i18n.t('to') : i18n.t('from')}
diff --git a/ui/src/components/search.tsx b/ui/src/components/search.tsx
index 3fd2f4677..b9662fae3 100644
--- a/ui/src/components/search.tsx
+++ b/ui/src/components/search.tsx
@@ -30,6 +30,7 @@ import {
commentsToFlatNodes,
} from '../utils';
import { PostListing } from './post-listing';
+import { UserListing } from './user-listing';
import { SortSelect } from './sort-select';
import { CommentNodes } from './comment-nodes';
import { i18n } from '../i18next';
@@ -266,22 +267,12 @@ export class Search extends Component {
{i.type_ == 'users' && (
-
- {(i.data as UserView).avatar && showAvatars() && (
-
- )}
- {`/u/${(i.data as UserView).name}`}
-
+
{` - ${
(i.data as UserView).comment_score
diff --git a/ui/src/components/sidebar.tsx b/ui/src/components/sidebar.tsx
index 0f4a0e10d..d66266f6c 100644
--- a/ui/src/components/sidebar.tsx
+++ b/ui/src/components/sidebar.tsx
@@ -15,6 +15,7 @@ import {
showAvatars,
} from '../utils';
import { CommunityForm } from './community-form';
+import { UserListing } from './user-listing';
import { i18n } from '../i18next';
interface SidebarProps {
@@ -204,20 +205,12 @@ export class Sidebar extends Component {
{i18n.t('mods')}:
{this.props.moderators.map(mod => (
-
- {mod.avatar && showAvatars() && (
-
- )}
- {mod.user_name}
-
+
))}
diff --git a/ui/src/components/site-form.tsx b/ui/src/components/site-form.tsx
index df913043e..f0c80585e 100644
--- a/ui/src/components/site-form.tsx
+++ b/ui/src/components/site-form.tsx
@@ -58,12 +58,19 @@ export class SiteForm extends Component {
});
}
+ // Necessary to stop the loading
+ componentWillReceiveProps() {
+ this.state.loading = false;
+ this.setState(this.state);
+ }
+
render() {
return (
<>
{
xmlnsXlink="http://www.w3.org/1999/xlink"
>
+
+
+
diff --git a/ui/src/components/user-listing.tsx b/ui/src/components/user-listing.tsx
new file mode 100644
index 000000000..1f136e006
--- /dev/null
+++ b/ui/src/components/user-listing.tsx
@@ -0,0 +1,36 @@
+import { Component } from 'inferno';
+import { Link } from 'inferno-router';
+import { UserView } from '../interfaces';
+import { pictshareAvatarThumbnail, showAvatars } from '../utils';
+
+interface UserOther {
+ name: string;
+ avatar?: string;
+}
+
+interface UserListingProps {
+ user: UserView | UserOther;
+}
+
+export class UserListing extends Component {
+ constructor(props: any, context: any) {
+ super(props, context);
+ }
+
+ render() {
+ let user = this.props.user;
+ return (
+
+ {user.avatar && showAvatars() && (
+
+ )}
+ {user.name}
+
+ );
+ }
+}
diff --git a/ui/src/index.tsx b/ui/src/index.tsx
index c56f6c4ea..8e49df9fb 100644
--- a/ui/src/index.tsx
+++ b/ui/src/index.tsx
@@ -15,79 +15,85 @@ import { Communities } from './components/communities';
import { User } from './components/user';
import { Modlog } from './components/modlog';
import { Setup } from './components/setup';
+import { AdminSettings } from './components/admin-settings';
import { Inbox } from './components/inbox';
import { Search } from './components/search';
import { Sponsors } from './components/sponsors';
import { Symbols } from './components/symbols';
import { i18n } from './i18next';
-import { WebSocketService, UserService } from './services';
-
const container = document.getElementById('app');
class Index extends Component {
constructor(props: any, context: any) {
super(props, context);
- WebSocketService.Instance;
- UserService.Instance;
}
render() {
return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
);
diff --git a/ui/src/interfaces.ts b/ui/src/interfaces.ts
index 0eeeac06d..b77ccac65 100644
--- a/ui/src/interfaces.ts
+++ b/ui/src/interfaces.ts
@@ -43,6 +43,8 @@ export enum UserOperation {
GetPrivateMessages,
UserJoin,
GetComments,
+ GetSiteConfig,
+ SaveSiteConfig,
}
export enum CommentSortType {
@@ -102,7 +104,6 @@ export interface UserView {
avatar?: string;
email?: string;
matrix_user_id?: string;
- fedi_name: string;
published: string;
number_of_posts: number;
post_score: number;
@@ -699,6 +700,19 @@ export interface SiteForm {
auth?: string;
}
+export interface GetSiteConfig {
+ auth?: string;
+}
+
+export interface GetSiteConfigResponse {
+ config_hjson: string;
+}
+
+export interface SiteConfigForm {
+ config_hjson: string;
+ auth?: string;
+}
+
export interface GetSiteResponse {
site: Site;
admins: Array
;
@@ -846,7 +860,8 @@ export type MessageType =
| PasswordChangeForm
| PrivateMessageForm
| EditPrivateMessageForm
- | GetPrivateMessagesForm;
+ | GetPrivateMessagesForm
+ | SiteConfigForm;
type ResponseType =
| SiteResponse
@@ -868,7 +883,8 @@ type ResponseType =
| BanUserResponse
| AddAdminResponse
| PrivateMessageResponse
- | PrivateMessagesResponse;
+ | PrivateMessagesResponse
+ | GetSiteConfigResponse;
export interface WebSocketResponse {
op: UserOperation;
diff --git a/ui/src/services/WebSocketService.ts b/ui/src/services/WebSocketService.ts
index 02c97cc94..f18b518b9 100644
--- a/ui/src/services/WebSocketService.ts
+++ b/ui/src/services/WebSocketService.ts
@@ -40,6 +40,8 @@ import {
GetPrivateMessagesForm,
GetCommentsForm,
UserJoinForm,
+ GetSiteConfig,
+ SiteConfigForm,
MessageType,
WebSocketJsonResponse,
} from '../interfaces';
@@ -268,6 +270,12 @@ export class WebSocketService {
this.ws.send(this.wsSendWrapper(UserOperation.GetSite, {}));
}
+ public getSiteConfig() {
+ let siteConfig: GetSiteConfig = {};
+ this.setAuth(siteConfig);
+ this.ws.send(this.wsSendWrapper(UserOperation.GetSiteConfig, siteConfig));
+ }
+
public search(form: SearchForm) {
this.setAuth(form, false);
this.ws.send(this.wsSendWrapper(UserOperation.Search, form));
@@ -314,6 +322,11 @@ export class WebSocketService {
this.ws.send(this.wsSendWrapper(UserOperation.GetPrivateMessages, form));
}
+ public saveSiteConfig(form: SiteConfigForm) {
+ this.setAuth(form);
+ this.ws.send(this.wsSendWrapper(UserOperation.SaveSiteConfig, form));
+ }
+
private wsSendWrapper(op: UserOperation, data: MessageType) {
let send = { op: UserOperation[op], data: data };
console.log(send);
diff --git a/ui/translations/en.json b/ui/translations/en.json
index 0281aaf4b..a39496aba 100644
--- a/ui/translations/en.json
+++ b/ui/translations/en.json
@@ -53,6 +53,8 @@
"mods": "mods",
"moderates": "Moderates",
"settings": "Settings",
+ "admin_settings": "Admin Settings",
+ "site_config": "Site Configuration",
"remove_as_mod": "remove as mod",
"appoint_as_mod": "appoint as mod",
"modlog": "Modlog",
@@ -78,6 +80,7 @@
"unban": "unban",
"unban_from_site": "unban from site",
"banned": "banned",
+ "banned_users": "Banned Users",
"save": "save",
"unsave": "unsave",
"create": "create",
@@ -210,6 +213,7 @@
"Lemmy is a <1>link aggregator1> / reddit alternative, intended to work in the <2>fediverse2>.<3>3>It's self-hostable, has live-updating comment threads, and is tiny (<4>~80kB4>). Federation into the ActivityPub network is on the roadmap. <5>5>This is a <6>very early beta version6>, and a lot of features are currently broken or missing. <7>7>Suggest new features or report bugs <8>here.8><9>9>Made with <10>Rust10>, <11>Actix11>, <12>Inferno12>, <13>Typescript13>.",
"not_logged_in": "Not logged in.",
"logged_in": "Logged in.",
+ "site_saved": "Site Saved.",
"community_ban": "You have been banned from this community.",
"site_ban": "You have been banned from the site",
"couldnt_create_comment": "Couldn't create comment.",
From 938c61b94f4e50d73af4449ca8b49e72bf73b218 Mon Sep 17 00:00:00 2001
From: Dessalines
Date: Sat, 11 Apr 2020 14:06:04 -0400
Subject: [PATCH 12/24] Adding live reloading of config.hjson changes through
UI.
- https://stackoverflow.com/questions/61159698/update-re-initialize-a-var-defined-in-lazy-static/61161271#61161271
- https://stackoverflow.com/questions/29654927/how-do-i-assign-a-string-to-a-mutable-static-variable/47181804#47181804
---
server/src/api/user.rs | 2 +-
server/src/lib.rs | 4 ++--
server/src/main.rs | 1 +
server/src/routes/index.rs | 2 +-
server/src/settings.rs | 35 +++++++++++++++++++++--------------
5 files changed, 26 insertions(+), 18 deletions(-)
diff --git a/server/src/api/user.rs b/server/src/api/user.rs
index 056a2a846..40e099694 100644
--- a/server/src/api/user.rs
+++ b/server/src/api/user.rs
@@ -253,7 +253,7 @@ impl Perform for Oper {
// Register the new user
let user_form = UserForm {
name: data.username.to_owned(),
- fedi_name: Settings::get().hostname.to_owned(),
+ fedi_name: Settings::get().hostname,
email: data.email.to_owned(),
matrix_user_id: None,
avatar: None,
diff --git a/server/src/lib.rs b/server/src/lib.rs
index 8257dab9a..9bbfe251a 100644
--- a/server/src/lib.rs
+++ b/server/src/lib.rs
@@ -112,7 +112,7 @@ pub fn send_email(
to_username: &str,
html: &str,
) -> Result<(), String> {
- let email_config = Settings::get().email.as_ref().ok_or("no_email_setup")?;
+ let email_config = Settings::get().email.ok_or("no_email_setup")?;
let email = Email::builder()
.to((to_email, to_username))
@@ -127,7 +127,7 @@ pub fn send_email(
} else {
SmtpClient::new(&email_config.smtp_server, ClientSecurity::None).unwrap()
}
- .hello_name(ClientId::Domain(Settings::get().hostname.to_owned()))
+ .hello_name(ClientId::Domain(Settings::get().hostname))
.smtp_utf8(true)
.authentication_mechanism(Mechanism::Plain)
.connection_reuse(ConnectionReuseParameters::ReuseUnlimited);
diff --git a/server/src/main.rs b/server/src/main.rs
index 601c2e0dc..1c79c9ee3 100644
--- a/server/src/main.rs
+++ b/server/src/main.rs
@@ -39,6 +39,7 @@ async fn main() -> io::Result<()> {
// Create Http server with websocket support
HttpServer::new(move || {
+ let settings = Settings::get();
App::new()
.wrap(middleware::Logger::default())
.data(pool.clone())
diff --git a/server/src/routes/index.rs b/server/src/routes/index.rs
index 45ce204e8..2e192df41 100644
--- a/server/src/routes/index.rs
+++ b/server/src/routes/index.rs
@@ -45,6 +45,6 @@ pub fn config(cfg: &mut web::ServiceConfig) {
async fn index() -> Result {
Ok(NamedFile::open(
- Settings::get().front_end_dir.to_owned() + "/index.html",
+ Settings::get().front_end_dir + "/index.html",
)?)
}
diff --git a/server/src/settings.rs b/server/src/settings.rs
index 216c057e4..6e5667cb2 100644
--- a/server/src/settings.rs
+++ b/server/src/settings.rs
@@ -4,11 +4,12 @@ use serde::Deserialize;
use std::env;
use std::fs;
use std::net::IpAddr;
+use std::sync::RwLock;
static CONFIG_FILE_DEFAULTS: &str = "config/defaults.hjson";
static CONFIG_FILE: &str = "config/config.hjson";
-#[derive(Debug, Deserialize)]
+#[derive(Debug, Deserialize, Clone)]
pub struct Settings {
pub setup: Option,
pub database: Database,
@@ -22,7 +23,7 @@ pub struct Settings {
pub federation_enabled: bool,
}
-#[derive(Debug, Deserialize)]
+#[derive(Debug, Deserialize, Clone)]
pub struct Setup {
pub admin_username: String,
pub admin_password: String,
@@ -30,7 +31,7 @@ pub struct Setup {
pub site_name: String,
}
-#[derive(Debug, Deserialize)]
+#[derive(Debug, Deserialize, Clone)]
pub struct RateLimitConfig {
pub message: i32,
pub message_per_second: i32,
@@ -40,7 +41,7 @@ pub struct RateLimitConfig {
pub register_per_second: i32,
}
-#[derive(Debug, Deserialize)]
+#[derive(Debug, Deserialize, Clone)]
pub struct EmailConfig {
pub smtp_server: String,
pub smtp_login: Option,
@@ -49,7 +50,7 @@ pub struct EmailConfig {
pub use_tls: bool,
}
-#[derive(Debug, Deserialize)]
+#[derive(Debug, Deserialize, Clone)]
pub struct Database {
pub user: String,
pub password: String,
@@ -60,12 +61,10 @@ pub struct Database {
}
lazy_static! {
- static ref SETTINGS: Settings = {
- match Settings::init() {
- Ok(c) => c,
- Err(e) => panic!("{}", e),
- }
- };
+ static ref SETTINGS: RwLock = RwLock::new(match Settings::init() {
+ Ok(c) => c,
+ Err(e) => panic!("{}", e),
+ });
}
impl Settings {
@@ -91,8 +90,8 @@ impl Settings {
}
/// Returns the config as a struct.
- pub fn get() -> &'static Self {
- &SETTINGS
+ pub fn get() -> Self {
+ SETTINGS.read().unwrap().to_owned()
}
/// Returns the postgres connection url. If LEMMY_DATABASE_URL is set, that is used,
@@ -121,7 +120,15 @@ impl Settings {
pub fn save_config_file(data: &str) -> Result {
fs::write(CONFIG_FILE, data)?;
- Self::init()?;
+
+ // Reload the new settings
+ // From https://stackoverflow.com/questions/29654927/how-do-i-assign-a-string-to-a-mutable-static-variable/47181804#47181804
+ let mut new_settings = SETTINGS.write().unwrap();
+ *new_settings = match Settings::init() {
+ Ok(c) => c,
+ Err(e) => panic!("{}", e),
+ };
+
Self::read_config_file()
}
}
From d9d52d7d06e96aa0ff9e2461446e229a3cae47db Mon Sep 17 00:00:00 2001
From: Dessalines
Date: Sat, 11 Apr 2020 14:10:33 -0400
Subject: [PATCH 13/24] Removing redundant to_owned
---
server/src/main.rs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/server/src/main.rs b/server/src/main.rs
index 1c79c9ee3..f38875275 100644
--- a/server/src/main.rs
+++ b/server/src/main.rs
@@ -59,7 +59,7 @@ async fn main() -> io::Result<()> {
))
.service(actix_files::Files::new(
"/docs",
- settings.front_end_dir.to_owned() + "/documentation",
+ settings.front_end_dir + "/documentation",
))
})
.bind((settings.bind, settings.port))?
From c459a5208543c5aa6da46048e7b66a039c273878 Mon Sep 17 00:00:00 2001
From: Dessalines
Date: Sat, 11 Apr 2020 23:22:46 -0400
Subject: [PATCH 14/24] Add Emoji Picker for comments and post body.
- Fixes #634
---
ui/assets/css/main.css | 2 +-
ui/package.json | 1 +
ui/src/components/comment-form.tsx | 28 +++++++++++
ui/src/components/post-form.tsx | 32 ++++++++++++-
ui/src/components/symbols.tsx | 3 ++
ui/src/utils.ts | 9 ++++
ui/translations/en.json | 1 +
ui/yarn.lock | 75 +++++++++++++++++++++++++++++-
8 files changed, 147 insertions(+), 4 deletions(-)
diff --git a/ui/assets/css/main.css b/ui/assets/css/main.css
index 1c8206e35..bf249e5bf 100644
--- a/ui/assets/css/main.css
+++ b/ui/assets/css/main.css
@@ -156,7 +156,7 @@ hr {
}
.emoji {
- height: 1.2em !important;
+ max-height: 1.2em !important;
}
.text-wrap-truncate {
diff --git a/ui/package.json b/ui/package.json
index 7d946614c..25ee2e00d 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -14,6 +14,7 @@
},
"keywords": [],
"dependencies": {
+ "@joeattardi/emoji-button": "^2.12.1",
"@types/autosize": "^3.0.6",
"@types/js-cookie": "^2.2.5",
"@types/jwt-decode": "^2.2.1",
diff --git a/ui/src/components/comment-form.tsx b/ui/src/components/comment-form.tsx
index ae3e7cfc3..6898ebc79 100644
--- a/ui/src/components/comment-form.tsx
+++ b/ui/src/components/comment-form.tsx
@@ -17,10 +17,12 @@ import {
toast,
setupTribute,
wsJsonToRes,
+ emojiPicker,
} from '../utils';
import { WebSocketService, UserService } from '../services';
import autosize from 'autosize';
import Tribute from 'tributejs/src/Tribute.js';
+import emojiShortName from 'emoji-short-name';
import { i18n } from '../i18next';
interface CommentFormProps {
@@ -69,6 +71,8 @@ export class CommentForm extends Component {
super(props, context);
this.tribute = setupTribute();
+ this.setupEmojiPicker();
+
this.state = this.emptyState;
if (this.props.node) {
@@ -209,6 +213,15 @@ export class CommentForm extends Component {
)}
+
+
+
+
+
@@ -216,6 +229,17 @@ export class CommentForm extends Component {
);
}
+ setupEmojiPicker() {
+ emojiPicker.on('emoji', emoji => {
+ if (this.state.commentForm.content == null) {
+ this.state.commentForm.content = '';
+ }
+ let shortName = `:${emojiShortName[emoji]}:`;
+ this.state.commentForm.content += shortName;
+ this.setState(this.state);
+ });
+ }
+
handleFinished() {
this.state.previewMode = false;
this.state.loading = false;
@@ -242,6 +266,10 @@ export class CommentForm extends Component {
i.setState(i.state);
}
+ handleEmojiPickerClick(_i: CommentForm, event: any) {
+ emojiPicker.togglePicker(event.target);
+ }
+
handleCommentContentChange(i: CommentForm, event: any) {
i.state.commentForm.content = event.target.value;
i.setState(i.state);
diff --git a/ui/src/components/post-form.tsx b/ui/src/components/post-form.tsx
index 47920b9b4..a65ead462 100644
--- a/ui/src/components/post-form.tsx
+++ b/ui/src/components/post-form.tsx
@@ -34,9 +34,11 @@ import {
randomStr,
setupTribute,
setupTippy,
+ emojiPicker,
} from '../utils';
import autosize from 'autosize';
import Tribute from 'tributejs/src/Tribute.js';
+import emojiShortName from 'emoji-short-name';
import Selectr from 'mobius1-selectr';
import { i18n } from '../i18next';
@@ -92,6 +94,8 @@ export class PostForm extends Component {
this.fetchPageTitle = debounce(this.fetchPageTitle).bind(this);
this.tribute = setupTribute();
+ this.setupEmojiPicker();
+
this.state = this.emptyState;
if (this.props.post) {
@@ -191,7 +195,7 @@ export class PostForm extends Component {
@@ -294,13 +298,22 @@ export class PostForm extends Component {
+
+
+
+
+
{!this.props.post && (
@@ -369,6 +382,17 @@ export class PostForm extends Component {
);
}
+ setupEmojiPicker() {
+ emojiPicker.on('emoji', emoji => {
+ if (this.state.postForm.body == null) {
+ this.state.postForm.body = '';
+ }
+ let shortName = `:${emojiShortName[emoji]}:`;
+ this.state.postForm.body += shortName;
+ this.setState(this.state);
+ });
+ }
+
handlePostSubmit(i: PostForm, event: any) {
event.preventDefault();
if (i.props.post) {
@@ -512,6 +536,10 @@ export class PostForm extends Component {
});
}
+ handleEmojiPickerClick(_i: PostForm, event: any) {
+ emojiPicker.togglePicker(event.target);
+ }
+
parseMessage(msg: WebSocketJsonResponse) {
let res = wsJsonToRes(msg);
if (msg.error) {
diff --git a/ui/src/components/symbols.tsx b/ui/src/components/symbols.tsx
index dae734a80..4925257be 100644
--- a/ui/src/components/symbols.tsx
+++ b/ui/src/components/symbols.tsx
@@ -15,6 +15,9 @@ export class Symbols extends Component {
xmlnsXlink="http://www.w3.org/1999/xlink"
>
+
+
+
diff --git a/ui/src/utils.ts b/ui/src/utils.ts
index ceb05764d..7c3c4205a 100644
--- a/ui/src/utils.ts
+++ b/ui/src/utils.ts
@@ -43,6 +43,7 @@ import twemoji from 'twemoji';
import emojiShortName from 'emoji-short-name';
import Toastify from 'toastify-js';
import tippy from 'tippy.js';
+import EmojiButton from '@joeattardi/emoji-button';
export const repoUrl = 'https://github.com/LemmyNet/lemmy';
export const helpGuideUrl = '/docs/about_guide.html';
@@ -88,6 +89,14 @@ export const themes = [
'i386',
];
+export const emojiPicker = new EmojiButton({
+ // Use the emojiShortName from native
+ // style: 'twemoji',
+ theme: 'dark',
+ position: 'auto-start',
+ // TODO i18n
+});
+
export function randomStr() {
return Math.random()
.toString(36)
diff --git a/ui/translations/en.json b/ui/translations/en.json
index 0281aaf4b..1b29db553 100644
--- a/ui/translations/en.json
+++ b/ui/translations/en.json
@@ -251,5 +251,6 @@
"couldnt_update_private_message": "Couldn't update private message.",
"time": "Time",
"action": "Action",
+ "emoji_picker": "Emoji Picker",
"block_leaving": "Are you sure you want to leave?"
}
diff --git a/ui/yarn.lock b/ui/yarn.lock
index 8d75052b9..eb88b8af0 100644
--- a/ui/yarn.lock
+++ b/ui/yarn.lock
@@ -126,6 +126,51 @@
lodash "^4.17.13"
to-fast-properties "^2.0.0"
+"@fortawesome/fontawesome-common-types@^0.2.28":
+ version "0.2.28"
+ resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.28.tgz#1091bdfe63b3f139441e9cba27aa022bff97d8b2"
+ integrity sha512-gtis2/5yLdfI6n0ia0jH7NJs5i/Z/8M/ZbQL6jXQhCthEOe5Cr5NcQPhgTvFxNOtURE03/ZqUcEskdn2M+QaBg==
+
+"@fortawesome/fontawesome-svg-core@^1.2.22":
+ version "1.2.28"
+ resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.28.tgz#e5b8c8814ef375f01f5d7c132d3c3a2f83a3abf9"
+ integrity sha512-4LeaNHWvrneoU0i8b5RTOJHKx7E+y7jYejplR7uSVB34+mp3Veg7cbKk7NBCLiI4TyoWS1wh9ZdoyLJR8wSAdg==
+ dependencies:
+ "@fortawesome/fontawesome-common-types" "^0.2.28"
+
+"@fortawesome/free-regular-svg-icons@^5.10.2":
+ version "5.13.0"
+ resolved "https://registry.yarnpkg.com/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-5.13.0.tgz#925a13d8bdda0678f71551828cac80ab47b8150c"
+ integrity sha512-70FAyiS5j+ANYD4dh9NGowTorNDnyvQHHpCM7FpnF7GxtDjBUCKdrFqCPzesEIpNDFNd+La3vex+jDk4nnUfpA==
+ dependencies:
+ "@fortawesome/fontawesome-common-types" "^0.2.28"
+
+"@fortawesome/free-solid-svg-icons@^5.10.2":
+ version "5.13.0"
+ resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.13.0.tgz#44d9118668ad96b4fd5c9434a43efc5903525739"
+ integrity sha512-IHUgDJdomv6YtG4p3zl1B5wWf9ffinHIvebqQOmV3U+3SLw4fC+LUCCgwfETkbTtjy5/Qws2VoVf6z/ETQpFpg==
+ dependencies:
+ "@fortawesome/fontawesome-common-types" "^0.2.28"
+
+"@joeattardi/emoji-button@^2.12.1":
+ version "2.12.1"
+ resolved "https://registry.yarnpkg.com/@joeattardi/emoji-button/-/emoji-button-2.12.1.tgz#190df7c00721e04742ed6f8852db828798a4cf98"
+ integrity sha512-rUuCXIcv4mRFK2IUKarYJN6J667wtH234smb1aQILzRf3/ycOoa6yUwnnvjxZeXMsPhuTnz15ndMOP2DhO5nNw==
+ dependencies:
+ "@fortawesome/fontawesome-svg-core" "^1.2.22"
+ "@fortawesome/free-regular-svg-icons" "^5.10.2"
+ "@fortawesome/free-solid-svg-icons" "^5.10.2"
+ "@popperjs/core" "^2.0.0"
+ focus-trap "^5.1.0"
+ tiny-emitter "^2.1.0"
+ tslib "^1.10.0"
+ twemoji "^12.1.5"
+
+"@popperjs/core@^2.0.0":
+ version "2.2.3"
+ resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.2.3.tgz#0ae22b5650ab0b8fe508047245b66e71fc59e983"
+ integrity sha512-68EQPzEZRrpFavFX40V2+80eqzQIhgza2AGTXW+i8laxSA4It+Y13rmZInrAYoIujp8YO7YJPbvgOesDZcIulQ==
+
"@popperjs/core@^2.1.1":
version "2.1.1"
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.1.1.tgz#12c572ab88ef7345b43f21883fca26631c223085"
@@ -1829,6 +1874,14 @@ fliplog@^0.3.13:
dependencies:
chain-able "^1.0.1"
+focus-trap@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/focus-trap/-/focus-trap-5.1.0.tgz#64a0bfabd95c382103397dbc96bfef3a3cf8e5ad"
+ integrity sha512-CkB/nrO55069QAUjWFBpX6oc+9V90Qhgpe6fBWApzruMq5gnlh90Oo7iSSDK7pKiV5ugG6OY2AXM5mxcmL3lwQ==
+ dependencies:
+ tabbable "^4.0.0"
+ xtend "^4.0.1"
+
for-in@^1.0.1, for-in@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
@@ -4473,6 +4526,11 @@ symbol-observable@^1.1.0:
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==
+tabbable@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-4.0.0.tgz#5bff1d1135df1482cf0f0206434f15eadbeb9261"
+ integrity sha512-H1XoH1URcBOa/rZZWxLxHCtOdVUEev+9vo5YdYhC9tCY4wnybX+VQrCYuy9ubkg69fCBxCONJOSLGfw0DWMffQ==
+
table@^5.2.3:
version "5.4.6"
resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e"
@@ -4502,6 +4560,11 @@ through@^2.3.6:
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
+tiny-emitter@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423"
+ integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==
+
tiny-invariant@^1.0.2:
version "1.1.0"
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.1.0.tgz#634c5f8efdc27714b7f386c35e6760991d230875"
@@ -4609,6 +4672,11 @@ ts-transform-inferno@^4.0.2:
resolved "https://registry.yarnpkg.com/ts-transform-inferno/-/ts-transform-inferno-4.0.2.tgz#06b9be45edf874ba7a6ebfb6107ba782509c6afe"
integrity sha512-CZb4+w/2l2zikPZ/c51fi3n+qnR2HCEfAS73oGQB80aqRLffkZqm25kYYTMmqUW2+oVfs4M5AZa0z14cvxlQ5w==
+tslib@^1.10.0:
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35"
+ integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==
+
tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a"
@@ -4638,7 +4706,7 @@ twemoji-parser@12.1.3:
resolved "https://registry.yarnpkg.com/twemoji-parser/-/twemoji-parser-12.1.3.tgz#916c0153e77bd5f1011e7a99cbeacf52e43c9371"
integrity sha512-ND4LZXF4X92/PFrzSgGkq6KPPg8swy/U0yRw1k/+izWRVmq1HYi3khPwV3XIB6FRudgVICAaBhJfW8e8G3HC7Q==
-twemoji@^12.1.2:
+twemoji@^12.1.2, twemoji@^12.1.5:
version "12.1.5"
resolved "https://registry.yarnpkg.com/twemoji/-/twemoji-12.1.5.tgz#a961fb65a1afcb1f729ad7e59391f9fe969820b9"
integrity sha512-B0PBVy5xomwb1M/WZxf/IqPZfnoIYy1skXnlHjMwLwTNfZ9ljh8VgWQktAPcJXu8080WoEh6YwQGPVhDVqvrVQ==
@@ -4890,6 +4958,11 @@ xregexp@^4.3.0:
dependencies:
"@babel/runtime-corejs3" "^7.8.3"
+xtend@^4.0.1:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
+ integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
+
yaml@^1.7.2:
version "1.7.2"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.7.2.tgz#f26aabf738590ab61efaca502358e48dc9f348b2"
From d6d7680c7b52b34017dddc2dead6ebe42bb1eb8f Mon Sep 17 00:00:00 2001
From: Dessalines
Date: Sun, 12 Apr 2020 11:45:44 -0400
Subject: [PATCH 15/24] Make sure typing dropdown uses twemojis.
---
ui/src/utils.ts | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/ui/src/utils.ts b/ui/src/utils.ts
index 7c3c4205a..fd23bf9ea 100644
--- a/ui/src/utils.ts
+++ b/ui/src/utils.ts
@@ -482,8 +482,9 @@ export function setupTribute(): Tribute {
{
trigger: ':',
menuItemTemplate: (item: any) => {
- let emoji = `:${item.original.key}:`;
- return `${item.original.val} ${emoji}`;
+ let shortName = `:${item.original.key}:`;
+ let twemojiIcon = twemoji.parse(item.original.val);
+ return `${twemojiIcon} ${shortName}`;
},
selectTemplate: (item: any) => {
return `:${item.original.key}:`;
From 8e05274bc8884c6d0a9b43748221f2c1ac6d4a13 Mon Sep 17 00:00:00 2001
From: Dessalines
Date: Sun, 12 Apr 2020 12:47:48 -0400
Subject: [PATCH 16/24] Add Emoji squashed commit.
---
ui/assets/css/main.css | 2 +-
ui/package.json | 1 +
ui/src/components/comment-form.tsx | 28 +++++++++++
ui/src/components/post-form.tsx | 32 ++++++++++++-
ui/src/components/symbols.tsx | 3 ++
ui/src/utils.ts | 14 +++++-
ui/translations/en.json | 1 +
ui/yarn.lock | 75 +++++++++++++++++++++++++++++-
8 files changed, 150 insertions(+), 6 deletions(-)
diff --git a/ui/assets/css/main.css b/ui/assets/css/main.css
index 1c8206e35..bf249e5bf 100644
--- a/ui/assets/css/main.css
+++ b/ui/assets/css/main.css
@@ -156,7 +156,7 @@ hr {
}
.emoji {
- height: 1.2em !important;
+ max-height: 1.2em !important;
}
.text-wrap-truncate {
diff --git a/ui/package.json b/ui/package.json
index 7d946614c..25ee2e00d 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -14,6 +14,7 @@
},
"keywords": [],
"dependencies": {
+ "@joeattardi/emoji-button": "^2.12.1",
"@types/autosize": "^3.0.6",
"@types/js-cookie": "^2.2.5",
"@types/jwt-decode": "^2.2.1",
diff --git a/ui/src/components/comment-form.tsx b/ui/src/components/comment-form.tsx
index ae3e7cfc3..6898ebc79 100644
--- a/ui/src/components/comment-form.tsx
+++ b/ui/src/components/comment-form.tsx
@@ -17,10 +17,12 @@ import {
toast,
setupTribute,
wsJsonToRes,
+ emojiPicker,
} from '../utils';
import { WebSocketService, UserService } from '../services';
import autosize from 'autosize';
import Tribute from 'tributejs/src/Tribute.js';
+import emojiShortName from 'emoji-short-name';
import { i18n } from '../i18next';
interface CommentFormProps {
@@ -69,6 +71,8 @@ export class CommentForm extends Component {
super(props, context);
this.tribute = setupTribute();
+ this.setupEmojiPicker();
+
this.state = this.emptyState;
if (this.props.node) {
@@ -209,6 +213,15 @@ export class CommentForm extends Component {
)}
+
+
+
+
+
@@ -216,6 +229,17 @@ export class CommentForm extends Component {
);
}
+ setupEmojiPicker() {
+ emojiPicker.on('emoji', emoji => {
+ if (this.state.commentForm.content == null) {
+ this.state.commentForm.content = '';
+ }
+ let shortName = `:${emojiShortName[emoji]}:`;
+ this.state.commentForm.content += shortName;
+ this.setState(this.state);
+ });
+ }
+
handleFinished() {
this.state.previewMode = false;
this.state.loading = false;
@@ -242,6 +266,10 @@ export class CommentForm extends Component {
i.setState(i.state);
}
+ handleEmojiPickerClick(_i: CommentForm, event: any) {
+ emojiPicker.togglePicker(event.target);
+ }
+
handleCommentContentChange(i: CommentForm, event: any) {
i.state.commentForm.content = event.target.value;
i.setState(i.state);
diff --git a/ui/src/components/post-form.tsx b/ui/src/components/post-form.tsx
index 47920b9b4..a65ead462 100644
--- a/ui/src/components/post-form.tsx
+++ b/ui/src/components/post-form.tsx
@@ -34,9 +34,11 @@ import {
randomStr,
setupTribute,
setupTippy,
+ emojiPicker,
} from '../utils';
import autosize from 'autosize';
import Tribute from 'tributejs/src/Tribute.js';
+import emojiShortName from 'emoji-short-name';
import Selectr from 'mobius1-selectr';
import { i18n } from '../i18next';
@@ -92,6 +94,8 @@ export class PostForm extends Component {
this.fetchPageTitle = debounce(this.fetchPageTitle).bind(this);
this.tribute = setupTribute();
+ this.setupEmojiPicker();
+
this.state = this.emptyState;
if (this.props.post) {
@@ -191,7 +195,7 @@ export class PostForm extends Component {
@@ -294,13 +298,22 @@ export class PostForm extends Component {
+
+
+
+
+
{!this.props.post && (
@@ -369,6 +382,17 @@ export class PostForm extends Component {
);
}
+ setupEmojiPicker() {
+ emojiPicker.on('emoji', emoji => {
+ if (this.state.postForm.body == null) {
+ this.state.postForm.body = '';
+ }
+ let shortName = `:${emojiShortName[emoji]}:`;
+ this.state.postForm.body += shortName;
+ this.setState(this.state);
+ });
+ }
+
handlePostSubmit(i: PostForm, event: any) {
event.preventDefault();
if (i.props.post) {
@@ -512,6 +536,10 @@ export class PostForm extends Component {
});
}
+ handleEmojiPickerClick(_i: PostForm, event: any) {
+ emojiPicker.togglePicker(event.target);
+ }
+
parseMessage(msg: WebSocketJsonResponse) {
let res = wsJsonToRes(msg);
if (msg.error) {
diff --git a/ui/src/components/symbols.tsx b/ui/src/components/symbols.tsx
index dae734a80..4925257be 100644
--- a/ui/src/components/symbols.tsx
+++ b/ui/src/components/symbols.tsx
@@ -15,6 +15,9 @@ export class Symbols extends Component {
xmlnsXlink="http://www.w3.org/1999/xlink"
>
+
+
+
diff --git a/ui/src/utils.ts b/ui/src/utils.ts
index ceb05764d..fd23bf9ea 100644
--- a/ui/src/utils.ts
+++ b/ui/src/utils.ts
@@ -43,6 +43,7 @@ import twemoji from 'twemoji';
import emojiShortName from 'emoji-short-name';
import Toastify from 'toastify-js';
import tippy from 'tippy.js';
+import EmojiButton from '@joeattardi/emoji-button';
export const repoUrl = 'https://github.com/LemmyNet/lemmy';
export const helpGuideUrl = '/docs/about_guide.html';
@@ -88,6 +89,14 @@ export const themes = [
'i386',
];
+export const emojiPicker = new EmojiButton({
+ // Use the emojiShortName from native
+ // style: 'twemoji',
+ theme: 'dark',
+ position: 'auto-start',
+ // TODO i18n
+});
+
export function randomStr() {
return Math.random()
.toString(36)
@@ -473,8 +482,9 @@ export function setupTribute(): Tribute {
{
trigger: ':',
menuItemTemplate: (item: any) => {
- let emoji = `:${item.original.key}:`;
- return `${item.original.val} ${emoji}`;
+ let shortName = `:${item.original.key}:`;
+ let twemojiIcon = twemoji.parse(item.original.val);
+ return `${twemojiIcon} ${shortName}`;
},
selectTemplate: (item: any) => {
return `:${item.original.key}:`;
diff --git a/ui/translations/en.json b/ui/translations/en.json
index 0281aaf4b..1b29db553 100644
--- a/ui/translations/en.json
+++ b/ui/translations/en.json
@@ -251,5 +251,6 @@
"couldnt_update_private_message": "Couldn't update private message.",
"time": "Time",
"action": "Action",
+ "emoji_picker": "Emoji Picker",
"block_leaving": "Are you sure you want to leave?"
}
diff --git a/ui/yarn.lock b/ui/yarn.lock
index 8d75052b9..eb88b8af0 100644
--- a/ui/yarn.lock
+++ b/ui/yarn.lock
@@ -126,6 +126,51 @@
lodash "^4.17.13"
to-fast-properties "^2.0.0"
+"@fortawesome/fontawesome-common-types@^0.2.28":
+ version "0.2.28"
+ resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.28.tgz#1091bdfe63b3f139441e9cba27aa022bff97d8b2"
+ integrity sha512-gtis2/5yLdfI6n0ia0jH7NJs5i/Z/8M/ZbQL6jXQhCthEOe5Cr5NcQPhgTvFxNOtURE03/ZqUcEskdn2M+QaBg==
+
+"@fortawesome/fontawesome-svg-core@^1.2.22":
+ version "1.2.28"
+ resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.28.tgz#e5b8c8814ef375f01f5d7c132d3c3a2f83a3abf9"
+ integrity sha512-4LeaNHWvrneoU0i8b5RTOJHKx7E+y7jYejplR7uSVB34+mp3Veg7cbKk7NBCLiI4TyoWS1wh9ZdoyLJR8wSAdg==
+ dependencies:
+ "@fortawesome/fontawesome-common-types" "^0.2.28"
+
+"@fortawesome/free-regular-svg-icons@^5.10.2":
+ version "5.13.0"
+ resolved "https://registry.yarnpkg.com/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-5.13.0.tgz#925a13d8bdda0678f71551828cac80ab47b8150c"
+ integrity sha512-70FAyiS5j+ANYD4dh9NGowTorNDnyvQHHpCM7FpnF7GxtDjBUCKdrFqCPzesEIpNDFNd+La3vex+jDk4nnUfpA==
+ dependencies:
+ "@fortawesome/fontawesome-common-types" "^0.2.28"
+
+"@fortawesome/free-solid-svg-icons@^5.10.2":
+ version "5.13.0"
+ resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.13.0.tgz#44d9118668ad96b4fd5c9434a43efc5903525739"
+ integrity sha512-IHUgDJdomv6YtG4p3zl1B5wWf9ffinHIvebqQOmV3U+3SLw4fC+LUCCgwfETkbTtjy5/Qws2VoVf6z/ETQpFpg==
+ dependencies:
+ "@fortawesome/fontawesome-common-types" "^0.2.28"
+
+"@joeattardi/emoji-button@^2.12.1":
+ version "2.12.1"
+ resolved "https://registry.yarnpkg.com/@joeattardi/emoji-button/-/emoji-button-2.12.1.tgz#190df7c00721e04742ed6f8852db828798a4cf98"
+ integrity sha512-rUuCXIcv4mRFK2IUKarYJN6J667wtH234smb1aQILzRf3/ycOoa6yUwnnvjxZeXMsPhuTnz15ndMOP2DhO5nNw==
+ dependencies:
+ "@fortawesome/fontawesome-svg-core" "^1.2.22"
+ "@fortawesome/free-regular-svg-icons" "^5.10.2"
+ "@fortawesome/free-solid-svg-icons" "^5.10.2"
+ "@popperjs/core" "^2.0.0"
+ focus-trap "^5.1.0"
+ tiny-emitter "^2.1.0"
+ tslib "^1.10.0"
+ twemoji "^12.1.5"
+
+"@popperjs/core@^2.0.0":
+ version "2.2.3"
+ resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.2.3.tgz#0ae22b5650ab0b8fe508047245b66e71fc59e983"
+ integrity sha512-68EQPzEZRrpFavFX40V2+80eqzQIhgza2AGTXW+i8laxSA4It+Y13rmZInrAYoIujp8YO7YJPbvgOesDZcIulQ==
+
"@popperjs/core@^2.1.1":
version "2.1.1"
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.1.1.tgz#12c572ab88ef7345b43f21883fca26631c223085"
@@ -1829,6 +1874,14 @@ fliplog@^0.3.13:
dependencies:
chain-able "^1.0.1"
+focus-trap@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/focus-trap/-/focus-trap-5.1.0.tgz#64a0bfabd95c382103397dbc96bfef3a3cf8e5ad"
+ integrity sha512-CkB/nrO55069QAUjWFBpX6oc+9V90Qhgpe6fBWApzruMq5gnlh90Oo7iSSDK7pKiV5ugG6OY2AXM5mxcmL3lwQ==
+ dependencies:
+ tabbable "^4.0.0"
+ xtend "^4.0.1"
+
for-in@^1.0.1, for-in@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
@@ -4473,6 +4526,11 @@ symbol-observable@^1.1.0:
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==
+tabbable@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-4.0.0.tgz#5bff1d1135df1482cf0f0206434f15eadbeb9261"
+ integrity sha512-H1XoH1URcBOa/rZZWxLxHCtOdVUEev+9vo5YdYhC9tCY4wnybX+VQrCYuy9ubkg69fCBxCONJOSLGfw0DWMffQ==
+
table@^5.2.3:
version "5.4.6"
resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e"
@@ -4502,6 +4560,11 @@ through@^2.3.6:
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
+tiny-emitter@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423"
+ integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==
+
tiny-invariant@^1.0.2:
version "1.1.0"
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.1.0.tgz#634c5f8efdc27714b7f386c35e6760991d230875"
@@ -4609,6 +4672,11 @@ ts-transform-inferno@^4.0.2:
resolved "https://registry.yarnpkg.com/ts-transform-inferno/-/ts-transform-inferno-4.0.2.tgz#06b9be45edf874ba7a6ebfb6107ba782509c6afe"
integrity sha512-CZb4+w/2l2zikPZ/c51fi3n+qnR2HCEfAS73oGQB80aqRLffkZqm25kYYTMmqUW2+oVfs4M5AZa0z14cvxlQ5w==
+tslib@^1.10.0:
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35"
+ integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==
+
tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a"
@@ -4638,7 +4706,7 @@ twemoji-parser@12.1.3:
resolved "https://registry.yarnpkg.com/twemoji-parser/-/twemoji-parser-12.1.3.tgz#916c0153e77bd5f1011e7a99cbeacf52e43c9371"
integrity sha512-ND4LZXF4X92/PFrzSgGkq6KPPg8swy/U0yRw1k/+izWRVmq1HYi3khPwV3XIB6FRudgVICAaBhJfW8e8G3HC7Q==
-twemoji@^12.1.2:
+twemoji@^12.1.2, twemoji@^12.1.5:
version "12.1.5"
resolved "https://registry.yarnpkg.com/twemoji/-/twemoji-12.1.5.tgz#a961fb65a1afcb1f729ad7e59391f9fe969820b9"
integrity sha512-B0PBVy5xomwb1M/WZxf/IqPZfnoIYy1skXnlHjMwLwTNfZ9ljh8VgWQktAPcJXu8080WoEh6YwQGPVhDVqvrVQ==
@@ -4890,6 +4958,11 @@ xregexp@^4.3.0:
dependencies:
"@babel/runtime-corejs3" "^7.8.3"
+xtend@^4.0.1:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
+ integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
+
yaml@^1.7.2:
version "1.7.2"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.7.2.tgz#f26aabf738590ab61efaca502358e48dc9f348b2"
From 56281ffda2a0db408151610fc96235d87cf5811e Mon Sep 17 00:00:00 2001
From: Dessalines
Date: Sun, 12 Apr 2020 12:54:49 -0400
Subject: [PATCH 17/24] Add open collective (#637)
* Add Emoji Picker for comments and post body.
- Fixes #634
* Make sure typing dropdown uses twemojis.
* Adding opencollective links. Fixes #636
---
README.md | 3 ++-
ui/src/components/sponsors.tsx | 6 ++++++
ui/translations/en.json | 1 +
3 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index d576e5be7..723d535ff 100644
--- a/README.md
+++ b/README.md
@@ -108,8 +108,9 @@ Each lemmy server can set its own moderation policy; appointing site-wide admins
Lemmy is free, open-source software, meaning no advertising, monetizing, or venture capital, ever. Your donations directly support full-time development of the project.
-- [Support on Liberapay.](https://liberapay.com/Lemmy)
+- [Support on Liberapay](https://liberapay.com/Lemmy).
- [Support on Patreon](https://www.patreon.com/dessalines).
+- [Support on OpenCollective](https://opencollective.com/lemmy).
- [List of Sponsors](https://dev.lemmy.ml/sponsors).
### Crypto
diff --git a/ui/src/components/sponsors.tsx b/ui/src/components/sponsors.tsx
index 643153e68..71f309caa 100644
--- a/ui/src/components/sponsors.tsx
+++ b/ui/src/components/sponsors.tsx
@@ -57,6 +57,12 @@ export class Sponsors extends Component {
>
{i18n.t('support_on_patreon')}
+
+ {i18n.t('support_on_open_collective')}
+
);
}
diff --git a/ui/translations/en.json b/ui/translations/en.json
index 1b29db553..7e4702aee 100644
--- a/ui/translations/en.json
+++ b/ui/translations/en.json
@@ -187,6 +187,7 @@
"Lemmy is free, <1>open-source1> software, meaning no advertising, monetizing, or venture capital, ever. Your donations directly support full-time development of the project. Thank you to the following people:",
"support_on_patreon": "Support on Patreon",
"support_on_liberapay": "Support on Liberapay",
+ "support_on_open_collective": "Support on OpenCollective",
"donate_to_lemmy": "Donate to Lemmy",
"donate": "Donate",
"general_sponsors":
From cadd94e954eaa3ed03ea4eed3014199017d0887f Mon Sep 17 00:00:00 2001
From: Dessalines
Date: Sun, 12 Apr 2020 14:07:22 -0400
Subject: [PATCH 18/24] Updating federation docker volumes ignores.
---
.dockerignore | 2 +-
.gitignore | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/.dockerignore b/.dockerignore
index d7177be49..a29cd2ec2 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -2,5 +2,5 @@ ui/node_modules
ui/dist
server/target
docker/dev/volumes
-docker/federation-test/volumes
+docker/federation/volumes
.git
diff --git a/.gitignore b/.gitignore
index 9f7fa1e3c..7aeaa31b7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,4 +7,4 @@ build/
.idea/
ui/src/translations
docker/dev/volumes
-docker/federation-test/volumes
+docker/federation/volumes
From 9b329d42f7cb3dc7e3f4ac7988a58121e86f0d36 Mon Sep 17 00:00:00 2001
From: Dessalines
Date: Sun, 12 Apr 2020 14:08:02 -0400
Subject: [PATCH 19/24] Version v0.6.48
---
ansible/VERSION | 2 +-
docker/prod/docker-compose.yml | 2 +-
server/src/version.rs | 2 +-
ui/src/version.ts | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/ansible/VERSION b/ansible/VERSION
index 48861fee4..45e4cb8e0 100644
--- a/ansible/VERSION
+++ b/ansible/VERSION
@@ -1 +1 @@
-v0.6.45
+v0.6.48
diff --git a/docker/prod/docker-compose.yml b/docker/prod/docker-compose.yml
index 325effa65..115b1b887 100644
--- a/docker/prod/docker-compose.yml
+++ b/docker/prod/docker-compose.yml
@@ -12,7 +12,7 @@ services:
restart: always
lemmy:
- image: dessalines/lemmy:v0.6.45
+ image: dessalines/lemmy:v0.6.48
ports:
- "127.0.0.1:8536:8536"
restart: always
diff --git a/server/src/version.rs b/server/src/version.rs
index c2717a78e..f455236d8 100644
--- a/server/src/version.rs
+++ b/server/src/version.rs
@@ -1 +1 @@
-pub const VERSION: &str = "v0.6.45";
+pub const VERSION: &str = "v0.6.48";
diff --git a/ui/src/version.ts b/ui/src/version.ts
index f0847f757..27616cb2a 100644
--- a/ui/src/version.ts
+++ b/ui/src/version.ts
@@ -1 +1 @@
-export const version: string = 'v0.6.45';
+export const version: string = 'v0.6.48';
From 2adf8a8eb2a7ea559e46abf11c184eb3951d86b4 Mon Sep 17 00:00:00 2001
From: Dessalines
Date: Sun, 12 Apr 2020 14:55:52 -0400
Subject: [PATCH 20/24] Use twemoji style for emoji picker.
---
ui/src/components/comment-form.tsx | 7 +++++--
ui/src/components/post-form.tsx | 7 +++++--
ui/src/utils.ts | 2 +-
3 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/ui/src/components/comment-form.tsx b/ui/src/components/comment-form.tsx
index 6898ebc79..5239eb2c7 100644
--- a/ui/src/components/comment-form.tsx
+++ b/ui/src/components/comment-form.tsx
@@ -230,11 +230,14 @@ export class CommentForm extends Component {
}
setupEmojiPicker() {
- emojiPicker.on('emoji', emoji => {
+ emojiPicker.on('emoji', twemojiHtmlStr => {
if (this.state.commentForm.content == null) {
this.state.commentForm.content = '';
}
- let shortName = `:${emojiShortName[emoji]}:`;
+ var el = document.createElement('div');
+ el.innerHTML = twemojiHtmlStr;
+ let nativeUnicode = (el.childNodes[0] as HTMLElement).getAttribute('alt');
+ let shortName = `:${emojiShortName[nativeUnicode]}:`;
this.state.commentForm.content += shortName;
this.setState(this.state);
});
diff --git a/ui/src/components/post-form.tsx b/ui/src/components/post-form.tsx
index a65ead462..912d8e589 100644
--- a/ui/src/components/post-form.tsx
+++ b/ui/src/components/post-form.tsx
@@ -383,11 +383,14 @@ export class PostForm extends Component {
}
setupEmojiPicker() {
- emojiPicker.on('emoji', emoji => {
+ emojiPicker.on('emoji', twemojiHtmlStr => {
if (this.state.postForm.body == null) {
this.state.postForm.body = '';
}
- let shortName = `:${emojiShortName[emoji]}:`;
+ var el = document.createElement('div');
+ el.innerHTML = twemojiHtmlStr;
+ let nativeUnicode = (el.childNodes[0] as HTMLElement).getAttribute('alt');
+ let shortName = `:${emojiShortName[nativeUnicode]}:`;
this.state.postForm.body += shortName;
this.setState(this.state);
});
diff --git a/ui/src/utils.ts b/ui/src/utils.ts
index fd23bf9ea..21a7fef83 100644
--- a/ui/src/utils.ts
+++ b/ui/src/utils.ts
@@ -91,7 +91,7 @@ export const themes = [
export const emojiPicker = new EmojiButton({
// Use the emojiShortName from native
- // style: 'twemoji',
+ style: 'twemoji',
theme: 'dark',
position: 'auto-start',
// TODO i18n
From ec5471aaec798708c212e4867e5acd0d5ce2331a Mon Sep 17 00:00:00 2001
From: Dessalines
Date: Sun, 12 Apr 2020 14:57:37 -0400
Subject: [PATCH 21/24] Version v0.6.49
---
ansible/VERSION | 2 +-
docker/prod/docker-compose.yml | 2 +-
server/src/version.rs | 2 +-
ui/src/version.ts | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/ansible/VERSION b/ansible/VERSION
index 45e4cb8e0..25690dbe8 100644
--- a/ansible/VERSION
+++ b/ansible/VERSION
@@ -1 +1 @@
-v0.6.48
+v0.6.49
diff --git a/docker/prod/docker-compose.yml b/docker/prod/docker-compose.yml
index 115b1b887..727b7307b 100644
--- a/docker/prod/docker-compose.yml
+++ b/docker/prod/docker-compose.yml
@@ -12,7 +12,7 @@ services:
restart: always
lemmy:
- image: dessalines/lemmy:v0.6.48
+ image: dessalines/lemmy:v0.6.49
ports:
- "127.0.0.1:8536:8536"
restart: always
diff --git a/server/src/version.rs b/server/src/version.rs
index f455236d8..f02e9ae5f 100644
--- a/server/src/version.rs
+++ b/server/src/version.rs
@@ -1 +1 @@
-pub const VERSION: &str = "v0.6.48";
+pub const VERSION: &str = "v0.6.49";
diff --git a/ui/src/version.ts b/ui/src/version.ts
index 27616cb2a..8a3563532 100644
--- a/ui/src/version.ts
+++ b/ui/src/version.ts
@@ -1 +1 @@
-export const version: string = 'v0.6.48';
+export const version: string = 'v0.6.49';
From 7cc70d0977ed4caa45d82e83a6ea8cc2cc3aec6d Mon Sep 17 00:00:00 2001
From: Dessalines
Date: Mon, 13 Apr 2020 12:42:16 -0400
Subject: [PATCH 22/24] Adding another sponsor.
---
ui/src/components/sponsors.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ui/src/components/sponsors.tsx b/ui/src/components/sponsors.tsx
index 71f309caa..cd7e14c5b 100644
--- a/ui/src/components/sponsors.tsx
+++ b/ui/src/components/sponsors.tsx
@@ -5,9 +5,9 @@ import { T } from 'inferno-i18next';
import { repoUrl } from '../utils';
let general = [
+ 'alexx henry',
'Nathan J. Goode',
'Andre Vallestero',
- 'riccardo',
'NotTooHighToHack',
];
let highlighted = ['Alex Benishek'];
From f6c0e7072d14e9d369d250853053ff8b486b708f Mon Sep 17 00:00:00 2001
From: Dessalines
Date: Tue, 14 Apr 2020 10:07:40 -0400
Subject: [PATCH 23/24] Fixing test deploy.
---
docker/dev/dev_deploy.sh | 12 ------------
docker/dev/test_deploy.sh | 11 +++++++++++
2 files changed, 11 insertions(+), 12 deletions(-)
delete mode 100755 docker/dev/dev_deploy.sh
create mode 100755 docker/dev/test_deploy.sh
diff --git a/docker/dev/dev_deploy.sh b/docker/dev/dev_deploy.sh
deleted file mode 100755
index ef41434b3..000000000
--- a/docker/dev/dev_deploy.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/sh
-
-# Building from the dev branch for dev servers
-git checkout dev
-
-# Rebuilding dev docker
-docker-compose build
-docker tag dev_lemmy:latest dessalines/lemmy:dev
-docker push dessalines/lemmy:dev
-
-# SSH and pull it
-ssh $LEMMY_USER@$LEMMY_HOST "cd ~/git/lemmy/docker/dev && docker pull dessalines/lemmy:dev && docker-compose up -d"
diff --git a/docker/dev/test_deploy.sh b/docker/dev/test_deploy.sh
new file mode 100755
index 000000000..1ae91f654
--- /dev/null
+++ b/docker/dev/test_deploy.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+# Rebuilding dev docker
+docker-compose build
+docker tag dev_lemmy:latest dessalines/lemmy:test
+docker push dessalines/lemmy:test
+
+# Run the playbook
+pushd ../../../lemmy-ansible
+ansible-playbook -i test playbooks/site.yml --vault-password-file vault_pass
+popd
From 2246d4e05334433c8eebd9e5dae746f512884ec1 Mon Sep 17 00:00:00 2001
From: Dessalines
Date: Tue, 14 Apr 2020 12:34:52 -0400
Subject: [PATCH 24/24] Updating front end packages.
---
ui/package.json | 34 ++++-----
ui/yarn.lock | 191 +++++++++++++++++++++++++++---------------------
2 files changed, 123 insertions(+), 102 deletions(-)
diff --git a/ui/package.json b/ui/package.json
index 25ee2e00d..21458f0d2 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -16,18 +16,18 @@
"dependencies": {
"@joeattardi/emoji-button": "^2.12.1",
"@types/autosize": "^3.0.6",
- "@types/js-cookie": "^2.2.5",
+ "@types/js-cookie": "^2.2.6",
"@types/jwt-decode": "^2.2.1",
- "@types/markdown-it": "^0.0.9",
+ "@types/markdown-it": "^10.0.0",
"@types/markdown-it-container": "^2.0.2",
- "@types/node": "^13.9.2",
+ "@types/node": "^13.11.1",
"autosize": "^4.0.2",
"bootswatch": "^4.3.1",
- "classcat": "^1.1.3",
+ "classcat": "^4.0.2",
"dotenv": "^8.2.0",
"emoji-short-name": "^1.0.0",
- "husky": "^4.2.3",
- "i18next": "^19.3.3",
+ "husky": "^4.2.5",
+ "i18next": "^19.4.1",
"inferno": "^7.4.2",
"inferno-i18next": "nimbusec-oss/inferno-i18next",
"inferno-router": "^7.4.2",
@@ -38,26 +38,26 @@
"markdown-it-emoji": "^1.4.0",
"mobius1-selectr": "^2.4.13",
"moment": "^2.24.0",
- "prettier": "^1.18.2",
+ "prettier": "^2.0.4",
"reconnecting-websocket": "^4.4.0",
- "rxjs": "^6.4.0",
- "terser": "^4.6.7",
- "tippy.js": "^6.1.0",
+ "rxjs": "^6.5.5",
+ "terser": "^4.6.11",
+ "tippy.js": "^6.1.1",
"toastify-js": "^1.7.0",
- "tributejs": "^5.1.2",
+ "tributejs": "^5.1.3",
"twemoji": "^12.1.2",
"ws": "^7.2.3"
},
"devDependencies": {
"eslint": "^6.5.1",
"eslint-plugin-inferno": "^7.14.3",
- "eslint-plugin-jane": "^7.2.0",
+ "eslint-plugin-jane": "^7.2.1",
"fuse-box": "^3.1.3",
- "lint-staged": "^10.0.8",
- "sortpack": "^2.1.2",
- "ts-node": "^8.7.0",
- "ts-transform-classcat": "^0.0.2",
- "ts-transform-inferno": "^4.0.2",
+ "lint-staged": "^10.1.3",
+ "sortpack": "^2.1.4",
+ "ts-node": "^8.8.2",
+ "ts-transform-classcat": "^1.0.0",
+ "ts-transform-inferno": "^4.0.3",
"typescript": "^3.8.3"
},
"engines": {
diff --git a/ui/yarn.lock b/ui/yarn.lock
index eb88b8af0..35ad32a0a 100644
--- a/ui/yarn.lock
+++ b/ui/yarn.lock
@@ -171,10 +171,10 @@
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.2.3.tgz#0ae22b5650ab0b8fe508047245b66e71fc59e983"
integrity sha512-68EQPzEZRrpFavFX40V2+80eqzQIhgza2AGTXW+i8laxSA4It+Y13rmZInrAYoIujp8YO7YJPbvgOesDZcIulQ==
-"@popperjs/core@^2.1.1":
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.1.1.tgz#12c572ab88ef7345b43f21883fca26631c223085"
- integrity sha512-sLqWxCzC5/QHLhziXSCAksBxHfOnQlhPRVgPK0egEw+ktWvG75T2k+aYWVjVh9+WKeT3tlG3ZNbZQvZLmfuOIw==
+"@popperjs/core@^2.2.0":
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.3.2.tgz#1e56eb99bccddbda6a3e29aa4f3660f5b23edc43"
+ integrity sha512-18Tz3QghwsuHUC4gTNoxcEw1ClsrJ+lRypYpm+aucQonYNnmskQYvDZZKLHMPvQ7OwthWJl715UEX+Tg2fJkJw==
"@samverschueren/stream-to-observable@^0.3.0":
version "0.3.0"
@@ -207,10 +207,10 @@
dependencies:
"@types/sizzle" "*"
-"@types/js-cookie@^2.2.5":
- version "2.2.5"
- resolved "https://registry.yarnpkg.com/@types/js-cookie/-/js-cookie-2.2.5.tgz#38dfaacae8623b37cc0b0d27398e574e3fc28b1e"
- integrity sha512-cpmwBRcHJmmZx0OGU7aPVwGWGbs4iKwVYchk9iuMtxNCA2zorwdaTz4GkLgs2WGxiRZRFKnV1k6tRUHX7tBMxg==
+"@types/js-cookie@^2.2.6":
+ version "2.2.6"
+ resolved "https://registry.yarnpkg.com/@types/js-cookie/-/js-cookie-2.2.6.tgz#f1a1cb35aff47bc5cfb05cb0c441ca91e914c26f"
+ integrity sha512-+oY0FDTO2GYKEV0YPvSshGq9t7YozVkgvXLty7zogQNuCxBhT9/3INX9Q7H1aRZ4SUDRXAKlJuA4EA5nTt7SNw==
"@types/json-schema@^7.0.3":
version "7.0.4"
@@ -234,17 +234,30 @@
dependencies:
"@types/markdown-it" "*"
-"@types/markdown-it@*", "@types/markdown-it@^0.0.9":
+"@types/markdown-it@*":
version "0.0.9"
resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-0.0.9.tgz#a5d552f95216c478e0a27a5acc1b28dcffd989ce"
integrity sha512-IFSepyZXbF4dgSvsk8EsgaQ/8Msv1I5eTL0BZ0X3iGO9jw6tCVtPG8HchIPm3wrkmGdqZOD42kE0zplVi1gYDA==
dependencies:
"@types/linkify-it" "*"
-"@types/node@^13.9.2":
- version "13.9.2"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.2.tgz#ace1880c03594cc3e80206d96847157d8e7fa349"
- integrity sha512-bnoqK579sAYrQbp73wwglccjJ4sfRdKU7WNEZ5FW4K2U6Kc0/eZ5kvXG0JKsEKFB50zrFmfFt52/cvBbZa7eXg==
+"@types/markdown-it@^10.0.0":
+ version "10.0.0"
+ resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-10.0.0.tgz#a2b5f9fb444bb27c1e0c4a0116fea09b3c6ebc1e"
+ integrity sha512-7UPBg1W0rfsqQ1JwNFfhxibKO0t7Q0scNt96XcFIFLGE/vhZamzZayaFS2LKha/26Pz7b/2GgiaxQZ1GUwW0dA==
+ dependencies:
+ "@types/linkify-it" "*"
+ "@types/mdurl" "*"
+
+"@types/mdurl@*":
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-1.0.2.tgz#e2ce9d83a613bacf284c7be7d491945e39e1f8e9"
+ integrity sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==
+
+"@types/node@^13.11.1":
+ version "13.11.1"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-13.11.1.tgz#49a2a83df9d26daacead30d0ccc8762b128d53c7"
+ integrity sha512-eWQGP3qtxwL8FGneRrC5DwrJLGN4/dH1clNTuLfN81HCrxVtxRjygDTUoZJ5ASlDEeo0ppYFQjQIlXhtXpOn6g==
"@types/normalize-package-data@^2.4.0":
version "2.4.0"
@@ -794,6 +807,14 @@ chalk@^3.0.0:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
+chalk@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.0.0.tgz#6e98081ed2d17faab615eb52ac66ec1fe6209e72"
+ integrity sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==
+ dependencies:
+ ansi-styles "^4.1.0"
+ supports-color "^7.1.0"
+
chardet@^0.4.0:
version "0.4.2"
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2"
@@ -835,10 +856,10 @@ class-utils@^0.3.5:
isobject "^3.0.0"
static-extend "^0.1.1"
-classcat@^1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/classcat/-/classcat-1.1.3.tgz#ec748eecd962ec195a5d8f73f01d67c3d9040912"
- integrity sha512-nuf6HJ5RlEgUUPqN/giIy1wsfA0LJwCHpo/aMGMwEIAxYypbLW/ZdPH4SNrF+OwdrkL3wxJmAs4GPyoE3ZkQ4w==
+classcat@^4.0.2:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/classcat/-/classcat-4.0.2.tgz#bd5d51b656e01e9cdd21c1aae3d29ed035a52126"
+ integrity sha512-RlMPOPp8VDu3CJOUVorPumhz/CI+t9ft6f0uexxxCguk28/M+Kf27eQXjNWeDTisEQWei/30oDfITOQqr1TNpQ==
clean-css@^4.1.9:
version "4.2.3"
@@ -935,10 +956,10 @@ commander@^4.0.1:
resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.0.tgz#545983a0603fe425bc672d66c9e3c89c42121a83"
integrity sha512-NIQrwvv9V39FHgGFm36+U9SMQzbiHvU79k+iADraJTpmrFFfx7Ds0IvDoAdZsDrknlkRk14OYoWXb57uTh7/sw==
-compare-versions@^3.5.1:
- version "3.5.1"
- resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.5.1.tgz#26e1f5cf0d48a77eced5046b9f67b6b61075a393"
- integrity sha512-9fGPIB7C6AyM18CJJBHt5EnCZDG3oiTJYy0NjfIAGjKpzv0tkxWko7TNQHF5ymqm7IH03tqmeuBxtvD+Izh6mg==
+compare-versions@^3.6.0:
+ version "3.6.0"
+ resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.6.0.tgz#1a5689913685e5a87637b8d3ffca75514ec41d62"
+ integrity sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==
component-emitter@^1.2.1:
version "1.3.0"
@@ -1328,10 +1349,10 @@ eslint-plugin-inferno@^7.14.3:
object.values "^1.1.0"
resolve "^1.12.0"
-eslint-plugin-jane@^7.2.0:
- version "7.2.0"
- resolved "https://registry.yarnpkg.com/eslint-plugin-jane/-/eslint-plugin-jane-7.2.0.tgz#a2454a6700c644e6c86821ca294adf303e75eddc"
- integrity sha512-/BPZrfxWX9T45gJSf4/2GHfBYgsBYTW7StAQfxL8PxWABZIQKWPWy/5ZokX7UaJlgKHAoC42rJHCQLK5hmfJNA==
+eslint-plugin-jane@^7.2.1:
+ version "7.2.1"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-jane/-/eslint-plugin-jane-7.2.1.tgz#5ffba9ce75e0a5e5dbe3918fc0c5332d2cd89c13"
+ integrity sha512-hUmhEkHTDq6lQ4oLWZV5cLut9L67fcTiy0USbTsEOx658i9Jdikedt8NJhtamRqO5OUHBGSPU0JkOqBtVNUD+A==
dependencies:
"@typescript-eslint/eslint-plugin" "2.24.0"
"@typescript-eslint/parser" "2.24.0"
@@ -1345,7 +1366,7 @@ eslint-plugin-jane@^7.2.0:
eslint-plugin-prettier "3.1.2"
eslint-plugin-promise "4.2.1"
eslint-plugin-react "7.19.0"
- eslint-plugin-react-hooks "2.5.0"
+ eslint-plugin-react-hooks "2.5.1"
eslint-plugin-unicorn "17.2.0"
eslint-plugin-jest@23.8.2:
@@ -1394,10 +1415,10 @@ eslint-plugin-promise@4.2.1:
resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz#845fd8b2260ad8f82564c1222fce44ad71d9418a"
integrity sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==
-eslint-plugin-react-hooks@2.5.0:
- version "2.5.0"
- resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-2.5.0.tgz#c50ab7ca5945ce6d1cf8248d9e185c80b54171b6"
- integrity sha512-bzvdX47Jx847bgAYf0FPX3u1oxU+mKU8tqrpj4UX9A96SbAmj/HVEefEy6rJUog5u8QIlOPTKZcBpGn5kkKfAQ==
+eslint-plugin-react-hooks@2.5.1:
+ version "2.5.1"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-2.5.1.tgz#4ef5930592588ce171abeb26f400c7fbcbc23cd0"
+ integrity sha512-Y2c4b55R+6ZzwtTppKwSmK/Kar8AdLiC2f9NADCuxbcTgPPg41Gyqa6b9GppgXSvCtkRw43ZE86CT5sejKC6/g==
eslint-plugin-react@7.19.0:
version "7.19.0"
@@ -2235,14 +2256,14 @@ human-signals@^1.1.1:
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3"
integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==
-husky@^4.2.3:
- version "4.2.3"
- resolved "https://registry.yarnpkg.com/husky/-/husky-4.2.3.tgz#3b18d2ee5febe99e27f2983500202daffbc3151e"
- integrity sha512-VxTsSTRwYveKXN4SaH1/FefRJYCtx+wx04sSVcOpD7N2zjoHxa+cEJ07Qg5NmV3HAK+IRKOyNVpi2YBIVccIfQ==
+husky@^4.2.5:
+ version "4.2.5"
+ resolved "https://registry.yarnpkg.com/husky/-/husky-4.2.5.tgz#2b4f7622673a71579f901d9885ed448394b5fa36"
+ integrity sha512-SYZ95AjKcX7goYVZtVZF2i6XiZcHknw50iXvY7b0MiGoj5RwdgRQNEHdb+gPDPCXKlzwrybjFjkL6FOj8uRhZQ==
dependencies:
- chalk "^3.0.0"
+ chalk "^4.0.0"
ci-info "^2.0.0"
- compare-versions "^3.5.1"
+ compare-versions "^3.6.0"
cosmiconfig "^6.0.0"
find-versions "^3.2.0"
opencollective-postinstall "^2.0.2"
@@ -2251,10 +2272,10 @@ husky@^4.2.3:
slash "^3.0.0"
which-pm-runs "^1.0.0"
-i18next@^19.3.3:
- version "19.3.3"
- resolved "https://registry.yarnpkg.com/i18next/-/i18next-19.3.3.tgz#04bd79b315e5fe2c87ab8f411e5d55eda0a17bd8"
- integrity sha512-CnuPqep5/JsltkGvQqzYN4d79eCe0TreCBRF3a8qHHi8x4SON1qqZ/pvR2X7BfNkNqpA5HXIqw0E731H+VsgSg==
+i18next@^19.4.1:
+ version "19.4.1"
+ resolved "https://registry.yarnpkg.com/i18next/-/i18next-19.4.1.tgz#4929d15d3d01e4712350a368d005cefa50ff5455"
+ integrity sha512-dC3ue15jkLebN2je4xEjfjVYd/fSAo+UVK9f+JxvceCJRowkI+S0lGohgKejqU+FYLfvw9IAPylIIEWwR8Djrg==
dependencies:
"@babel/runtime" "^7.3.1"
@@ -2867,10 +2888,10 @@ linkify-it@^2.0.0:
dependencies:
uc.micro "^1.0.1"
-lint-staged@^10.0.8:
- version "10.0.8"
- resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-10.0.8.tgz#0f7849cdc336061f25f5d4fcbcfa385701ff4739"
- integrity sha512-Oa9eS4DJqvQMVdywXfEor6F4vP+21fPHF8LUXgBbVWUSWBddjqsvO6Bv1LwMChmgQZZqwUvgJSHlu8HFHAPZmA==
+lint-staged@^10.1.3:
+ version "10.1.3"
+ resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-10.1.3.tgz#da27713d3ac519da305381b4de87d5f866b1d2f1"
+ integrity sha512-o2OkLxgVns5RwSC5QF7waeAjJA5nz5gnUfqL311LkZcFipKV7TztrSlhNUK5nQX9H0E5NELAdduMQ+M/JPT7RQ==
dependencies:
chalk "^3.0.0"
commander "^4.0.1"
@@ -3665,10 +3686,10 @@ prettier-linter-helpers@^1.0.0:
dependencies:
fast-diff "^1.1.2"
-prettier@^1.18.2:
- version "1.19.1"
- resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb"
- integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==
+prettier@^2.0.4:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.4.tgz#2d1bae173e355996ee355ec9830a7a1ee05457ef"
+ integrity sha512-SVJIQ51spzFDvh4fIbCLvciiDMCrRhlN3mbZvv/+ycjvmF5E73bKdGfU8QDLNmjYJf+lsGnDBC4UUnvTe5OO0w==
pretty-time@^0.2.0:
version "0.2.0"
@@ -4054,13 +4075,20 @@ rx-lite@*, rx-lite@^4.0.8:
resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444"
integrity sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=
-rxjs@^6.3.3, rxjs@^6.4.0, rxjs@^6.5.3:
+rxjs@^6.3.3, rxjs@^6.5.3:
version "6.5.4"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.4.tgz#e0777fe0d184cec7872df147f303572d414e211c"
integrity sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==
dependencies:
tslib "^1.9.0"
+rxjs@^6.5.5:
+ version "6.5.5"
+ resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.5.tgz#c5c884e3094c8cfee31bf27eb87e54ccfc87f9ec"
+ integrity sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==
+ dependencies:
+ tslib "^1.9.0"
+
safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.2"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
@@ -4250,10 +4278,10 @@ snapdragon@^0.8.1:
source-map-resolve "^0.5.0"
use "^3.1.0"
-sortpack@^2.1.2:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/sortpack/-/sortpack-2.1.2.tgz#25bf86f2923c81f43a00a2166ff4d271fafeed11"
- integrity sha512-43fSND1vmAdyfgC38aOkVxZBV331f4blF8acjwQmx7Gba4nuL2ene/Cq5eixNmDhKA/qQHnvSeAl+jEWb31rfg==
+sortpack@^2.1.4:
+ version "2.1.4"
+ resolved "https://registry.yarnpkg.com/sortpack/-/sortpack-2.1.4.tgz#a2e251c5868455135cc41d3c98a53756a6de5282"
+ integrity sha512-RGD0l9kGmuPelXMT8WMMiSv1MkUkaqElB39nMkboIaqVkYns1aaNx263B2EE5QzF1YVUOrBlXnQpd7RX68SSow==
source-map-resolve@^0.5.0:
version "0.5.3"
@@ -4541,10 +4569,10 @@ table@^5.2.3:
slice-ansi "^2.1.0"
string-width "^3.0.0"
-terser@^4.6.7:
- version "4.6.7"
- resolved "https://registry.yarnpkg.com/terser/-/terser-4.6.7.tgz#478d7f9394ec1907f0e488c5f6a6a9a2bad55e72"
- integrity sha512-fmr7M1f7DBly5cX2+rFDvmGBAaaZyPrHYK4mMdHEDAdNTqXSZgSOfqsfGq2HqPGT/1V0foZZuCZFx8CHKgAk3g==
+terser@^4.6.11:
+ version "4.6.11"
+ resolved "https://registry.yarnpkg.com/terser/-/terser-4.6.11.tgz#12ff99fdd62a26de2a82f508515407eb6ccd8a9f"
+ integrity sha512-76Ynm7OXUG5xhOpblhytE7X58oeNSmC8xnNhjWVo8CksHit0U0kO4hfNbPrrYwowLWFgM2n9L176VNx2QaHmtA==
dependencies:
commander "^2.20.0"
source-map "~0.6.1"
@@ -4575,12 +4603,12 @@ tiny-warning@^1.0.0:
resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
-tippy.js@^6.1.0:
- version "6.1.0"
- resolved "https://registry.yarnpkg.com/tippy.js/-/tippy.js-6.1.0.tgz#9c58b94f92f3044d5e861b9d83da3c2a6d3d4323"
- integrity sha512-cRFydlVZlvo4soQSUfVNbH2K77zDUhDAzaAjxseyn81gGIa+j72y98yDL2yB0n8gas/E+Zlr1iOyR5ckslUFqA==
+tippy.js@^6.1.1:
+ version "6.1.1"
+ resolved "https://registry.yarnpkg.com/tippy.js/-/tippy.js-6.1.1.tgz#9ed09aa4f9c47fb06a0e280e03055f898f5ddfff"
+ integrity sha512-Sk+FPihack9XFbPOc2jRbn6iRLA9my2a8qhaGY6wwD3EeW57/xY5PAPkZOutKVYDWLyNZ/laCkJqg7QJG/gqQw==
dependencies:
- "@popperjs/core" "^2.1.1"
+ "@popperjs/core" "^2.2.0"
tmp@^0.0.33:
version "0.0.33"
@@ -4644,15 +4672,15 @@ tough-cookie@~2.4.3:
psl "^1.1.24"
punycode "^1.4.1"
-tributejs@^5.1.2:
- version "5.1.2"
- resolved "https://registry.yarnpkg.com/tributejs/-/tributejs-5.1.2.tgz#d8492d974d3098d6016248d689fb063cda6e77f7"
- integrity sha512-R9ff/q6w4T5f3Y9+RL+qinog3X1eAj1UnR/yfZaGJ8D3wuJs4/vicrGYul9+fgS9EJ/iYgwARekTb92xwark0g==
+tributejs@^5.1.3:
+ version "5.1.3"
+ resolved "https://registry.yarnpkg.com/tributejs/-/tributejs-5.1.3.tgz#980600fc72865be5868893078b4bfde721129eae"
+ integrity sha512-B5CXihaVzXw+1UHhNFyAwUTMDk1EfoLP5Tj1VhD9yybZ1I8DZJEv8tZ1l0RJo0t0tk9ZhR8eG5tEsaCvRigmdQ==
-ts-node@^8.7.0:
- version "8.7.0"
- resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.7.0.tgz#266186947596bef9f3a034687595b30e31b20976"
- integrity sha512-s659CsHrsxaRVDEleuOkGvbsA0rWHtszUNEt1r0CgAFN5ZZTQtDzpsluS7W5pOGJIa1xZE8R/zK4dEs+ldFezg==
+ts-node@^8.8.2:
+ version "8.8.2"
+ resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.8.2.tgz#0b39e690bee39ea5111513a9d2bcdc0bc121755f"
+ integrity sha512-duVj6BpSpUpD/oM4MfhO98ozgkp3Gt9qIp3jGxwU2DFvl/3IRaEAvbLa8G60uS7C77457e/m5TMowjedeRxI1Q==
dependencies:
arg "^4.1.0"
diff "^4.0.1"
@@ -4660,17 +4688,15 @@ ts-node@^8.7.0:
source-map-support "^0.5.6"
yn "3.1.1"
-ts-transform-classcat@^0.0.2:
- version "0.0.2"
- resolved "https://registry.yarnpkg.com/ts-transform-classcat/-/ts-transform-classcat-0.0.2.tgz#2386c9418f3a7c1f03261ff51225b70d0a7664fb"
- integrity sha512-7laOOhgVxWVqvhK10mIEfedJx2nnNOS8J4P/6a/ehXtHFvsBVRRS9/FcTifgzJweOScZsF5BRD5VOGeNidMSqQ==
- dependencies:
- typescript "^2.6.2"
+ts-transform-classcat@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/ts-transform-classcat/-/ts-transform-classcat-1.0.0.tgz#6ae1be1b32f1f3c6b1c4232daf8a28e3ced0b62f"
+ integrity sha512-LWXEYvBwHDOqBBtoDWSUmbPMsw8FI9vD4XZm98RgziN9UCIj5MRtpmXuP5YYoimCTlPU+D4TFR3IqS+5xSzWsQ==
-ts-transform-inferno@^4.0.2:
- version "4.0.2"
- resolved "https://registry.yarnpkg.com/ts-transform-inferno/-/ts-transform-inferno-4.0.2.tgz#06b9be45edf874ba7a6ebfb6107ba782509c6afe"
- integrity sha512-CZb4+w/2l2zikPZ/c51fi3n+qnR2HCEfAS73oGQB80aqRLffkZqm25kYYTMmqUW2+oVfs4M5AZa0z14cvxlQ5w==
+ts-transform-inferno@^4.0.3:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/ts-transform-inferno/-/ts-transform-inferno-4.0.3.tgz#2cc0eb125abdaff24b8298106a618ab7c6319edc"
+ integrity sha512-Pcg0PVQwJ7Fpv4+3R9obFNsrNKQyLbmUqsjeG7T7r4/4UTgIl0MSwurexjtuGpCp2iv2X/i9ffKPAfAOyYJ9og==
tslib@^1.10.0:
version "1.11.1"
@@ -4741,11 +4767,6 @@ type-is@~1.6.17, type-is@~1.6.18:
media-typer "0.3.0"
mime-types "~2.1.24"
-typescript@^2.6.2:
- version "2.9.2"
- resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.9.2.tgz#1cbf61d05d6b96269244eb6a3bce4bd914e0f00c"
- integrity sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==
-
typescript@^3.8.3:
version "3.8.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061"