- { 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'
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
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;
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
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
iframely:
image: dogbin/iframely:latest
+ ports:
+ - "127.0.0.1:8061:80"
volumes:
- ../iframely.config.local.js:/iframely/config.local.js:ro
restart: always
} from '../interfaces';
import {
wsJsonToRes,
- pictshareAvatarThumbnail,
+ pictrsAvatarThumbnail,
showAvatars,
fetchLimit,
isCommentType,
<span>
{UserService.Instance.user.avatar && showAvatars() && (
<img
- src={pictshareAvatarThumbnail(
+ src={pictrsAvatarThumbnail(
UserService.Instance.user.avatar
)}
height="32"
requestNotificationPermission() {
if (UserService.Instance.user) {
- document.addEventListener('DOMContentLoaded', function() {
+ document.addEventListener('DOMContentLoaded', function () {
if (!Notification) {
toast(i18n.t('notifications_error'), 'danger');
return;
const imageUploadUrl = `/pictrs/image`;
const formData = new FormData();
- formData.append('images', file);
+ formData.append('images[]', file);
i.state.imageLoading = true;
i.setState(i.state);
})
.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;
isImage,
isVideo,
getUnixTime,
- pictshareImage,
+ pictrsImage,
setupTippy,
previewLines,
} from '../utils';
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);
}
}
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';
<img
height="32"
width="32"
- src={pictshareAvatarThumbnail(
+ src={pictrsAvatarThumbnail(
this.mine
? message.recipient_avatar
: message.creator_avatar
}
>
<svg
- class={`icon icon-inline ${message.read &&
- 'text-success'}`}
+ class={`icon icon-inline ${
+ message.read && 'text-success'
+ }`}
>
<use xlinkHref="#icon-check"></use>
</svg>
}
>
<svg
- class={`icon icon-inline ${message.deleted &&
- 'text-danger'}`}
+ class={`icon icon-inline ${
+ message.deleted && 'text-danger'
+ }`}
>
<use xlinkHref="#icon-trash"></use>
</svg>
data-tippy-content={i18n.t('view_source')}
>
<svg
- class={`icon icon-inline ${this.state.viewSource &&
- 'text-success'}`}
+ class={`icon icon-inline ${
+ this.state.viewSource && 'text-success'
+ }`}
>
<use xlinkHref="#icon-file-text"></use>
</svg>
fetchLimit,
routeSearchTypeToEnum,
routeSortTypeToEnum,
- pictshareAvatarThumbnail,
+ pictrsAvatarThumbnail,
showAvatars,
toast,
createCommentLikeRes,
import {
mdToHtml,
getUnixTime,
- pictshareAvatarThumbnail,
+ pictrsAvatarThumbnail,
showAvatars,
} from '../utils';
import { CommunityForm } from './community-form';
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;
<img
height="32"
width="32"
- src={pictshareAvatarThumbnail(user.avatar)}
+ src={pictrsAvatarThumbnail(user.avatar)}
class="rounded-circle mr-2"
/>
)}
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);
})
.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;
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;
}
}
// 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;
}