From e583e45d9a2221b3ed2a743cfa172abcd2a1d6a0 Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Mon, 8 Jun 2020 19:52:32 +0200 Subject: [PATCH 01/68] Use pictrs instead of pictshare --- ansible/ansible.cfg | 1 + ansible/lemmy.yml | 10 +++--- ansible/lemmy_dev.yml | 7 ++-- ansible/templates/docker-compose.yml | 13 +++---- ansible/templates/nginx.conf | 8 ++--- docker/dev/docker-compose.yml | 52 ++++++++++++++++------------ docker/dev/nginx.conf | 40 +++++++++++++++++++++ ui/src/components/comment-form.tsx | 4 +-- ui/src/components/post-form.tsx | 6 ++-- ui/src/components/user.tsx | 4 +-- 10 files changed, 94 insertions(+), 51 deletions(-) create mode 100644 docker/dev/nginx.conf diff --git a/ansible/ansible.cfg b/ansible/ansible.cfg index 960a7c40fd5..74b6ab2f195 100644 --- a/ansible/ansible.cfg +++ b/ansible/ansible.cfg @@ -1,5 +1,6 @@ [defaults] inventory=inventory +interpreter_python=/usr/bin/python3 [ssh_connection] pipelining = True diff --git a/ansible/lemmy.yml b/ansible/lemmy.yml index bc01623fc55..dcafc5eac4f 100644 --- a/ansible/lemmy.yml +++ b/ansible/lemmy.yml @@ -24,10 +24,11 @@ creates: '/etc/letsencrypt/live/{{domain}}/privkey.pem' - name: create lemmy folder - file: path={{item.path}} state=directory + file: path={{item.path}} {{item.owner}} state=directory with_items: - - { path: '/lemmy/' } - - { path: '/lemmy/volumes/' } + - { path: '/lemmy/', owner: 'root' } + - { path: '/lemmy/volumes/', owner: 'root' } + - { path: '/lemmy/volumes/pictrs/', owner: '991' } - block: - name: add template files @@ -38,9 +39,6 @@ - { src: '../docker/iframely.config.local.js', dest: '/lemmy/iframely.config.local.js', mode: '0600' } vars: lemmy_docker_image: "dessalines/lemmy:{{ lookup('file', 'VERSION') }}" - lemmy_port: "8536" - pictshare_port: "8537" - iframely_port: "8538" - name: add config file (only during initial setup) template: src='templates/config.hjson' dest='/lemmy/lemmy.hjson' mode='0600' force='no' owner='1000' group='1000' diff --git a/ansible/lemmy_dev.yml b/ansible/lemmy_dev.yml index e9b8364f386..05eb1ffed19 100644 --- a/ansible/lemmy_dev.yml +++ b/ansible/lemmy_dev.yml @@ -26,10 +26,11 @@ creates: '/etc/letsencrypt/live/{{domain}}/privkey.pem' - name: create lemmy folder - file: path={{item.path}} state=directory + file: path={{item.path}} owner={{item.owner}} state=directory with_items: - - { path: '/lemmy/' } - - { path: '/lemmy/volumes/' } + - { path: '/lemmy/', owner: 'root' } + - { path: '/lemmy/volumes/', owner: 'root' } + - { path: '/lemmy/volumes/pictrs/', owner: '991' } - block: - name: add template files diff --git a/ansible/templates/docker-compose.yml b/ansible/templates/docker-compose.yml index 9ec1bfbc22d..0b33399bde1 100644 --- a/ansible/templates/docker-compose.yml +++ b/ansible/templates/docker-compose.yml @@ -12,7 +12,7 @@ services: - ./lemmy.hjson:/config/config.hjson:ro depends_on: - postgres - - pictshare + - pictrs - iframely postgres: @@ -25,18 +25,19 @@ services: - ./volumes/postgres:/var/lib/postgresql/data restart: always - pictshare: - image: hascheksolutions/pictshare:latest + pictrs: + image: asonix/pictrs:amd64-v0.1.0-r9 + user: 991:991 ports: - - "127.0.0.1:8537:80" + - "127.0.0.1:8537:8080" volumes: - - ./volumes/pictshare:/usr/share/nginx/html/data + - ./volumes/pictrs:/mnt restart: always iframely: image: dogbin/iframely:latest ports: - - "127.0.0.1:8061:80" + - "127.0.0.1:8538:80" volumes: - ./iframely.config.local.js:/iframely/config.local.js:ro restart: always diff --git a/ansible/templates/nginx.conf b/ansible/templates/nginx.conf index a978c18999a..b96bbce7ffa 100644 --- a/ansible/templates/nginx.conf +++ b/ansible/templates/nginx.conf @@ -70,19 +70,15 @@ server { proxy_cache_min_uses 5; } - location /pictshare/ { + location /pictrs/ { proxy_pass http://0.0.0.0:8537/; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - - if ($request_uri ~ \.(?:ico|gif|jpe?g|png|webp|bmp|mp4)$) { - add_header Cache-Control "public, max-age=31536000, immutable"; - } } location /iframely/ { - proxy_pass http://0.0.0.0:8061/; + proxy_pass http://0.0.0.0:8538/; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; diff --git a/docker/dev/docker-compose.yml b/docker/dev/docker-compose.yml index 1702f66d3ff..6c0624c4bfc 100644 --- a/docker/dev/docker-compose.yml +++ b/docker/dev/docker-compose.yml @@ -1,6 +1,31 @@ version: '3.3' services: + nginx: + image: nginx:1.19-alpine + ports: + - "8536:8536" + volumes: + - ./nginx.conf:/etc/nginx/nginx.conf + depends_on: + - lemmy + - pictrs + - iframely + restart: "always" + + lemmy: + build: + context: ../../ + dockerfile: docker/dev/Dockerfile + restart: always + environment: + - RUST_LOG=debug + volumes: + - ../lemmy.hjson:/config/config.hjson + depends_on: + - postgres + - iframely + postgres: image: postgres:12-alpine environment: @@ -11,34 +36,15 @@ services: - ./volumes/postgres:/var/lib/postgresql/data restart: always - lemmy: - build: - context: ../../ - dockerfile: docker/dev/Dockerfile - ports: - - "127.0.0.1:8536:8536" - restart: always - environment: - - RUST_LOG=debug + pictrs: + image: asonix/pictrs:amd64-v0.1.0-r9 + user: 991:991 volumes: - - ../lemmy.hjson:/config/config.hjson - depends_on: - - postgres - - pictshare - - iframely - - pictshare: - image: hascheksolutions/pictshare:latest - ports: - - "127.0.0.1:8537:80" - volumes: - - ./volumes/pictshare:/usr/share/nginx/html/data + - ./volumes/pictrs:/mnt restart: always iframely: image: dogbin/iframely:latest - ports: - - "127.0.0.1:8061:80" volumes: - ../iframely.config.local.js:/iframely/config.local.js:ro restart: always diff --git a/docker/dev/nginx.conf b/docker/dev/nginx.conf new file mode 100644 index 00000000000..3e4ff510e1c --- /dev/null +++ b/docker/dev/nginx.conf @@ -0,0 +1,40 @@ +events { + worker_connections 1024; +} + +http { + server { + listen 8536; + server_name 127.0.0.1; + #access_log off; + + # Upload limit for pictshare + client_max_body_size 50M; + + location / { + proxy_pass http://lemmy:8536; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + # WebSocket support + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } + + location /pictrs/ { + proxy_pass http://pictrs:8080/; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + + location /iframely/ { + proxy_pass http://iframely:80/; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + } +} diff --git a/ui/src/components/comment-form.tsx b/ui/src/components/comment-form.tsx index 5239eb2c7a1..7abab752420 100644 --- a/ui/src/components/comment-form.tsx +++ b/ui/src/components/comment-form.tsx @@ -304,7 +304,7 @@ export class CommentForm extends Component { file = event; } - const imageUploadUrl = `/pictshare/api/upload.php`; + const imageUploadUrl = `/pictrs/image`; const formData = new FormData(); formData.append('file', file); @@ -317,7 +317,7 @@ export class CommentForm extends Component { }) .then(res => res.json()) .then(res => { - let url = `${window.location.origin}/pictshare/${res.url}`; + let url = `${window.location.origin}/pictrs/${res.url}`; let imageMarkdown = res.filetype == 'mp4' ? `[vid](${url}/raw)` : `![](${url})`; let content = i.state.commentForm.content; diff --git a/ui/src/components/post-form.tsx b/ui/src/components/post-form.tsx index 6f1e34e0141..a9356d05d2c 100644 --- a/ui/src/components/post-form.tsx +++ b/ui/src/components/post-form.tsx @@ -518,9 +518,9 @@ export class PostForm extends Component { file = event; } - const imageUploadUrl = `/pictshare/api/upload.php`; + const imageUploadUrl = `/pictrs/image`; const formData = new FormData(); - formData.append('file', file); + formData.append('images', file); i.state.imageLoading = true; i.setState(i.state); @@ -531,7 +531,7 @@ export class PostForm extends Component { }) .then(res => res.json()) .then(res => { - let url = `${window.location.origin}/pictshare/${encodeURI(res.url)}`; + let url = `${window.location.origin}/pictrs/${encodeURI(res.url)}`; if (res.filetype == 'mp4') { url += '/raw'; } diff --git a/ui/src/components/user.tsx b/ui/src/components/user.tsx index eded9998c53..c3b12fe0230 100644 --- a/ui/src/components/user.tsx +++ b/ui/src/components/user.tsx @@ -988,7 +988,7 @@ export class User extends Component { handleImageUpload(i: User, event: any) { event.preventDefault(); let file = event.target.files[0]; - const imageUploadUrl = `/pictshare/api/upload.php`; + const imageUploadUrl = `/pictrs/image`; const formData = new FormData(); formData.append('file', file); @@ -1001,7 +1001,7 @@ export class User extends Component { }) .then(res => res.json()) .then(res => { - let url = `${window.location.origin}/pictshare/${res.url}`; + let url = `${window.location.origin}/pictrs/${res.url}`; if (res.filetype == 'mp4') { url += '/raw'; } From d8859001a7e0abc3465cf546d1662ce59d8d5cdf Mon Sep 17 00:00:00 2001 From: Ady Nemo Date: Tue, 9 Jun 2020 13:34:11 +0000 Subject: [PATCH 02/68] Translated using Weblate (French) Currently translated at 100.0% (246 of 246 strings) Translation: Lemmy/lemmy Translate-URL: http://weblate.yerbamate.dev/projects/lemmy/lemmy/fr/ --- ui/translations/fr.json | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/ui/translations/fr.json b/ui/translations/fr.json index 82714249806..f7457b2e17f 100644 --- a/ui/translations/fr.json +++ b/ui/translations/fr.json @@ -28,7 +28,7 @@ "community_reqs": "en minuscule, sans espace et avec tiret du bas.", "create_private_message": "Créer un message privé", "send_secure_message": "Envoyer le message sécurisé", - "send_message": "Enovyer le message", + "send_message": "Envoyer le message", "message": "Message", "edit": "éditer", "reply": "répondre", @@ -58,14 +58,14 @@ "remove_as_admin": "Supprimer comme admin", "appoint_as_admin": "Nommer comme admin", "remove": "retirer", - "removed": "retiré", + "removed": "retiré par le modérateur", "locked": "bloqué", "stickied": "épinglé", "reason": "Raison", "mark_as_read": "marquer comme lu", "mark_as_unread": "marquer comme non-lu", "delete": "supprimer", - "deleted": "supprimé", + "deleted": "supprimé par le créateur", "delete_account": "Supprimer le compte", "delete_account_confirm": "Avertissement : cette action supprimera toutes vos données de façons permanente ! Saisissez votre mot de passe pour confirmer.", "restore": "restaurer", @@ -171,7 +171,7 @@ "theme": "Thème", "sponsors": "Sponsors", "sponsors_of_lemmy": "Sponsors de Lemmy", - "sponsor_message": "Lemmy est un logiciel libre et <1>open-source, c’est à dire, il fonctionne sans publicité et sans monétisation aucune. Vos dons soutiennent directement le développement du projet à temps plein. Merci à toutes ces personnes :", + "sponsor_message": "Lemmy est un logiciel libre et <1>open-source, sans jamais aucune publicité, ni monétisation ou capital-risque. Vos dons soutiennent directement le développement du projet à temps plein. Merci à toutes ces personnes :", "support_on_patreon": "Soutenir sur Patreon", "support_on_liberapay": "Soutenir sur Liberapay", "donate_to_lemmy": "Faire un don à Lemmy", @@ -251,5 +251,7 @@ "number_of_downvotes_plural": "{{count}} votes contre", "downvote": "Voter contre", "emoji_picker": "Sélecteur d’émojis", - "silver_sponsors": "Les sponsors argent sont ceux et celles qui ont fait une donation de 40$ à Lemmy." + "silver_sponsors": "Les sponsors argent sont ceux et celles qui ont fait une donation de 40$ à Lemmy.", + "select_a_community": "Sélectionner une communauté", + "invalid_username": "Nom d'utilisateur invalide." } From 7bc601ad3bba8cb63331ae06a3101cf05cc24953 Mon Sep 17 00:00:00 2001 From: maxigaz Date: Tue, 9 Jun 2020 13:34:11 +0000 Subject: [PATCH 03/68] Translated using Weblate (Hungarian) Currently translated at 5.6% (14 of 246 strings) Translation: Lemmy/lemmy Translate-URL: http://weblate.yerbamate.dev/projects/lemmy/lemmy/hu/ Translated using Weblate (Hungarian) Currently translated at 2.4% (6 of 246 strings) Translation: Lemmy/lemmy Translate-URL: http://weblate.yerbamate.dev/projects/lemmy/lemmy/hu/ --- ui/translations/hu.json | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/ui/translations/hu.json b/ui/translations/hu.json index 0967ef424bc..35f826750a7 100644 --- a/ui/translations/hu.json +++ b/ui/translations/hu.json @@ -1 +1,18 @@ -{} +{ + "post": "Elküld", + "remove_post": "Bejegyzés eltávolítása", + "no_posts": "Nincs bejegyzés.", + "create_post": "Új bejegyzés létrehozása", + "create_a_post": "Új bejegyzés létrehozása", + "number_of_posts": "{{count}} bejegyzés", + "number_of_posts_plural": "{{count}} bejegyzés", + "posts": "Bejegyzések", + "related_posts": "Ezek a bejegyzések kapcsolódhatnak", + "cross_posts": "Ez a hivatkozás itt is be lett küldve:", + "cross_post": "keresztbejegyzés", + "comments": "Hozzászólások", + "remove_comment": "Hozzászólások eltávolítása", + "cross_posted_to": "beküldve ide is: ", + "number_of_comments": "{{count}} hozzászólás", + "number_of_comments_plural": "{{count}} hozzászólás" +} From bd26e4e9c1b146163ee839de0a45bb9354efd1f2 Mon Sep 17 00:00:00 2001 From: Dessalines Date: Tue, 9 Jun 2020 17:17:24 -0400 Subject: [PATCH 04/68] Fixing some front end pictshare to pictrs conversions. --- ansible/lemmy.yml | 3 +++ ansible/templates/docker-compose.yml | 2 +- ansible/templates/nginx.conf | 6 +++++- docker/dev/docker-compose.yml | 19 +++++++------------ ui/src/components/navbar.tsx | 6 +++--- ui/src/components/post-form.tsx | 20 +++++++++++++------- ui/src/components/post-listing.tsx | 10 +++++----- ui/src/components/private-message.tsx | 24 +++++++++++------------- ui/src/components/search.tsx | 2 +- ui/src/components/sidebar.tsx | 2 +- ui/src/components/user-listing.tsx | 4 ++-- ui/src/components/user.tsx | 21 +++++++++++++-------- ui/src/utils.ts | 25 ++++++++++++------------- 13 files changed, 77 insertions(+), 67 deletions(-) diff --git a/ansible/lemmy.yml b/ansible/lemmy.yml index dcafc5eac4f..0b49856aca8 100644 --- a/ansible/lemmy.yml +++ b/ansible/lemmy.yml @@ -39,6 +39,9 @@ - { src: '../docker/iframely.config.local.js', dest: '/lemmy/iframely.config.local.js', mode: '0600' } vars: lemmy_docker_image: "dessalines/lemmy:{{ lookup('file', 'VERSION') }}" + lemmy_port: "8536" + pictshare_port: "8537" + iframely_port: "8538" - name: add config file (only during initial setup) template: src='templates/config.hjson' dest='/lemmy/lemmy.hjson' mode='0600' force='no' owner='1000' group='1000' diff --git a/ansible/templates/docker-compose.yml b/ansible/templates/docker-compose.yml index 0b33399bde1..f4c94fd71db 100644 --- a/ansible/templates/docker-compose.yml +++ b/ansible/templates/docker-compose.yml @@ -37,7 +37,7 @@ services: iframely: image: dogbin/iframely:latest ports: - - "127.0.0.1:8538:80" + - "127.0.0.1:8061:80" volumes: - ./iframely.config.local.js:/iframely/config.local.js:ro restart: always diff --git a/ansible/templates/nginx.conf b/ansible/templates/nginx.conf index b96bbce7ffa..68fa64fc5fa 100644 --- a/ansible/templates/nginx.conf +++ b/ansible/templates/nginx.conf @@ -75,10 +75,14 @@ server { proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + if ($request_uri ~ \.(?:ico|gif|jpe?g|png|webp|bmp|mp4)$) { + add_header Cache-Control "public, max-age=31536000, immutable"; + } } location /iframely/ { - proxy_pass http://0.0.0.0:8538/; + proxy_pass http://0.0.0.0:8061/; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; diff --git a/docker/dev/docker-compose.yml b/docker/dev/docker-compose.yml index 6c0624c4bfc..60b04beb86f 100644 --- a/docker/dev/docker-compose.yml +++ b/docker/dev/docker-compose.yml @@ -1,22 +1,13 @@ version: '3.3' services: - nginx: - image: nginx:1.19-alpine - ports: - - "8536:8536" - volumes: - - ./nginx.conf:/etc/nginx/nginx.conf - depends_on: - - lemmy - - pictrs - - iframely - restart: "always" lemmy: build: context: ../../ dockerfile: docker/dev/Dockerfile + ports: + - "127.0.0.1:8536:8536" restart: always environment: - RUST_LOG=debug @@ -37,7 +28,9 @@ services: restart: always pictrs: - image: asonix/pictrs:amd64-v0.1.0-r9 + image: asonix/pictrs:v0.1.0-r13 + ports: + - "127.0.0.1:8537:8080" user: 991:991 volumes: - ./volumes/pictrs:/mnt @@ -45,6 +38,8 @@ services: iframely: image: dogbin/iframely:latest + ports: + - "127.0.0.1:8061:80" volumes: - ../iframely.config.local.js:/iframely/config.local.js:ro restart: always diff --git a/ui/src/components/navbar.tsx b/ui/src/components/navbar.tsx index e0d8aff50ad..4cb74391b73 100644 --- a/ui/src/components/navbar.tsx +++ b/ui/src/components/navbar.tsx @@ -22,7 +22,7 @@ import { } from '../interfaces'; import { wsJsonToRes, - pictshareAvatarThumbnail, + pictrsAvatarThumbnail, showAvatars, fetchLimit, isCommentType, @@ -218,7 +218,7 @@ export class Navbar extends Component { {UserService.Instance.user.avatar && showAvatars() && ( { requestNotificationPermission() { if (UserService.Instance.user) { - document.addEventListener('DOMContentLoaded', function() { + document.addEventListener('DOMContentLoaded', function () { if (!Notification) { toast(i18n.t('notifications_error'), 'danger'); return; diff --git a/ui/src/components/post-form.tsx b/ui/src/components/post-form.tsx index a9356d05d2c..7811f9180f5 100644 --- a/ui/src/components/post-form.tsx +++ b/ui/src/components/post-form.tsx @@ -520,7 +520,7 @@ export class PostForm extends Component { const imageUploadUrl = `/pictrs/image`; const formData = new FormData(); - formData.append('images', file); + formData.append('images[]', file); i.state.imageLoading = true; i.setState(i.state); @@ -531,13 +531,19 @@ export class PostForm extends Component { }) .then(res => res.json()) .then(res => { - let url = `${window.location.origin}/pictrs/${encodeURI(res.url)}`; - if (res.filetype == 'mp4') { - url += '/raw'; + console.log('pictrs upload:'); + console.log(res); + if (res.msg == 'ok') { + let hash = res.files[0].file; + let url = `${window.location.origin}/pictrs/image/${hash}`; + i.state.postForm.url = url; + i.state.imageLoading = false; + i.setState(i.state); + } else { + i.state.imageLoading = false; + i.setState(i.state); + toast(JSON.stringify(res), 'danger'); } - i.state.postForm.url = url; - i.state.imageLoading = false; - i.setState(i.state); }) .catch(error => { i.state.imageLoading = false; diff --git a/ui/src/components/post-listing.tsx b/ui/src/components/post-listing.tsx index 36a1e2828dc..7d10acf7213 100644 --- a/ui/src/components/post-listing.tsx +++ b/ui/src/components/post-listing.tsx @@ -28,7 +28,7 @@ import { isImage, isVideo, getUnixTime, - pictshareImage, + pictrsImage, setupTippy, previewLines, } from '../utils'; @@ -161,15 +161,15 @@ export class PostListing extends Component { getImage(thumbnail: boolean = false) { let post = this.props.post; if (isImage(post.url)) { - if (post.url.includes('pictshare')) { - return pictshareImage(post.url, thumbnail); + if (post.url.includes('pictrs')) { + return pictrsImage(post.url, thumbnail); } else if (post.thumbnail_url) { - return pictshareImage(post.thumbnail_url, thumbnail); + return pictrsImage(post.thumbnail_url, thumbnail); } else { return post.url; } } else if (post.thumbnail_url) { - return pictshareImage(post.thumbnail_url, thumbnail); + return pictrsImage(post.thumbnail_url, thumbnail); } } diff --git a/ui/src/components/private-message.tsx b/ui/src/components/private-message.tsx index 337b1650120..71924f0cbab 100644 --- a/ui/src/components/private-message.tsx +++ b/ui/src/components/private-message.tsx @@ -5,12 +5,7 @@ import { EditPrivateMessageForm, } from '../interfaces'; import { WebSocketService, UserService } from '../services'; -import { - mdToHtml, - pictshareAvatarThumbnail, - showAvatars, - toast, -} from '../utils'; +import { mdToHtml, pictrsAvatarThumbnail, showAvatars, toast } from '../utils'; import { MomentTime } from './moment-time'; import { PrivateMessageForm } from './private-message-form'; import { i18n } from '../i18next'; @@ -78,7 +73,7 @@ export class PrivateMessage extends Component< @@ -188,8 +184,9 @@ export class PrivateMessage extends Component< } > @@ -204,8 +201,9 @@ export class PrivateMessage extends Component< data-tippy-content={i18n.t('view_source')} > diff --git a/ui/src/components/search.tsx b/ui/src/components/search.tsx index b9662fae3ab..c32f4f2fbb7 100644 --- a/ui/src/components/search.tsx +++ b/ui/src/components/search.tsx @@ -22,7 +22,7 @@ import { fetchLimit, routeSearchTypeToEnum, routeSortTypeToEnum, - pictshareAvatarThumbnail, + pictrsAvatarThumbnail, showAvatars, toast, createCommentLikeRes, diff --git a/ui/src/components/sidebar.tsx b/ui/src/components/sidebar.tsx index fce31561000..b280ef4fbfa 100644 --- a/ui/src/components/sidebar.tsx +++ b/ui/src/components/sidebar.tsx @@ -11,7 +11,7 @@ import { WebSocketService, UserService } from '../services'; import { mdToHtml, getUnixTime, - pictshareAvatarThumbnail, + pictrsAvatarThumbnail, showAvatars, } from '../utils'; import { CommunityForm } from './community-form'; diff --git a/ui/src/components/user-listing.tsx b/ui/src/components/user-listing.tsx index 1f136e006c8..ea87fd3aae7 100644 --- a/ui/src/components/user-listing.tsx +++ b/ui/src/components/user-listing.tsx @@ -1,7 +1,7 @@ import { Component } from 'inferno'; import { Link } from 'inferno-router'; import { UserView } from '../interfaces'; -import { pictshareAvatarThumbnail, showAvatars } from '../utils'; +import { pictrsAvatarThumbnail, showAvatars } from '../utils'; interface UserOther { name: string; @@ -25,7 +25,7 @@ export class UserListing extends Component { )} diff --git a/ui/src/components/user.tsx b/ui/src/components/user.tsx index c3b12fe0230..833366a6e2c 100644 --- a/ui/src/components/user.tsx +++ b/ui/src/components/user.tsx @@ -990,7 +990,7 @@ export class User extends Component { let file = event.target.files[0]; const imageUploadUrl = `/pictrs/image`; const formData = new FormData(); - formData.append('file', file); + formData.append('images[]', file); i.state.avatarLoading = true; i.setState(i.state); @@ -1001,14 +1001,19 @@ export class User extends Component { }) .then(res => res.json()) .then(res => { - let url = `${window.location.origin}/pictrs/${res.url}`; - if (res.filetype == 'mp4') { - url += '/raw'; + console.log('pictrs upload:'); + console.log(res); + if (res.msg == 'ok') { + let hash = res.files[0].file; + let url = `${window.location.origin}/pictrs/image/${hash}`; + i.state.userSettingsForm.avatar = url; + i.state.avatarLoading = false; + i.setState(i.state); + } else { + i.state.avatarLoading = false; + i.setState(i.state); + toast(JSON.stringify(res), 'danger'); } - i.state.userSettingsForm.avatar = url; - console.log(url); - i.state.avatarLoading = false; - i.setState(i.state); }) .catch(error => { i.state.avatarLoading = false; diff --git a/ui/src/utils.ts b/ui/src/utils.ts index 3bad50404cb..2820bc482df 100644 --- a/ui/src/utils.ts +++ b/ui/src/utils.ts @@ -440,10 +440,12 @@ export function objectFlip(obj: any) { return ret; } -export function pictshareAvatarThumbnail(src: string): string { - // sample url: http://localhost:8535/pictshare/gs7xuu.jpg - let split = src.split('pictshare'); - let out = `${split[0]}pictshare/${canUseWebP() ? 'webp/' : ''}96${split[1]}`; +export function pictrsAvatarThumbnail(src: string): string { + // sample url: http://localhost:8535/pictrs/image/thumbnail256/gs7xuu.jpg + let split = src.split('/pictrs/image'); + let out = `${split[0]}/pictrs/image/${ + canUseWebP() ? 'webp/' : '' + }thumbnail96${split[1]}`; return out; } @@ -455,21 +457,18 @@ export function showAvatars(): boolean { } // Converts to image thumbnail -export function pictshareImage( - hash: string, - thumbnail: boolean = false -): string { - let root = `/pictshare`; +export function pictrsImage(hash: string, thumbnail: boolean = false): string { + let root = `/pictrs/image`; // Necessary for other servers / domains - if (hash.includes('pictshare')) { - let split = hash.split('/pictshare/'); - root = `${split[0]}/pictshare`; + if (hash.includes('pictrs')) { + let split = hash.split('/pictrs/image/'); + root = `${split[0]}/pictrs/image`; hash = split[1]; } let out = `${root}/${canUseWebP() ? 'webp/' : ''}${ - thumbnail ? '192/' : '' + thumbnail ? 'thumbnail192/' : '' }${hash}`; return out; } From 2e4c7256476e4d5c79f43c9c86c6c8dc3c6965af Mon Sep 17 00:00:00 2001 From: Dessalines Date: Tue, 9 Jun 2020 22:41:04 -0400 Subject: [PATCH 05/68] Fixing toast background for all but i386. Fixes #794 --- ui/src/utils.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ui/src/utils.ts b/ui/src/utils.ts index cb56ba58102..82900cab61f 100644 --- a/ui/src/utils.ts +++ b/ui/src/utils.ts @@ -481,7 +481,7 @@ export function messageToastify( text: `${body}
${creator}`, avatar: avatar, backgroundColor: backgroundColor, - className: 'text-body', + className: 'text-dark', close: true, gravity: 'top', position: 'right', @@ -868,9 +868,7 @@ function canUseWebP() { if (!!(elem.getContext && elem.getContext('2d'))) { var testString = !(window.mozInnerScreenX == null) ? 'png' : 'webp'; // was able or not to get WebP representation - return ( - elem.toDataURL('image/webp').startsWith('data:image/' + testString) - ); + return elem.toDataURL('image/webp').startsWith('data:image/' + testString); } // very old browser like IE 8, canvas not supported From 46bb3064ed64bee31e8ae3a31a9380bf9fb17f14 Mon Sep 17 00:00:00 2001 From: Dessalines Date: Tue, 9 Jun 2020 22:49:42 -0400 Subject: [PATCH 06/68] Version v0.6.72 --- 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 e31dcbc4276..7fc60200e3a 100644 --- a/ansible/VERSION +++ b/ansible/VERSION @@ -1 +1 @@ -v0.6.71 +v0.6.72 diff --git a/docker/prod/docker-compose.yml b/docker/prod/docker-compose.yml index db6e4004569..8d77356979b 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.71 + image: dessalines/lemmy:v0.6.72 ports: - "127.0.0.1:8536:8536" restart: always diff --git a/server/src/version.rs b/server/src/version.rs index 354b86b40b4..23f0242b11a 100644 --- a/server/src/version.rs +++ b/server/src/version.rs @@ -1 +1 @@ -pub const VERSION: &str = "v0.6.71"; +pub const VERSION: &str = "v0.6.72"; diff --git a/ui/src/version.ts b/ui/src/version.ts index 9abc8bceb5c..d4c3c0452d1 100644 --- a/ui/src/version.ts +++ b/ui/src/version.ts @@ -1 +1 @@ -export const version: string = 'v0.6.71'; +export const version: string = 'v0.6.72'; From 13771d56cd948addc93569dcf7a67d7641bbd747 Mon Sep 17 00:00:00 2001 From: Lorenz Schmidt Date: Wed, 10 Jun 2020 17:11:51 +0200 Subject: [PATCH 07/68] Add default themes with media queries (#796) * Indicate unstable API in README and mdbook * Support user preference for light and dark theme * Add default themes and load them in `setTheme` * Fixes #758 --- ui/src/components/user.tsx | 2 +- ui/src/index.html | 3 ++- ui/src/services/UserService.ts | 4 +--- ui/src/utils.ts | 19 ++++++++++++++----- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/ui/src/components/user.tsx b/ui/src/components/user.tsx index eded9998c53..7cd460a17b9 100644 --- a/ui/src/components/user.tsx +++ b/ui/src/components/user.tsx @@ -922,7 +922,7 @@ export class User extends Component { handleUserSettingsThemeChange(i: User, event: any) { i.state.userSettingsForm.theme = event.target.value; - setTheme(event.target.value); + setTheme(event.target.value, true); i.setState(i.state); } diff --git a/ui/src/index.html b/ui/src/index.html index f39773d02ef..7cea8c4e8db 100644 --- a/ui/src/index.html +++ b/ui/src/index.html @@ -15,7 +15,8 @@ - + + diff --git a/ui/src/services/UserService.ts b/ui/src/services/UserService.ts index 47e28c73e8d..786d5d07ebd 100644 --- a/ui/src/services/UserService.ts +++ b/ui/src/services/UserService.ts @@ -41,9 +41,7 @@ export class UserService { private setUser(jwt: string) { this.user = jwt_decode(jwt); - if (this.user.theme != 'darkly') { - setTheme(this.user.theme); - } + setTheme(this.user.theme, true); this.sub.next({ user: this.user }); console.log(this.user); } diff --git a/ui/src/utils.ts b/ui/src/utils.ts index 81bb014750d..93b9cab08bd 100644 --- a/ui/src/utils.ts +++ b/ui/src/utils.ts @@ -404,7 +404,7 @@ export function getMomentLanguage(): string { return lang; } -export function setTheme(theme: string = 'darkly') { +export function setTheme(theme: string = 'darkly', loggedIn: boolean = false) { // unload all the other themes for (var i = 0; i < themes.length; i++) { let styleSheet = document.getElementById(themes[i]); @@ -413,10 +413,19 @@ export function setTheme(theme: string = 'darkly') { } } - // Load the theme dynamically - let cssLoc = `/static/assets/css/themes/${theme}.min.css`; - loadCss(theme, cssLoc); - document.getElementById(theme).removeAttribute('disabled'); + // if the user is not logged in, we load the default themes and let the browser decide + if(!loggedIn) { + document.getElementById("default-light").removeAttribute('disabled') + document.getElementById("default-dark").removeAttribute('disabled') + } else { + document.getElementById("default-light").setAttribute('disabled', 'disabled'); + document.getElementById("default-dark").setAttribute('disabled', 'disabled'); + + // Load the theme dynamically + let cssLoc = `/static/assets/css/themes/${theme}.min.css`; + loadCss(theme, cssLoc); + document.getElementById(theme).removeAttribute('disabled'); + } } export function loadCss(id: string, loc: string) { From 36e8ce624c86546af9e833a96d9ff645d2450617 Mon Sep 17 00:00:00 2001 From: kartikynwa Date: Wed, 10 Jun 2020 20:42:53 +0530 Subject: [PATCH 08/68] Change "Forgot Password" button's type to "button" (#797) --- ui/src/components/login.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/src/components/login.tsx b/ui/src/components/login.tsx index 84014f68c57..ce04d0d4f98 100644 --- a/ui/src/components/login.tsx +++ b/ui/src/components/login.tsx @@ -111,6 +111,7 @@ export class Login extends Component { required /> {this.state.commentForm.content && ( )} - )} {!this.props.showContext && this.linkBtn} +