mirror of
https://github.com/LemmyNet/lemmy-ui.git
synced 2024-11-22 04:11:12 +00:00
Adding opengraph tags. Fixes #5
This commit is contained in:
parent
d909ec8096
commit
89d15c9d09
21 changed files with 246 additions and 165 deletions
|
@ -1,5 +1,4 @@
|
|||
import { Component, linkEvent } from 'inferno';
|
||||
import { Helmet } from 'inferno-helmet';
|
||||
import { Subscription } from 'rxjs';
|
||||
import {
|
||||
UserOperation,
|
||||
|
@ -25,6 +24,7 @@ import {
|
|||
import autosize from 'autosize';
|
||||
import { SiteForm } from './site-form';
|
||||
import { UserListing } from './user-listing';
|
||||
import { HtmlTags } from './html-tags';
|
||||
import { i18n } from '../i18next';
|
||||
|
||||
interface AdminSettingsState {
|
||||
|
@ -97,7 +97,10 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
|
|||
render() {
|
||||
return (
|
||||
<div class="container">
|
||||
<Helmet title={this.documentTitle} />
|
||||
<HtmlTags
|
||||
title={this.documentTitle}
|
||||
path={this.context.router.route.match.url}
|
||||
/>
|
||||
{this.state.loading ? (
|
||||
<h5>
|
||||
<svg class="icon icon-spinner spin">
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { Component } from 'inferno';
|
||||
import { Route, Switch } from 'inferno-router';
|
||||
import { Provider } from 'inferno-i18next';
|
||||
import { Helmet } from 'inferno-helmet';
|
||||
import { i18n } from '../i18next';
|
||||
import { routes } from '../../shared/routes';
|
||||
import { Navbar } from '../../shared/components/navbar';
|
||||
|
@ -23,6 +24,16 @@ export class App extends Component<AppProps, any> {
|
|||
<>
|
||||
<Provider i18next={i18n}>
|
||||
<div>
|
||||
{this.props.site.site.icon && (
|
||||
<Helmet>
|
||||
<link
|
||||
id="favicon"
|
||||
rel="icon"
|
||||
type="image/x-icon"
|
||||
href={this.props.site.site.icon}
|
||||
/>
|
||||
</Helmet>
|
||||
)}
|
||||
<Navbar site={this.props.site} />
|
||||
<div class="mt-4 p-0 fl-1">
|
||||
<Switch>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Component, linkEvent } from 'inferno';
|
||||
import { Helmet } from 'inferno-helmet';
|
||||
import { HtmlTags } from './html-tags';
|
||||
import { Subscription } from 'rxjs';
|
||||
import {
|
||||
UserOperation,
|
||||
|
@ -94,7 +94,10 @@ export class Communities extends Component<any, CommunitiesState> {
|
|||
render() {
|
||||
return (
|
||||
<div class="container">
|
||||
<Helmet title={this.documentTitle} />
|
||||
<HtmlTags
|
||||
title={this.documentTitle}
|
||||
path={this.context.router.route.match.url}
|
||||
/>
|
||||
{this.state.loading ? (
|
||||
<h5 class="">
|
||||
<svg class="icon icon-spinner spin">
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { Component, linkEvent } from 'inferno';
|
||||
import { Helmet } from 'inferno-helmet';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { DataType } from '../interfaces';
|
||||
import {
|
||||
|
@ -27,6 +26,7 @@ import {
|
|||
import { UserService, WebSocketService } from '../services';
|
||||
import { PostListings } from './post-listings';
|
||||
import { CommentNodes } from './comment-nodes';
|
||||
import { HtmlTags } from './html-tags';
|
||||
import { SortSelect } from './sort-select';
|
||||
import { DataTypeSelect } from './data-type-select';
|
||||
import { Sidebar } from './sidebar';
|
||||
|
@ -46,7 +46,6 @@ import {
|
|||
editPostFindRes,
|
||||
commentsToFlatNodes,
|
||||
setupTippy,
|
||||
favIconUrl,
|
||||
notifyPost,
|
||||
setIsoData,
|
||||
wsSubscribe,
|
||||
|
@ -226,30 +225,12 @@ export class Community extends Component<any, State> {
|
|||
}
|
||||
|
||||
get documentTitle(): string {
|
||||
if (this.state.communityRes) {
|
||||
return `${this.state.communityRes.community.title} - ${this.state.siteRes.site.name}`;
|
||||
} else {
|
||||
return 'Lemmy';
|
||||
}
|
||||
}
|
||||
|
||||
get favIcon(): string {
|
||||
return this.state.siteRes.site.icon
|
||||
? this.state.siteRes.site.icon
|
||||
: favIconUrl;
|
||||
return `${this.state.communityRes.community.title} - ${this.state.siteRes.site.name}`;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div class="container">
|
||||
<Helmet title={this.documentTitle}>
|
||||
<link
|
||||
id="favicon"
|
||||
rel="icon"
|
||||
type="image/x-icon"
|
||||
href={this.favIcon}
|
||||
/>
|
||||
</Helmet>
|
||||
{this.state.loading ? (
|
||||
<h5>
|
||||
<svg class="icon icon-spinner spin">
|
||||
|
@ -259,6 +240,12 @@ export class Community extends Component<any, State> {
|
|||
) : (
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-8">
|
||||
<HtmlTags
|
||||
title={this.documentTitle}
|
||||
path={this.context.router.route.match.url}
|
||||
description={this.state.communityRes.community.title}
|
||||
image={this.state.communityRes.community.icon}
|
||||
/>
|
||||
{this.communityInfo()}
|
||||
{this.selects()}
|
||||
{this.listings()}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Component } from 'inferno';
|
||||
import { Helmet } from 'inferno-helmet';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { CommunityForm } from './community-form';
|
||||
import { HtmlTags } from './html-tags';
|
||||
import {
|
||||
Community,
|
||||
UserOperation,
|
||||
|
@ -70,7 +70,10 @@ export class CreateCommunity extends Component<any, CreateCommunityState> {
|
|||
render() {
|
||||
return (
|
||||
<div class="container">
|
||||
<Helmet title={this.documentTitle} />
|
||||
<HtmlTags
|
||||
title={this.documentTitle}
|
||||
path={this.context.router.route.match.url}
|
||||
/>
|
||||
{this.state.loading ? (
|
||||
<h5>
|
||||
<svg class="icon icon-spinner spin">
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Component } from 'inferno';
|
||||
import { Helmet } from 'inferno-helmet';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { PostForm } from './post-form';
|
||||
import { HtmlTags } from './html-tags';
|
||||
import {
|
||||
isBrowser,
|
||||
lemmyHttp,
|
||||
|
@ -82,7 +82,10 @@ export class CreatePost extends Component<any, CreatePostState> {
|
|||
render() {
|
||||
return (
|
||||
<div class="container">
|
||||
<Helmet title={this.documentTitle} />
|
||||
<HtmlTags
|
||||
title={this.documentTitle}
|
||||
path={this.context.router.route.match.url}
|
||||
/>
|
||||
{this.state.loading ? (
|
||||
<h5>
|
||||
<svg class="icon icon-spinner spin">
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Component } from 'inferno';
|
||||
import { Helmet } from 'inferno-helmet';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { PrivateMessageForm } from './private-message-form';
|
||||
import { HtmlTags } from './html-tags';
|
||||
import { UserService, WebSocketService } from '../services';
|
||||
import {
|
||||
Site,
|
||||
|
@ -102,7 +102,10 @@ export class CreatePrivateMessage extends Component<
|
|||
render() {
|
||||
return (
|
||||
<div class="container">
|
||||
<Helmet title={this.documentTitle} />
|
||||
<HtmlTags
|
||||
title={this.documentTitle}
|
||||
path={this.context.router.route.match.url}
|
||||
/>
|
||||
{this.state.loading ? (
|
||||
<h5>
|
||||
<svg class="icon icon-spinner spin">
|
||||
|
|
52
src/shared/components/html-tags.tsx
Normal file
52
src/shared/components/html-tags.tsx
Normal file
|
@ -0,0 +1,52 @@
|
|||
import { Component } from 'inferno';
|
||||
import { Helmet } from 'inferno-helmet';
|
||||
import { httpExternalPath } from '../env';
|
||||
|
||||
interface HtmlTagsProps {
|
||||
title: string;
|
||||
path: string;
|
||||
description?: string;
|
||||
image?: string;
|
||||
}
|
||||
|
||||
/// Taken from https://metatags.io/
|
||||
export class HtmlTags extends Component<HtmlTagsProps, any> {
|
||||
render() {
|
||||
let url = httpExternalPath(this.props.path);
|
||||
|
||||
return (
|
||||
<Helmet title={this.props.title}>
|
||||
{/* Primary Meta Tags */}
|
||||
<meta name="title" content={this.props.title} />
|
||||
{this.props.description && (
|
||||
<meta name="description" content={this.props.description} />
|
||||
)}
|
||||
|
||||
{/* Open Graph / Facebook */}
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content={url} />
|
||||
<meta property="og:title" content={this.props.title} />
|
||||
{this.props.description && (
|
||||
<meta property="og:description" content={this.props.description} />
|
||||
)}
|
||||
{this.props.image && (
|
||||
<meta property="og:image" content={this.props.image} />
|
||||
)}
|
||||
|
||||
{/* Twitter */}
|
||||
<meta property="twitter:card" content="summary_large_image" />
|
||||
<meta property="twitter:url" content={url} />
|
||||
<meta property="twitter:title" content={this.props.title} />
|
||||
{this.props.description && (
|
||||
<meta
|
||||
property="twitter:description"
|
||||
content={this.props.description}
|
||||
/>
|
||||
)}
|
||||
{this.props.image && (
|
||||
<meta property="twitter:image" content={this.props.image} />
|
||||
)}
|
||||
</Helmet>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
import { Component, linkEvent } from 'inferno';
|
||||
import { Helmet } from 'inferno-helmet';
|
||||
import { Subscription } from 'rxjs';
|
||||
import {
|
||||
UserOperation,
|
||||
|
@ -37,6 +36,7 @@ import {
|
|||
} from '../utils';
|
||||
import { CommentNodes } from './comment-nodes';
|
||||
import { PrivateMessage } from './private-message';
|
||||
import { HtmlTags } from './html-tags';
|
||||
import { SortSelect } from './sort-select';
|
||||
import { i18n } from '../i18next';
|
||||
|
||||
|
@ -117,7 +117,6 @@ export class Inbox extends Component<any, InboxState> {
|
|||
render() {
|
||||
return (
|
||||
<div class="container">
|
||||
<Helmet title={this.documentTitle} />
|
||||
{this.state.loading ? (
|
||||
<h5>
|
||||
<svg class="icon icon-spinner spin">
|
||||
|
@ -127,6 +126,10 @@ export class Inbox extends Component<any, InboxState> {
|
|||
) : (
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<HtmlTags
|
||||
title={this.documentTitle}
|
||||
path={this.context.router.route.match.url}
|
||||
/>
|
||||
<h5 class="mb-1">
|
||||
{i18n.t('inbox')}
|
||||
<small>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Component } from 'inferno';
|
||||
import { Helmet } from 'inferno-helmet';
|
||||
import { GetSiteResponse } from 'lemmy-js-client';
|
||||
import { setIsoData } from '../utils';
|
||||
import { i18n } from '../i18next';
|
||||
import { HtmlTags } from './html-tags';
|
||||
|
||||
interface InstancesState {
|
||||
siteRes: GetSiteResponse;
|
||||
|
@ -26,7 +26,10 @@ export class Instances extends Component<any, InstancesState> {
|
|||
render() {
|
||||
return (
|
||||
<div class="container">
|
||||
<Helmet title={this.documentTitle} />
|
||||
<HtmlTags
|
||||
title={this.documentTitle}
|
||||
path={this.context.router.route.match.url}
|
||||
/>
|
||||
<div>
|
||||
<h5>{i18n.t('linked_instances')}</h5>
|
||||
{this.state.siteRes &&
|
||||
|
|
|
@ -22,6 +22,7 @@ import {
|
|||
setIsoData,
|
||||
} from '../utils';
|
||||
import { i18n } from '../i18next';
|
||||
import { HtmlTags } from './html-tags';
|
||||
|
||||
interface State {
|
||||
loginForm: LoginForm;
|
||||
|
@ -78,17 +79,16 @@ export class Login extends Component<any, State> {
|
|||
}
|
||||
|
||||
get documentTitle(): string {
|
||||
if (this.state.site.name) {
|
||||
return `${i18n.t('login')} - ${this.state.site.name}`;
|
||||
} else {
|
||||
return 'Lemmy';
|
||||
}
|
||||
return `${i18n.t('login')} - ${this.state.site.name}`;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div class="container">
|
||||
<Helmet title={this.documentTitle} />
|
||||
<HtmlTags
|
||||
title={this.documentTitle}
|
||||
path={this.context.router.route.match.url}
|
||||
/>
|
||||
<div class="row">
|
||||
<div class="col-12 col-lg-6 mb-4">{this.loginForm()}</div>
|
||||
<div class="col-12 col-lg-6">{this.registerForm()}</div>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { Component, linkEvent } from 'inferno';
|
||||
import { Helmet } from 'inferno-helmet';
|
||||
import { Link } from 'inferno-router';
|
||||
import { Subscription } from 'rxjs';
|
||||
import {
|
||||
|
@ -53,7 +52,6 @@ import {
|
|||
editPostFindRes,
|
||||
commentsToFlatNodes,
|
||||
setupTippy,
|
||||
favIconUrl,
|
||||
notifyPost,
|
||||
setIsoData,
|
||||
wsSubscribe,
|
||||
|
@ -63,6 +61,7 @@ import {
|
|||
} from '../utils';
|
||||
import { i18n } from '../i18next';
|
||||
import { T } from 'inferno-i18next';
|
||||
import { HtmlTags } from './html-tags';
|
||||
|
||||
interface MainState {
|
||||
subscribedCommunities: CommunityUser[];
|
||||
|
@ -240,23 +239,13 @@ export class Main extends Component<any, MainState> {
|
|||
return `${this.state.siteRes.site.name}`;
|
||||
}
|
||||
|
||||
get favIcon(): string {
|
||||
return this.state.siteRes.site.icon
|
||||
? this.state.siteRes.site.icon
|
||||
: favIconUrl;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div class="container">
|
||||
<Helmet title={this.documentTitle}>
|
||||
<link
|
||||
id="favicon"
|
||||
rel="icon"
|
||||
type="image/x-icon"
|
||||
href={this.favIcon}
|
||||
/>
|
||||
</Helmet>
|
||||
<HtmlTags
|
||||
title={this.documentTitle}
|
||||
path={this.context.router.route.match.url}
|
||||
/>
|
||||
<div class="row">
|
||||
<main role="main" class="col-12 col-md-8">
|
||||
{this.posts()}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { Component, linkEvent } from 'inferno';
|
||||
import { Helmet } from 'inferno-helmet';
|
||||
import { Link } from 'inferno-router';
|
||||
import { Subscription } from 'rxjs';
|
||||
import {
|
||||
|
@ -30,6 +29,7 @@ import {
|
|||
lemmyHttp,
|
||||
} from '../utils';
|
||||
import { MomentTime } from './moment-time';
|
||||
import { HtmlTags } from './html-tags';
|
||||
import moment from 'moment';
|
||||
import { i18n } from '../i18next';
|
||||
|
||||
|
@ -353,17 +353,16 @@ export class Modlog extends Component<any, ModlogState> {
|
|||
}
|
||||
|
||||
get documentTitle(): string {
|
||||
if (this.state.site) {
|
||||
return `Modlog - ${this.state.site.name}`;
|
||||
} else {
|
||||
return 'Lemmy';
|
||||
}
|
||||
return `Modlog - ${this.state.site.name}`;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div class="container">
|
||||
<Helmet title={this.documentTitle} />
|
||||
<HtmlTags
|
||||
title={this.documentTitle}
|
||||
path={this.context.router.route.match.url}
|
||||
/>
|
||||
{this.state.loading ? (
|
||||
<h5 class="">
|
||||
<svg class="icon icon-spinner spin">
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { Component, linkEvent } from 'inferno';
|
||||
import { Helmet } from 'inferno-helmet';
|
||||
import { Subscription } from 'rxjs';
|
||||
import {
|
||||
UserOperation,
|
||||
|
@ -18,6 +17,7 @@ import {
|
|||
wsSubscribe,
|
||||
} from '../utils';
|
||||
import { i18n } from '../i18next';
|
||||
import { HtmlTags } from './html-tags';
|
||||
|
||||
interface State {
|
||||
passwordChangeForm: PasswordChangeForm;
|
||||
|
@ -61,7 +61,10 @@ export class PasswordChange extends Component<any, State> {
|
|||
render() {
|
||||
return (
|
||||
<div class="container">
|
||||
<Helmet title={this.documentTitle} />
|
||||
<HtmlTags
|
||||
title={this.documentTitle}
|
||||
path={this.context.router.route.match.url}
|
||||
/>
|
||||
<div class="row">
|
||||
<div class="col-12 col-lg-6 offset-lg-3 mb-4">
|
||||
<h5>{i18n.t('password_change')}</h5>
|
||||
|
|
|
@ -38,6 +38,7 @@ import {
|
|||
previewLines,
|
||||
} from '../utils';
|
||||
import { i18n } from '../i18next';
|
||||
import { externalHost } from '../env';
|
||||
|
||||
interface PostListingState {
|
||||
showEdit: boolean;
|
||||
|
@ -309,7 +310,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
)}
|
||||
</li>
|
||||
<li className="list-inline-item">•</li>
|
||||
{post.url && !(hostname(post.url) == window.location.hostname) && (
|
||||
{post.url && !(hostname(post.url) == externalHost) && (
|
||||
<>
|
||||
<li className="list-inline-item">
|
||||
<a
|
||||
|
@ -413,43 +414,37 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
{post.name}
|
||||
</Link>
|
||||
)}
|
||||
{(isImage(post.url) || this.props.post.thumbnail_url) && (
|
||||
<>
|
||||
{!this.state.imageExpanded ? (
|
||||
{(isImage(post.url) || this.props.post.thumbnail_url) &&
|
||||
(!this.state.imageExpanded ? (
|
||||
<span
|
||||
class="text-monospace unselectable pointer ml-2 text-muted small"
|
||||
data-tippy-content={i18n.t('expand_here')}
|
||||
onClick={linkEvent(this, this.handleImageExpandClick)}
|
||||
>
|
||||
<svg class="icon icon-inline">
|
||||
<use xlinkHref="#icon-plus-square"></use>
|
||||
</svg>
|
||||
</span>
|
||||
) : (
|
||||
<span>
|
||||
<span
|
||||
class="text-monospace unselectable pointer ml-2 text-muted small"
|
||||
data-tippy-content={i18n.t('expand_here')}
|
||||
onClick={linkEvent(this, this.handleImageExpandClick)}
|
||||
>
|
||||
<svg class="icon icon-inline">
|
||||
<use xlinkHref="#icon-plus-square"></use>
|
||||
<use xlinkHref="#icon-minus-square"></use>
|
||||
</svg>
|
||||
</span>
|
||||
) : (
|
||||
<span>
|
||||
<div>
|
||||
<span
|
||||
class="text-monospace unselectable pointer ml-2 text-muted small"
|
||||
class="pointer"
|
||||
onClick={linkEvent(this, this.handleImageExpandClick)}
|
||||
>
|
||||
<svg class="icon icon-inline">
|
||||
<use xlinkHref="#icon-minus-square"></use>
|
||||
</svg>
|
||||
<img class="img-fluid img-expanded" src={this.getImage()} />
|
||||
</span>
|
||||
<div>
|
||||
<span
|
||||
class="pointer"
|
||||
onClick={linkEvent(this, this.handleImageExpandClick)}
|
||||
>
|
||||
<img
|
||||
class="img-fluid img-expanded"
|
||||
src={this.getImage()}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</span>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</span>
|
||||
))}
|
||||
{post.removed && (
|
||||
<small className="ml-2 text-muted font-italic">
|
||||
{i18n.t('removed')}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Component, linkEvent } from 'inferno';
|
||||
import { Helmet } from 'inferno-helmet';
|
||||
import { HtmlTags } from './html-tags';
|
||||
import { Subscription } from 'rxjs';
|
||||
import {
|
||||
UserOperation,
|
||||
|
@ -36,7 +36,6 @@ import {
|
|||
createPostLikeRes,
|
||||
commentsToFlatNodes,
|
||||
setupTippy,
|
||||
favIconUrl,
|
||||
setIsoData,
|
||||
getIdFromProps,
|
||||
getCommentIdFromProps,
|
||||
|
@ -44,6 +43,8 @@ import {
|
|||
setAuth,
|
||||
lemmyHttp,
|
||||
isBrowser,
|
||||
previewLines,
|
||||
isImage,
|
||||
} from '../utils';
|
||||
import { PostListing } from './post-listing';
|
||||
import { Sidebar } from './sidebar';
|
||||
|
@ -148,7 +149,7 @@ export class Post extends Component<any, PostState> {
|
|||
|
||||
// Necessary if you are on a post and you click another post (same route)
|
||||
if (_lastProps.location.pathname !== _lastProps.history.location.pathname) {
|
||||
// Couldnt get a refresh working. This does for now.
|
||||
// TODO Couldnt get a refresh working. This does for now.
|
||||
location.reload();
|
||||
|
||||
// let currentId = this.props.match.params.id;
|
||||
|
@ -191,30 +192,29 @@ export class Post extends Component<any, PostState> {
|
|||
}
|
||||
|
||||
get documentTitle(): string {
|
||||
if (this.state.postRes) {
|
||||
return `${this.state.postRes.post.name} - ${this.state.siteRes.site.name}`;
|
||||
} else {
|
||||
return 'Lemmy';
|
||||
}
|
||||
return `${this.state.postRes.post.name} - ${this.state.siteRes.site.name}`;
|
||||
}
|
||||
|
||||
get favIcon(): string {
|
||||
return this.state.siteRes.site.icon
|
||||
? this.state.siteRes.site.icon
|
||||
: favIconUrl;
|
||||
get imageTag(): string {
|
||||
return (
|
||||
this.state.postRes.post.thumbnail_url ||
|
||||
(this.state.postRes.post.url
|
||||
? isImage(this.state.postRes.post.url)
|
||||
? this.state.postRes.post.url
|
||||
: undefined
|
||||
: undefined)
|
||||
);
|
||||
}
|
||||
|
||||
get descriptionTag(): string {
|
||||
return this.state.postRes.post.body
|
||||
? previewLines(this.state.postRes.post.body)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div class="container">
|
||||
<Helmet title={this.documentTitle}>
|
||||
<link
|
||||
id="favicon"
|
||||
rel="icon"
|
||||
type="image/x-icon"
|
||||
href={this.favIcon}
|
||||
/>
|
||||
</Helmet>
|
||||
{this.state.loading ? (
|
||||
<h5>
|
||||
<svg class="icon icon-spinner spin">
|
||||
|
@ -224,6 +224,12 @@ export class Post extends Component<any, PostState> {
|
|||
) : (
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-8 mb-3">
|
||||
<HtmlTags
|
||||
title={this.documentTitle}
|
||||
path={this.context.router.route.match.url}
|
||||
image={this.imageTag}
|
||||
description={this.descriptionTag}
|
||||
/>
|
||||
<PostListing
|
||||
post={this.state.postRes.post}
|
||||
showBody
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { Component, linkEvent } from 'inferno';
|
||||
import { Helmet } from 'inferno-helmet';
|
||||
import { Subscription } from 'rxjs';
|
||||
import {
|
||||
UserOperation,
|
||||
|
@ -32,6 +31,7 @@ import {
|
|||
setAuth,
|
||||
} from '../utils';
|
||||
import { PostListing } from './post-listing';
|
||||
import { HtmlTags } from './html-tags';
|
||||
import { UserListing } from './user-listing';
|
||||
import { CommunityLink } from './community-link';
|
||||
import { SortSelect } from './sort-select';
|
||||
|
@ -165,23 +165,20 @@ export class Search extends Component<any, SearchState> {
|
|||
}
|
||||
|
||||
get documentTitle(): string {
|
||||
if (this.state.site.name) {
|
||||
if (this.state.q) {
|
||||
return `${i18n.t('search')} - ${this.state.q} - ${
|
||||
this.state.site.name
|
||||
}`;
|
||||
} else {
|
||||
return `${i18n.t('search')} - ${this.state.site.name}`;
|
||||
}
|
||||
if (this.state.q) {
|
||||
return `${i18n.t('search')} - ${this.state.q} - ${this.state.site.name}`;
|
||||
} else {
|
||||
return 'Lemmy';
|
||||
return `${i18n.t('search')} - ${this.state.site.name}`;
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div class="container">
|
||||
<Helmet title={this.documentTitle} />
|
||||
<HtmlTags
|
||||
title={this.documentTitle}
|
||||
path={this.context.router.route.match.url}
|
||||
/>
|
||||
<h5>{i18n.t('search')}</h5>
|
||||
{this.selects()}
|
||||
{this.searchForm()}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { Component } from 'inferno';
|
||||
import { Helmet } from 'inferno-helmet';
|
||||
import { Site } from 'lemmy-js-client';
|
||||
import { i18n } from '../i18next';
|
||||
import { T } from 'inferno-i18next';
|
||||
import { repoUrl, isBrowser } from '../utils';
|
||||
import { IsoData } from 'shared/interfaces';
|
||||
import { HtmlTags } from './html-tags';
|
||||
|
||||
interface SilverUser {
|
||||
name: string;
|
||||
|
@ -74,7 +74,10 @@ export class Sponsors extends Component<any, SponsorsState> {
|
|||
render() {
|
||||
return (
|
||||
<div class="container text-center">
|
||||
<Helmet title={this.documentTitle} />
|
||||
<HtmlTags
|
||||
title={this.documentTitle}
|
||||
path={this.context.router.route.match.url}
|
||||
/>
|
||||
{this.topMessage()}
|
||||
<hr />
|
||||
{this.sponsors()}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { Component, linkEvent } from 'inferno';
|
||||
import { Helmet } from 'inferno-helmet';
|
||||
import { Link } from 'inferno-router';
|
||||
import { Subscription } from 'rxjs';
|
||||
import {
|
||||
|
@ -33,7 +32,6 @@ import {
|
|||
getLanguage,
|
||||
mdToHtml,
|
||||
elementUrl,
|
||||
favIconUrl,
|
||||
setIsoData,
|
||||
getIdFromProps,
|
||||
getUsernameFromProps,
|
||||
|
@ -44,8 +42,10 @@ import {
|
|||
createPostLikeFindRes,
|
||||
setAuth,
|
||||
lemmyHttp,
|
||||
previewLines,
|
||||
} from '../utils';
|
||||
import { UserListing } from './user-listing';
|
||||
import { HtmlTags } from './html-tags';
|
||||
import { SortSelect } from './sort-select';
|
||||
import { ListingTypeSelect } from './listing-type-select';
|
||||
import { MomentTime } from './moment-time';
|
||||
|
@ -250,30 +250,18 @@ export class User extends Component<any, UserState> {
|
|||
}
|
||||
|
||||
get documentTitle(): string {
|
||||
if (this.state.siteRes.site.name) {
|
||||
return `@${this.state.userName} - ${this.state.siteRes.site.name}`;
|
||||
} else {
|
||||
return 'Lemmy';
|
||||
}
|
||||
return `@${this.state.userName} - ${this.state.siteRes.site.name}`;
|
||||
}
|
||||
|
||||
get favIcon(): string {
|
||||
return this.state.siteRes.site.icon
|
||||
? this.state.siteRes.site.icon
|
||||
: favIconUrl;
|
||||
get bioTag(): string {
|
||||
return this.state.userRes.user.bio
|
||||
? previewLines(this.state.userRes.user.bio)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div class="container">
|
||||
<Helmet title={this.documentTitle}>
|
||||
<link
|
||||
id="favicon"
|
||||
rel="icon"
|
||||
type="image/x-icon"
|
||||
href={this.favIcon}
|
||||
/>
|
||||
</Helmet>
|
||||
{this.state.loading ? (
|
||||
<h5>
|
||||
<svg class="icon icon-spinner spin">
|
||||
|
@ -284,6 +272,12 @@ export class User extends Component<any, UserState> {
|
|||
<div class="row">
|
||||
<div class="col-12 col-md-8">
|
||||
<>
|
||||
<HtmlTags
|
||||
title={this.documentTitle}
|
||||
path={this.context.router.route.match.url}
|
||||
description={this.bioTag}
|
||||
image={this.state.userRes.user.avatar}
|
||||
/>
|
||||
{this.userInfo()}
|
||||
<hr />
|
||||
</>
|
||||
|
|
|
@ -1,15 +1,46 @@
|
|||
import { isBrowser } from './utils';
|
||||
|
||||
const nodeHostname = process.env.LEMMY_HOST || 'localhost'; // used for local dev
|
||||
const host = isBrowser() ? window.location.hostname : nodeHostname;
|
||||
const secure = isBrowser() && window.location.protocol == 'https:' ? 's' : '';
|
||||
const port = isBrowser()
|
||||
? window.location.port == '1234' || window.location.port == '1235'
|
||||
? 8536
|
||||
: window.location.port
|
||||
: 8536;
|
||||
const endpoint = `${host}:${port}`;
|
||||
const testHost = 'localhost:8536';
|
||||
|
||||
export const wsUri = `ws${secure}://${endpoint}/api/v1/ws`;
|
||||
export const httpUri = `http${secure}://${endpoint}/api/v1`;
|
||||
export const pictrsUri = `http${secure}://${endpoint}/pictrs/image`;
|
||||
const internalHost = process.env.LEMMY_INTERNAL_HOST || testHost; // used for local dev
|
||||
export const externalHost = isBrowser()
|
||||
? `${window.location.hostname}:${
|
||||
window.location.port == '1234' || window.location.port == '1235'
|
||||
? 8536
|
||||
: window.location.port
|
||||
}`
|
||||
: process.env.LEMMY_EXTERNAL_HOST || testHost;
|
||||
|
||||
// ? window.location.port == '1234' || window.location.port == '1235'
|
||||
const secure = isBrowser() && window.location.protocol == 'https:' ? 's' : '';
|
||||
|
||||
const host = isBrowser() ? externalHost : internalHost;
|
||||
|
||||
const httpBase = `http${secure}://${host}`;
|
||||
export const wsUri = `ws${secure}://${host}/api/v1/ws`;
|
||||
export const httpUri = `${httpBase}/api/v1`;
|
||||
const httpExternalUri = `http${secure}://${externalHost}`;
|
||||
export const pictrsUri = `${httpBase}/pictrs/image`;
|
||||
|
||||
console.log(`Internal host: ${internalHost}`);
|
||||
console.log(`External host: ${externalHost}`);
|
||||
|
||||
export function httpExternalPath(path: string) {
|
||||
return `${httpExternalUri}${path}`;
|
||||
}
|
||||
|
||||
// export const httpUri = `http${secure}://${endpoint}/api/v1`;
|
||||
// export const pictrsUri = `http${secure}://${endpoint}/pictrs/image`;
|
||||
|
||||
// const host = isBrowser() ? window.location.hostname : localHostname;
|
||||
// const secure = isBrowser() && window.location.protocol == 'https:' ? 's' : '';
|
||||
// const port = isBrowser()
|
||||
// ? window.location.port == '1234' || window.location.port == '1235'
|
||||
// ? 8536
|
||||
// : window.location.port
|
||||
// : 8536;
|
||||
// const endpoint = `${host}:${port}`;
|
||||
//
|
||||
// export const wsUri = `ws${secure}://${endpoint}/api/v1/ws`;
|
||||
// export const httpUri = `http${secure}://${endpoint}/api/v1`;
|
||||
// export const pictrsUri = `http${secure}://${endpoint}/pictrs/image`;
|
||||
|
|
|
@ -271,7 +271,6 @@ export function isVideo(url: string) {
|
|||
|
||||
// TODO this broke
|
||||
export function validURL(str: string) {
|
||||
console.log(str);
|
||||
// try {
|
||||
return !!new URL(str);
|
||||
// } catch {
|
||||
|
@ -439,8 +438,6 @@ export function getMomentLanguage(): string {
|
|||
|
||||
export function setTheme(theme: string, forceReload: boolean = false) {
|
||||
if (isBrowser() && (theme !== 'darkly' || forceReload)) {
|
||||
console.log(`setting theme ${theme}`);
|
||||
|
||||
// Unload all the other themes
|
||||
for (var i = 0; i < themes.length; i++) {
|
||||
let styleSheet = document.getElementById(themes[i]);
|
||||
|
@ -1078,11 +1075,7 @@ export function previewLines(
|
|||
|
||||
export function hostname(url: string): string {
|
||||
let cUrl = new URL(url);
|
||||
// TODO
|
||||
return `${cUrl.hostname}:${cUrl.port}`;
|
||||
// return window.location.port
|
||||
// ? `${cUrl.hostname}:${cUrl.port}`
|
||||
// : `${cUrl.hostname}`;
|
||||
return cUrl.port ? `${cUrl.hostname}:${cUrl.port}` : `${cUrl.hostname}`;
|
||||
}
|
||||
|
||||
function canUseWebP() {
|
||||
|
|
Loading…
Reference in a new issue