Use image thumbnails from pictshare. Fixes #555
This commit is contained in:
parent
aa94f11a2c
commit
fb32acb1ed
4 changed files with 72 additions and 60 deletions
10
ui/assets/css/main.css
vendored
10
ui/assets/css/main.css
vendored
|
@ -188,16 +188,6 @@ hr {
|
|||
border: unset;
|
||||
}
|
||||
|
||||
.img-expand-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding: 2px;
|
||||
background: rgba(0,0,0,.4);
|
||||
border-bottom-left-radius: 0.25rem !important;
|
||||
border-top-right-radius: 0.25rem !important;
|
||||
}
|
||||
|
||||
.link-overlay:hover {
|
||||
transition: .1s;
|
||||
opacity: 1;
|
||||
|
|
4
ui/package.json
vendored
4
ui/package.json
vendored
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"name": "lemmy",
|
||||
"description": "A simple UI for lemmy",
|
||||
"description": "The official Lemmy UI",
|
||||
"version": "1.0.0",
|
||||
"author": "Dessalines",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"build": "node fuse prod",
|
||||
|
|
94
ui/src/components/post-listing.tsx
vendored
94
ui/src/components/post-listing.tsx
vendored
|
@ -51,6 +51,7 @@ interface PostListingState {
|
|||
downvotes: number;
|
||||
url: string;
|
||||
iframely: FramelyData;
|
||||
thumbnail: string;
|
||||
}
|
||||
|
||||
interface PostListingProps {
|
||||
|
@ -80,6 +81,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
downvotes: this.props.post.downvotes,
|
||||
url: this.props.post.url,
|
||||
iframely: null,
|
||||
thumbnail: null,
|
||||
};
|
||||
|
||||
constructor(props: any, context: any) {
|
||||
|
@ -92,6 +94,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
this.handleEditCancel = this.handleEditCancel.bind(this);
|
||||
|
||||
if (this.state.url) {
|
||||
this.setThumbnail();
|
||||
this.fetchIframely();
|
||||
}
|
||||
}
|
||||
|
@ -105,9 +108,11 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
if (nextProps.post.url !== this.state.url) {
|
||||
this.state.url = nextProps.post.url;
|
||||
if (this.state.url) {
|
||||
this.setThumbnail();
|
||||
this.fetchIframely();
|
||||
} else {
|
||||
this.state.iframely = null;
|
||||
this.state.thumbnail = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,6 +137,18 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
);
|
||||
}
|
||||
|
||||
imgThumbnail() {
|
||||
let post = this.props.post;
|
||||
return (
|
||||
<object
|
||||
className={`img-fluid thumbnail rounded ${(post.nsfw ||
|
||||
post.community_nsfw) &&
|
||||
'img-blur'}`}
|
||||
data={imageThumbnailer(this.state.thumbnail)}
|
||||
></object>
|
||||
);
|
||||
}
|
||||
|
||||
listing() {
|
||||
let post = this.props.post;
|
||||
return (
|
||||
|
@ -161,37 +178,32 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
</button>
|
||||
)}
|
||||
</div>
|
||||
{this.hasImage() && !this.state.imageExpanded && (
|
||||
{this.state.thumbnail && !this.state.imageExpanded && (
|
||||
<div class="mx-2 mt-1 float-left position-relative">
|
||||
{isImage(this.state.url) ? (
|
||||
<span
|
||||
class="text-body pointer"
|
||||
title={i18n.t('expand_here')}
|
||||
onClick={linkEvent(this, this.handleImageExpandClick)}
|
||||
>
|
||||
{this.imgThumbnail()}
|
||||
<svg class="icon rounded link-overlay hover-link">
|
||||
<use xlinkHref="#icon-image"></use>
|
||||
</svg>
|
||||
</span>
|
||||
) : (
|
||||
<a
|
||||
className="text-body"
|
||||
href={this.state.url}
|
||||
target="_blank"
|
||||
title={this.state.url}
|
||||
>
|
||||
<object
|
||||
className={`img-fluid thumbnail rounded ${(post.nsfw ||
|
||||
post.community_nsfw) &&
|
||||
'img-blur'}`}
|
||||
data={imageThumbnailer(this.getImage())}
|
||||
>
|
||||
<svg class="icon rounded placeholder">
|
||||
<use xlinkHref="#icon-external-link"></use>
|
||||
</svg>
|
||||
</object>
|
||||
{this.imgThumbnail()}
|
||||
<svg class="icon rounded link-overlay hover-link">
|
||||
<use xlinkHref="#icon-external-link"></use>
|
||||
</svg>
|
||||
</a>
|
||||
<span
|
||||
title={i18n.t('expand_here')}
|
||||
class="pointer"
|
||||
onClick={linkEvent(this, this.handleImageExpandClick)}
|
||||
>
|
||||
<svg class="icon img-expand-overlay">
|
||||
<use xlinkHref="#icon-image"></use>
|
||||
</svg>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{this.state.url && isVideo(this.state.url) && (
|
||||
|
@ -247,7 +259,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
</a>
|
||||
</small>
|
||||
)}
|
||||
{this.hasImage() && (
|
||||
{this.state.thumbnail && (
|
||||
<>
|
||||
{!this.state.imageExpanded ? (
|
||||
<span
|
||||
|
@ -272,7 +284,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
>
|
||||
<object
|
||||
class="img-fluid img-expanded"
|
||||
data={this.getImage()}
|
||||
data={this.state.thumbnail}
|
||||
>
|
||||
<svg class="icon rounded placeholder">
|
||||
<use xlinkHref="#icon-external-link"></use>
|
||||
|
@ -795,29 +807,39 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
.then(res => {
|
||||
this.state.iframely = res;
|
||||
this.setState(this.state);
|
||||
|
||||
// Store and fetch the image in pictshare
|
||||
if (
|
||||
this.state.iframely.thumbnail_url &&
|
||||
isImage(this.state.iframely.thumbnail_url)
|
||||
) {
|
||||
fetch(
|
||||
`/pictshare/api/geturl.php?url=${this.state.iframely.thumbnail_url}`
|
||||
)
|
||||
.then(res => res.json())
|
||||
.then(res => {
|
||||
let url = `${window.location.origin}/pictshare/${res.url}`;
|
||||
if (res.filetype == 'mp4') {
|
||||
url += '/raw';
|
||||
}
|
||||
this.state.thumbnail = url;
|
||||
this.setState(this.state);
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(`Iframely service not set up properly. ${error}`);
|
||||
});
|
||||
}
|
||||
|
||||
hasImage(): boolean {
|
||||
return (
|
||||
(this.state.url && isImage(this.state.url)) ||
|
||||
(this.state.iframely && this.state.iframely.thumbnail_url !== undefined)
|
||||
);
|
||||
}
|
||||
|
||||
getImage(): string {
|
||||
setThumbnail() {
|
||||
let simpleImg = isImage(this.state.url);
|
||||
if (simpleImg) {
|
||||
return this.state.url;
|
||||
} else if (this.state.iframely) {
|
||||
let iframelyThumbnail = this.state.iframely.thumbnail_url;
|
||||
if (iframelyThumbnail) {
|
||||
return iframelyThumbnail;
|
||||
}
|
||||
this.state.thumbnail = this.state.url;
|
||||
} else {
|
||||
this.state.thumbnail = null;
|
||||
}
|
||||
this.setState(this.state);
|
||||
}
|
||||
|
||||
handlePostLike(i: PostListing) {
|
||||
|
|
10
ui/src/utils.ts
vendored
10
ui/src/utils.ts
vendored
|
@ -220,9 +220,9 @@ export function routeSearchTypeToEnum(type: string): SearchType {
|
|||
}
|
||||
|
||||
export async function getPageTitle(url: string) {
|
||||
let res = await fetch(`https://textance.herokuapp.com/title/${url}`);
|
||||
let data = await res.text();
|
||||
return data;
|
||||
let res = await fetch(`/iframely/oembed?url=${url}`).then(res => res.json());
|
||||
let title = await res.title;
|
||||
return title;
|
||||
}
|
||||
|
||||
export function debounce(
|
||||
|
@ -386,7 +386,7 @@ export function objectFlip(obj: any) {
|
|||
export function pictshareAvatarThumbnail(src: string): string {
|
||||
// sample url: http://localhost:8535/pictshare/gs7xuu.jpg
|
||||
let split = src.split('pictshare');
|
||||
let out = `${split[0]}pictshare/96x96${split[1]}`;
|
||||
let out = `${split[0]}pictshare/96${split[1]}`;
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -401,7 +401,7 @@ export function showAvatars(): boolean {
|
|||
export function imageThumbnailer(url: string): string {
|
||||
let split = url.split('pictshare');
|
||||
if (split.length > 1) {
|
||||
let out = `${split[0]}pictshare/192x192${split[1]}`;
|
||||
let out = `${split[0]}pictshare/192${split[1]}`;
|
||||
return out;
|
||||
} else {
|
||||
return url;
|
||||
|
|
Loading…
Reference in a new issue