mirror of
https://github.com/mediacms-io/mediacms.git
synced 2026-02-04 14:32:59 -05:00
Merge branch 'main' into feat-lti-integration-select
This commit is contained in:
@@ -1 +1 @@
|
|||||||
VERSION = "7.8124"
|
VERSION = "8"
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -3,253 +3,278 @@ import { SiteContext } from '../../utils/contexts/';
|
|||||||
import { useUser, usePopup } from '../../utils/hooks/';
|
import { useUser, usePopup } from '../../utils/hooks/';
|
||||||
import { PageStore, MediaPageStore } from '../../utils/stores/';
|
import { PageStore, MediaPageStore } from '../../utils/stores/';
|
||||||
import { PageActions, MediaPageActions } from '../../utils/actions/';
|
import { PageActions, MediaPageActions } from '../../utils/actions/';
|
||||||
import { formatInnerLink, publishedOnDate } from '../../utils/helpers/';
|
import { formatInnerLink, inEmbeddedApp, publishedOnDate } from '../../utils/helpers/';
|
||||||
import { PopupMain } from '../_shared/';
|
import { PopupMain } from '../_shared/';
|
||||||
import CommentsList from '../comments/Comments';
|
import CommentsList from '../comments/Comments';
|
||||||
import { replaceString } from '../../utils/helpers/';
|
import { replaceString } from '../../utils/helpers/';
|
||||||
import { translateString } from '../../utils/helpers/';
|
import { translateString } from '../../utils/helpers/';
|
||||||
|
|
||||||
function metafield(arr) {
|
function metafield(arr) {
|
||||||
let i;
|
let i;
|
||||||
let sep;
|
let sep;
|
||||||
let ret = [];
|
let ret = [];
|
||||||
|
|
||||||
if (arr && arr.length) {
|
if (arr && arr.length) {
|
||||||
i = 0;
|
i = 0;
|
||||||
sep = 1 < arr.length ? ', ' : '';
|
sep = 1 < arr.length ? ', ' : '';
|
||||||
while (i < arr.length) {
|
while (i < arr.length) {
|
||||||
ret[i] = (
|
ret[i] = (
|
||||||
<div key={i}>
|
<div key={i}>
|
||||||
<a href={arr[i].url} title={arr[i].title}>
|
<a href={arr[i].url} title={arr[i].title}>
|
||||||
{arr[i].title}
|
{arr[i].title}
|
||||||
</a>
|
</a>
|
||||||
{i < arr.length - 1 ? sep : ''}
|
{i < arr.length - 1 ? sep : ''}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
i += 1;
|
i += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
function MediaAuthorBanner(props) {
|
function MediaAuthorBanner(props) {
|
||||||
return (
|
return (
|
||||||
<div className="media-author-banner">
|
<div className="media-author-banner">
|
||||||
<div>
|
<div>
|
||||||
<a className="author-banner-thumb" href={props.link || null} title={props.name}>
|
<a className="author-banner-thumb" href={props.link || null} title={props.name}>
|
||||||
<span style={{ backgroundImage: 'url(' + props.thumb + ')' }}>
|
<span style={{ backgroundImage: 'url(' + props.thumb + ')' }}>
|
||||||
<img src={props.thumb} loading="lazy" alt={props.name} title={props.name} />
|
<img src={props.thumb} loading="lazy" alt={props.name} title={props.name} />
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span>
|
<span>
|
||||||
<a href={props.link} className="author-banner-name" title={props.name}>
|
<a href={props.link} className="author-banner-name" title={props.name}>
|
||||||
<span>{props.name}</span>
|
<span>{props.name}</span>
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
{PageStore.get('config-media-item').displayPublishDate && props.published ? (
|
{PageStore.get('config-media-item').displayPublishDate && props.published ? (
|
||||||
<span className="author-banner-date">
|
<span className="author-banner-date">
|
||||||
{translateString('Published on')} {replaceString(publishedOnDate(new Date(props.published)))}
|
{translateString('Published on')} {replaceString(publishedOnDate(new Date(props.published)))}
|
||||||
</span>
|
</span>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function MediaMetaField(props) {
|
function MediaMetaField(props) {
|
||||||
return (
|
return (
|
||||||
<div className={props.id.trim() ? 'media-content-' + props.id.trim() : null}>
|
<div className={props.id.trim() ? 'media-content-' + props.id.trim() : null}>
|
||||||
<div className="media-content-field">
|
<div className="media-content-field">
|
||||||
<div className="media-content-field-label">
|
<div className="media-content-field-label">
|
||||||
<h4>{props.title}</h4>
|
<h4>{props.title}</h4>
|
||||||
|
</div>
|
||||||
|
<div className="media-content-field-content">{props.value}</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="media-content-field-content">{props.value}</div>
|
);
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function EditMediaButton(props) {
|
function EditMediaButton(props) {
|
||||||
const friendlyToken = window.MediaCMS.mediaId;
|
let link = props.link;
|
||||||
|
|
||||||
return (
|
if (window.MediaCMS.site.devEnv) {
|
||||||
<a href={`/edit?m=${friendlyToken}`} className="edit-media-icon" title={translateString('Edit metadata')}>
|
link = '/edit-media.html';
|
||||||
<i className="material-icons">edit</i>
|
}
|
||||||
</a>
|
|
||||||
);
|
return (
|
||||||
|
<a href={link} rel="nofollow" title={translateString('Edit media')} className="edit-media-icon">
|
||||||
|
<i className="material-icons">edit</i>
|
||||||
|
</a>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ViewerInfoContent(props) {
|
export default function ViewerInfoContent(props) {
|
||||||
const { userCan } = useUser();
|
const { userCan } = useUser();
|
||||||
|
|
||||||
const description = props.description.trim();
|
const description = props.description.trim();
|
||||||
const tagsContent =
|
const tagsContent =
|
||||||
!PageStore.get('config-enabled').taxonomies.tags || PageStore.get('config-enabled').taxonomies.tags.enabled
|
!PageStore.get('config-enabled').taxonomies.tags || PageStore.get('config-enabled').taxonomies.tags.enabled
|
||||||
? metafield(MediaPageStore.get('media-tags'))
|
? metafield(MediaPageStore.get('media-tags'))
|
||||||
: [];
|
: [];
|
||||||
const categoriesContent = PageStore.get('config-options').pages.media.categoriesWithTitle
|
const categoriesContent = PageStore.get('config-options').pages.media.categoriesWithTitle
|
||||||
? []
|
? []
|
||||||
: !PageStore.get('config-enabled').taxonomies.categories ||
|
: !PageStore.get('config-enabled').taxonomies.categories ||
|
||||||
PageStore.get('config-enabled').taxonomies.categories.enabled
|
PageStore.get('config-enabled').taxonomies.categories.enabled
|
||||||
? metafield(MediaPageStore.get('media-categories'))
|
? metafield(MediaPageStore.get('media-categories'))
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
let summary = MediaPageStore.get('media-summary');
|
let summary = MediaPageStore.get('media-summary');
|
||||||
|
|
||||||
summary = summary ? summary.trim() : '';
|
summary = summary ? summary.trim() : '';
|
||||||
|
|
||||||
const [popupContentRef, PopupContent, PopupTrigger] = usePopup();
|
const [popupContentRef, PopupContent, PopupTrigger] = usePopup();
|
||||||
|
|
||||||
const [hasSummary, setHasSummary] = useState('' !== summary);
|
const [hasSummary, setHasSummary] = useState('' !== summary);
|
||||||
const [isContentVisible, setIsContentVisible] = useState('' == summary);
|
const [isContentVisible, setIsContentVisible] = useState('' == summary);
|
||||||
|
|
||||||
function proceedMediaRemoval() {
|
function proceedMediaRemoval() {
|
||||||
MediaPageActions.removeMedia();
|
MediaPageActions.removeMedia();
|
||||||
popupContentRef.current.toggle();
|
popupContentRef.current.toggle();
|
||||||
}
|
|
||||||
|
|
||||||
function cancelMediaRemoval() {
|
|
||||||
popupContentRef.current.toggle();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMediaDelete(mediaId) {
|
|
||||||
// FIXME: Without delay creates conflict [ Uncaught Error: Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch. ].
|
|
||||||
setTimeout(function () {
|
|
||||||
PageActions.addNotification('Media removed. Redirecting...', 'mediaDelete');
|
|
||||||
setTimeout(function () {
|
|
||||||
window.location.href =
|
|
||||||
SiteContext._currentValue.url + '/' + MediaPageStore.get('media-data').author_profile.replace(/^\//g, '');
|
|
||||||
}, 2000);
|
|
||||||
}, 100);
|
|
||||||
|
|
||||||
if (void 0 !== mediaId) {
|
|
||||||
console.info("Removed media '" + mediaId + '"');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMediaDeleteFail(mediaId) {
|
|
||||||
// FIXME: Without delay creates conflict [ Uncaught Error: Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch. ].
|
|
||||||
setTimeout(function () {
|
|
||||||
PageActions.addNotification('Media removal failed', 'mediaDeleteFail');
|
|
||||||
}, 100);
|
|
||||||
|
|
||||||
if (void 0 !== mediaId) {
|
|
||||||
console.info('Media "' + mediaId + '"' + ' removal failed');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onClickLoadMore() {
|
|
||||||
setIsContentVisible(!isContentVisible);
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
MediaPageStore.on('media_delete', onMediaDelete);
|
|
||||||
MediaPageStore.on('media_delete_fail', onMediaDeleteFail);
|
|
||||||
return () => {
|
|
||||||
MediaPageStore.removeListener('media_delete', onMediaDelete);
|
|
||||||
MediaPageStore.removeListener('media_delete_fail', onMediaDeleteFail);
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const authorLink = formatInnerLink(props.author.url, SiteContext._currentValue.url);
|
|
||||||
const authorThumb = formatInnerLink(props.author.thumb, SiteContext._currentValue.url);
|
|
||||||
|
|
||||||
function setTimestampAnchors(text) {
|
|
||||||
function wrapTimestampWithAnchor(match, string) {
|
|
||||||
let split = match.split(':'),
|
|
||||||
s = 0,
|
|
||||||
m = 1;
|
|
||||||
|
|
||||||
while (split.length > 0) {
|
|
||||||
s += m * parseInt(split.pop(), 10);
|
|
||||||
m *= 60;
|
|
||||||
}
|
|
||||||
|
|
||||||
const wrapped = `<a href="#" data-timestamp="${s}" class="video-timestamp">${match}</a>`;
|
|
||||||
return wrapped;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const timeRegex = new RegExp('((\\d)?\\d:)?(\\d)?\\d:\\d\\d', 'g');
|
function cancelMediaRemoval() {
|
||||||
return text.replace(timeRegex, wrapTimestampWithAnchor);
|
popupContentRef.current.toggle();
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
function onMediaDelete(mediaId) {
|
||||||
<div className="media-info-content">
|
// FIXME: Without delay creates conflict [ Uncaught Error: Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch. ].
|
||||||
{void 0 === PageStore.get('config-media-item').displayAuthor ||
|
setTimeout(function () {
|
||||||
null === PageStore.get('config-media-item').displayAuthor ||
|
PageActions.addNotification('Media removed. Redirecting...', 'mediaDelete');
|
||||||
!!PageStore.get('config-media-item').displayAuthor ? (
|
setTimeout(function () {
|
||||||
<MediaAuthorBanner link={authorLink} thumb={authorThumb} name={props.author.name} published={props.published} />
|
window.location.href =
|
||||||
) : null}
|
SiteContext._currentValue.url +
|
||||||
|
'/' +
|
||||||
|
MediaPageStore.get('media-data').author_profile.replace(/^\//g, '');
|
||||||
|
}, 2000);
|
||||||
|
}, 100);
|
||||||
|
|
||||||
<div className="media-content-banner">
|
if (void 0 !== mediaId) {
|
||||||
<div className="media-content-banner-inner">
|
console.info("Removed media '" + mediaId + '"');
|
||||||
{hasSummary ? <div className="media-content-summary">{summary}</div> : null}
|
}
|
||||||
{(!hasSummary || isContentVisible) && description ? (
|
}
|
||||||
<div
|
|
||||||
className="media-content-description"
|
|
||||||
dangerouslySetInnerHTML={{ __html: setTimestampAnchors(description) }}
|
|
||||||
></div>
|
|
||||||
) : null}
|
|
||||||
{hasSummary ? (
|
|
||||||
<button className="load-more" onClick={onClickLoadMore}>
|
|
||||||
{isContentVisible ? 'SHOW LESS' : 'SHOW MORE'}
|
|
||||||
</button>
|
|
||||||
) : null}
|
|
||||||
{tagsContent.length ? (
|
|
||||||
<MediaMetaField
|
|
||||||
value={tagsContent}
|
|
||||||
title={1 < tagsContent.length ? translateString('Tags') : translateString('Tag')}
|
|
||||||
id="tags"
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
{categoriesContent.length ? (
|
|
||||||
<MediaMetaField
|
|
||||||
value={categoriesContent}
|
|
||||||
title={1 < categoriesContent.length ? translateString('Categories') : translateString('Category')}
|
|
||||||
id="categories"
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
{userCan.editMedia ? (
|
function onMediaDeleteFail(mediaId) {
|
||||||
<div className="media-author-actions">
|
// FIXME: Without delay creates conflict [ Uncaught Error: Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch. ].
|
||||||
{userCan.editMedia ? <EditMediaButton /> : null}
|
setTimeout(function () {
|
||||||
|
PageActions.addNotification('Media removal failed', 'mediaDeleteFail');
|
||||||
|
}, 100);
|
||||||
|
|
||||||
{userCan.deleteMedia ? (
|
if (void 0 !== mediaId) {
|
||||||
<PopupTrigger contentRef={popupContentRef}>
|
console.info('Media "' + mediaId + '"' + ' removal failed');
|
||||||
<button className="remove-media-icon" title={translateString('Delete media')}>
|
}
|
||||||
<i className="material-icons">delete</i>
|
}
|
||||||
</button>
|
|
||||||
</PopupTrigger>
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
{userCan.deleteMedia ? (
|
function onClickLoadMore() {
|
||||||
<PopupContent contentRef={popupContentRef}>
|
setIsContentVisible(!isContentVisible);
|
||||||
<PopupMain>
|
}
|
||||||
<div className="popup-message">
|
|
||||||
<span className="popup-message-title">Media removal</span>
|
useEffect(() => {
|
||||||
<span className="popup-message-main">You're willing to remove media permanently?</span>
|
MediaPageStore.on('media_delete', onMediaDelete);
|
||||||
</div>
|
MediaPageStore.on('media_delete_fail', onMediaDeleteFail);
|
||||||
<hr />
|
return () => {
|
||||||
<span className="popup-message-bottom">
|
MediaPageStore.removeListener('media_delete', onMediaDelete);
|
||||||
<button className="button-link cancel-comment-removal" onClick={cancelMediaRemoval}>
|
MediaPageStore.removeListener('media_delete_fail', onMediaDeleteFail);
|
||||||
CANCEL
|
};
|
||||||
</button>
|
}, []);
|
||||||
<button className="button-link proceed-comment-removal" onClick={proceedMediaRemoval}>
|
|
||||||
PROCEED
|
const authorLink = formatInnerLink(props.author.url, SiteContext._currentValue.url);
|
||||||
</button>
|
const authorThumb = formatInnerLink(props.author.thumb, SiteContext._currentValue.url);
|
||||||
</span>
|
|
||||||
</PopupMain>
|
function setTimestampAnchors(text) {
|
||||||
</PopupContent>
|
function wrapTimestampWithAnchor(match, string) {
|
||||||
) : null}
|
let split = match.split(':'),
|
||||||
|
s = 0,
|
||||||
|
m = 1;
|
||||||
|
|
||||||
|
while (split.length > 0) {
|
||||||
|
s += m * parseInt(split.pop(), 10);
|
||||||
|
m *= 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
const wrapped = `<a href="#" data-timestamp="${s}" class="video-timestamp">${match}</a>`;
|
||||||
|
return wrapped;
|
||||||
|
}
|
||||||
|
|
||||||
|
const timeRegex = new RegExp('((\\d)?\\d:)?(\\d)?\\d:\\d\\d', 'g');
|
||||||
|
return text.replace(timeRegex, wrapTimestampWithAnchor);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="media-info-content">
|
||||||
|
{void 0 === PageStore.get('config-media-item').displayAuthor ||
|
||||||
|
null === PageStore.get('config-media-item').displayAuthor ||
|
||||||
|
!!PageStore.get('config-media-item').displayAuthor ? (
|
||||||
|
<MediaAuthorBanner
|
||||||
|
link={authorLink}
|
||||||
|
thumb={authorThumb}
|
||||||
|
name={props.author.name}
|
||||||
|
published={props.published}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
<div className="media-content-banner">
|
||||||
|
<div className="media-content-banner-inner">
|
||||||
|
{hasSummary ? <div className="media-content-summary">{summary}</div> : null}
|
||||||
|
{(!hasSummary || isContentVisible) && description ? (
|
||||||
|
<div
|
||||||
|
className="media-content-description"
|
||||||
|
dangerouslySetInnerHTML={{ __html: setTimestampAnchors(description) }}
|
||||||
|
></div>
|
||||||
|
) : null}
|
||||||
|
{hasSummary ? (
|
||||||
|
<button className="load-more" onClick={onClickLoadMore}>
|
||||||
|
{isContentVisible ? 'SHOW LESS' : 'SHOW MORE'}
|
||||||
|
</button>
|
||||||
|
) : null}
|
||||||
|
{tagsContent.length ? (
|
||||||
|
<MediaMetaField
|
||||||
|
value={tagsContent}
|
||||||
|
title={1 < tagsContent.length ? translateString('Tags') : translateString('Tag')}
|
||||||
|
id="tags"
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
{categoriesContent.length ? (
|
||||||
|
<MediaMetaField
|
||||||
|
value={categoriesContent}
|
||||||
|
title={
|
||||||
|
1 < categoriesContent.length
|
||||||
|
? translateString('Categories')
|
||||||
|
: translateString('Category')
|
||||||
|
}
|
||||||
|
id="categories"
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{userCan.editMedia ? (
|
||||||
|
<div className="media-author-actions">
|
||||||
|
{userCan.editMedia ? (
|
||||||
|
<EditMediaButton link={MediaPageStore.get('media-data').edit_url} />
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{userCan.deleteMedia ? (
|
||||||
|
<PopupTrigger contentRef={popupContentRef}>
|
||||||
|
<button className="remove-media-icon" title={translateString('Delete media')}>
|
||||||
|
<i className="material-icons">delete</i>
|
||||||
|
</button>
|
||||||
|
</PopupTrigger>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{userCan.deleteMedia ? (
|
||||||
|
<PopupContent contentRef={popupContentRef}>
|
||||||
|
<PopupMain>
|
||||||
|
<div className="popup-message">
|
||||||
|
<span className="popup-message-title">Media removal</span>
|
||||||
|
<span className="popup-message-main">
|
||||||
|
You're willing to remove media permanently?
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<span className="popup-message-bottom">
|
||||||
|
<button
|
||||||
|
className="button-link cancel-comment-removal"
|
||||||
|
onClick={cancelMediaRemoval}
|
||||||
|
>
|
||||||
|
CANCEL
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className="button-link proceed-comment-removal"
|
||||||
|
onClick={proceedMediaRemoval}
|
||||||
|
>
|
||||||
|
PROCEED
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
|
</PopupMain>
|
||||||
|
</PopupContent>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<CommentsList />
|
{!inEmbeddedApp() && <CommentsList />}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,107 +1,119 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { formatViewsNumber } from '../../utils/helpers/';
|
import { formatViewsNumber, inEmbeddedApp } from '../../utils/helpers/';
|
||||||
import { PageStore, MediaPageStore } from '../../utils/stores/';
|
import { PageStore, MediaPageStore } from '../../utils/stores/';
|
||||||
import { MemberContext, PlaylistsContext } from '../../utils/contexts/';
|
import { MemberContext, PlaylistsContext } from '../../utils/contexts/';
|
||||||
import { MediaLikeIcon, MediaDislikeIcon, OtherMediaDownloadLink, VideoMediaDownloadLink, MediaSaveButton, MediaShareButton, MediaMoreOptionsIcon } from '../media-actions/';
|
import {
|
||||||
|
MediaLikeIcon,
|
||||||
|
MediaDislikeIcon,
|
||||||
|
OtherMediaDownloadLink,
|
||||||
|
VideoMediaDownloadLink,
|
||||||
|
MediaSaveButton,
|
||||||
|
MediaShareButton,
|
||||||
|
MediaMoreOptionsIcon,
|
||||||
|
} from '../media-actions/';
|
||||||
import ViewerInfoTitleBanner from './ViewerInfoTitleBanner';
|
import ViewerInfoTitleBanner from './ViewerInfoTitleBanner';
|
||||||
import { translateString } from '../../utils/helpers/';
|
import { translateString } from '../../utils/helpers/';
|
||||||
|
|
||||||
export default class ViewerInfoVideoTitleBanner extends ViewerInfoTitleBanner {
|
export default class ViewerInfoVideoTitleBanner extends ViewerInfoTitleBanner {
|
||||||
render() {
|
render() {
|
||||||
const displayViews = PageStore.get('config-options').pages.media.displayViews && void 0 !== this.props.views;
|
const displayViews = PageStore.get('config-options').pages.media.displayViews && void 0 !== this.props.views;
|
||||||
|
|
||||||
const mediaData = MediaPageStore.get('media-data');
|
const mediaData = MediaPageStore.get('media-data');
|
||||||
const mediaState = mediaData.state;
|
const mediaState = mediaData.state;
|
||||||
const isShared = mediaData.is_shared;
|
const isShared = mediaData.is_shared;
|
||||||
|
|
||||||
let stateTooltip = '';
|
let stateTooltip = '';
|
||||||
|
|
||||||
switch (mediaState) {
|
switch (mediaState) {
|
||||||
case 'private':
|
case 'private':
|
||||||
stateTooltip = 'The site admins have to make its access public';
|
stateTooltip = 'The site admins have to make its access public';
|
||||||
break;
|
break;
|
||||||
case 'unlisted':
|
case 'unlisted':
|
||||||
stateTooltip = 'The site admins have to make it appear on listings';
|
stateTooltip = 'The site admins have to make it appear on listings';
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const sharedTooltip = 'This media is shared with specific users or categories';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="media-title-banner">
|
||||||
|
{displayViews && PageStore.get('config-options').pages.media.categoriesWithTitle
|
||||||
|
? this.mediaCategories(true)
|
||||||
|
: null}
|
||||||
|
|
||||||
|
{void 0 !== this.props.title ? <h1>{this.props.title}</h1> : null}
|
||||||
|
|
||||||
|
{isShared || 'public' !== mediaState ? (
|
||||||
|
<div className="media-labels-area">
|
||||||
|
<div className="media-labels-area-inner">
|
||||||
|
{isShared ? (
|
||||||
|
<>
|
||||||
|
<span className="media-label-state">
|
||||||
|
<span>shared</span>
|
||||||
|
</span>
|
||||||
|
<span className="helper-icon" data-tooltip={sharedTooltip}>
|
||||||
|
<i className="material-icons">help_outline</i>
|
||||||
|
</span>
|
||||||
|
</>
|
||||||
|
) : 'public' !== mediaState ? (
|
||||||
|
<>
|
||||||
|
<span className="media-label-state">
|
||||||
|
<span>{mediaState}</span>
|
||||||
|
</span>
|
||||||
|
<span className="helper-icon" data-tooltip={stateTooltip}>
|
||||||
|
<i className="material-icons">help_outline</i>
|
||||||
|
</span>
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
<div
|
||||||
|
className={
|
||||||
|
'media-views-actions' +
|
||||||
|
(this.state.likedMedia ? ' liked-media' : '') +
|
||||||
|
(this.state.dislikedMedia ? ' disliked-media' : '')
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{!displayViews && PageStore.get('config-options').pages.media.categoriesWithTitle
|
||||||
|
? this.mediaCategories()
|
||||||
|
: null}
|
||||||
|
|
||||||
|
{displayViews ? (
|
||||||
|
<div className="media-views">
|
||||||
|
{formatViewsNumber(this.props.views, true)}{' '}
|
||||||
|
{1 >= this.props.views ? translateString('view') : translateString('views')}
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
<div className="media-actions">
|
||||||
|
<div>
|
||||||
|
{MemberContext._currentValue.can.likeMedia ? <MediaLikeIcon /> : null}
|
||||||
|
{MemberContext._currentValue.can.dislikeMedia ? <MediaDislikeIcon /> : null}
|
||||||
|
{!inEmbeddedApp() && MemberContext._currentValue.can.shareMedia ? (
|
||||||
|
<MediaShareButton isVideo={true} />
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{!inEmbeddedApp() &&
|
||||||
|
!MemberContext._currentValue.is.anonymous &&
|
||||||
|
MemberContext._currentValue.can.saveMedia &&
|
||||||
|
-1 < PlaylistsContext._currentValue.mediaTypes.indexOf(MediaPageStore.get('media-type')) ? (
|
||||||
|
<MediaSaveButton />
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{!this.props.allowDownload || !MemberContext._currentValue.can.downloadMedia ? null : !this
|
||||||
|
.downloadLink ? (
|
||||||
|
<VideoMediaDownloadLink />
|
||||||
|
) : (
|
||||||
|
<OtherMediaDownloadLink link={this.downloadLink} title={this.downloadFilename} />
|
||||||
|
)}
|
||||||
|
|
||||||
|
<MediaMoreOptionsIcon allowDownload={this.props.allowDownload} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const sharedTooltip = 'This media is shared with specific users or categories';
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="media-title-banner">
|
|
||||||
{displayViews && PageStore.get('config-options').pages.media.categoriesWithTitle
|
|
||||||
? this.mediaCategories(true)
|
|
||||||
: null}
|
|
||||||
|
|
||||||
{void 0 !== this.props.title ? <h1>{this.props.title}</h1> : null}
|
|
||||||
|
|
||||||
{isShared || 'public' !== mediaState ? (
|
|
||||||
<div className="media-labels-area">
|
|
||||||
<div className="media-labels-area-inner">
|
|
||||||
{isShared ? (
|
|
||||||
<>
|
|
||||||
<span className="media-label-state">
|
|
||||||
<span>shared</span>
|
|
||||||
</span>
|
|
||||||
<span className="helper-icon" data-tooltip={sharedTooltip}>
|
|
||||||
<i className="material-icons">help_outline</i>
|
|
||||||
</span>
|
|
||||||
</>
|
|
||||||
) : 'public' !== mediaState ? (
|
|
||||||
<>
|
|
||||||
<span className="media-label-state">
|
|
||||||
<span>{mediaState}</span>
|
|
||||||
</span>
|
|
||||||
<span className="helper-icon" data-tooltip={stateTooltip}>
|
|
||||||
<i className="material-icons">help_outline</i>
|
|
||||||
</span>
|
|
||||||
</>
|
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
<div
|
|
||||||
className={
|
|
||||||
'media-views-actions' +
|
|
||||||
(this.state.likedMedia ? ' liked-media' : '') +
|
|
||||||
(this.state.dislikedMedia ? ' disliked-media' : '')
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{!displayViews && PageStore.get('config-options').pages.media.categoriesWithTitle
|
|
||||||
? this.mediaCategories()
|
|
||||||
: null}
|
|
||||||
|
|
||||||
{displayViews ? (
|
|
||||||
<div className="media-views">
|
|
||||||
{formatViewsNumber(this.props.views, true)} {1 >= this.props.views ? translateString('view') : translateString('views')}
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
<div className="media-actions">
|
|
||||||
<div>
|
|
||||||
{MemberContext._currentValue.can.likeMedia ? <MediaLikeIcon /> : null}
|
|
||||||
{MemberContext._currentValue.can.dislikeMedia ? <MediaDislikeIcon /> : null}
|
|
||||||
{MemberContext._currentValue.can.shareMedia ? <MediaShareButton isVideo={true} /> : null}
|
|
||||||
|
|
||||||
{!MemberContext._currentValue.is.anonymous &&
|
|
||||||
MemberContext._currentValue.can.saveMedia &&
|
|
||||||
-1 < PlaylistsContext._currentValue.mediaTypes.indexOf(MediaPageStore.get('media-type')) ? (
|
|
||||||
<MediaSaveButton />
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
{!this.props.allowDownload || !MemberContext._currentValue.can.downloadMedia ? null : !this
|
|
||||||
.downloadLink ? (
|
|
||||||
<VideoMediaDownloadLink />
|
|
||||||
) : (
|
|
||||||
<OtherMediaDownloadLink link={this.downloadLink} title={this.downloadFilename} />
|
|
||||||
)}
|
|
||||||
|
|
||||||
<MediaMoreOptionsIcon allowDownload={this.props.allowDownload} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +1,33 @@
|
|||||||
.page-main-wrap {
|
.page-main-wrap {
|
||||||
padding-top: var(--header-height);
|
padding-top: var(--header-height);
|
||||||
will-change: padding-left;
|
will-change: padding-left;
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.visible-sidebar & {
|
||||||
|
padding-left: var(--sidebar-width);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.visible-sidebar #page-media & {
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
.visible-sidebar & {
|
.visible-sidebar & {
|
||||||
padding-left: var(--sidebar-width);
|
#page-media {
|
||||||
opacity: 1;
|
padding-left: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.visible-sidebar #page-media & {
|
body.sliding-sidebar & {
|
||||||
padding-left: 0;
|
transition-property: padding-left;
|
||||||
}
|
transition-duration: 0.2s;
|
||||||
|
|
||||||
.visible-sidebar & {
|
|
||||||
#page-media {
|
|
||||||
padding-left: 0;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
body.sliding-sidebar & {
|
.embedded-app & {
|
||||||
transition-property: padding-left;
|
padding-top: 0;
|
||||||
transition-duration: 0.2s;
|
padding-left: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#page-profile-media,
|
#page-profile-media,
|
||||||
@@ -30,20 +35,20 @@
|
|||||||
#page-profile-about,
|
#page-profile-about,
|
||||||
#page-liked.profile-page-liked,
|
#page-liked.profile-page-liked,
|
||||||
#page-history.profile-page-history {
|
#page-history.profile-page-history {
|
||||||
.page-main {
|
.page-main {
|
||||||
min-height: calc(100vh - var(--header-height));
|
min-height: calc(100vh - var(--header-height));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-main {
|
.page-main {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding-bottom: 16px;
|
padding-bottom: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-main-inner {
|
.page-main-inner {
|
||||||
display: block;
|
display: block;
|
||||||
margin: 1em 1em 0 1em;
|
margin: 1em 1em 0 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#page-profile-media,
|
#page-profile-media,
|
||||||
@@ -51,7 +56,7 @@
|
|||||||
#page-profile-about,
|
#page-profile-about,
|
||||||
#page-liked.profile-page-liked,
|
#page-liked.profile-page-liked,
|
||||||
#page-history.profile-page-history {
|
#page-history.profile-page-history {
|
||||||
.page-main-wrap {
|
.page-main-wrap {
|
||||||
background-color: var(--body-bg-color);
|
background-color: var(--body-bg-color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import UrlParse from 'url-parse';
|
import UrlParse from 'url-parse';
|
||||||
import { ApiUrlContext, MemberContext, SiteContext } from '../utils/contexts/';
|
import { ApiUrlContext, MemberContext, SiteContext } from '../utils/contexts/';
|
||||||
import { formatInnerLink, csrfToken, postRequest } from '../utils/helpers/';
|
import { formatInnerLink, csrfToken, postRequest, inEmbeddedApp } from '../utils/helpers/';
|
||||||
import { PageActions } from '../utils/actions/';
|
import { PageActions } from '../utils/actions/';
|
||||||
import { PageStore, ProfilePageStore } from '../utils/stores/';
|
import { PageStore, ProfilePageStore } from '../utils/stores/';
|
||||||
import ProfilePagesHeader from '../components/profile-page/ProfilePagesHeader';
|
import ProfilePagesHeader from '../components/profile-page/ProfilePagesHeader';
|
||||||
@@ -268,7 +268,7 @@ export class ProfileAboutPage extends ProfileMediaPage {
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
this.state.author ? (
|
this.state.author ? (
|
||||||
<ProfilePagesHeader key="ProfilePagesHeader" author={this.state.author} type="about" />
|
<ProfilePagesHeader key="ProfilePagesHeader" author={this.state.author} type="about" hideChannelBanner={inEmbeddedApp()} />
|
||||||
) : null,
|
) : null,
|
||||||
this.state.author ? (
|
this.state.author ? (
|
||||||
<ProfilePagesContent key="ProfilePagesContent" enabledContactForm={this.enabledContactForm}>
|
<ProfilePagesContent key="ProfilePagesContent" enabledContactForm={this.enabledContactForm}>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import React from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { ApiUrlConsumer } from '../utils/contexts/';
|
import { ApiUrlConsumer } from '../utils/contexts/';
|
||||||
import { PageStore } from '../utils/stores/';
|
import { PageStore } from '../utils/stores/';
|
||||||
|
import { inEmbeddedApp } from '../utils/helpers/';
|
||||||
import { MediaListWrapper } from '../components/MediaListWrapper';
|
import { MediaListWrapper } from '../components/MediaListWrapper';
|
||||||
import ProfilePagesHeader from '../components/profile-page/ProfilePagesHeader';
|
import ProfilePagesHeader from '../components/profile-page/ProfilePagesHeader';
|
||||||
import ProfilePagesContent from '../components/profile-page/ProfilePagesContent';
|
import ProfilePagesContent from '../components/profile-page/ProfilePagesContent';
|
||||||
@@ -28,7 +29,7 @@ export class ProfileHistoryPage extends ProfileMediaPage {
|
|||||||
pageContent() {
|
pageContent() {
|
||||||
return [
|
return [
|
||||||
this.state.author ? (
|
this.state.author ? (
|
||||||
<ProfilePagesHeader key="ProfilePagesHeader" author={this.state.author} type="history" />
|
<ProfilePagesHeader key="ProfilePagesHeader" author={this.state.author} type="history" hideChannelBanner={inEmbeddedApp()} />
|
||||||
) : null,
|
) : null,
|
||||||
this.state.author ? (
|
this.state.author ? (
|
||||||
<ProfilePagesContent key="ProfilePagesContent">
|
<ProfilePagesContent key="ProfilePagesContent">
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import React from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { ApiUrlConsumer } from '../utils/contexts/';
|
import { ApiUrlConsumer } from '../utils/contexts/';
|
||||||
import { PageStore } from '../utils/stores/';
|
import { PageStore } from '../utils/stores/';
|
||||||
|
import { inEmbeddedApp } from '../utils/helpers/';
|
||||||
import { MediaListWrapper } from '../components/MediaListWrapper';
|
import { MediaListWrapper } from '../components/MediaListWrapper';
|
||||||
import ProfilePagesHeader from '../components/profile-page/ProfilePagesHeader';
|
import ProfilePagesHeader from '../components/profile-page/ProfilePagesHeader';
|
||||||
import ProfilePagesContent from '../components/profile-page/ProfilePagesContent';
|
import ProfilePagesContent from '../components/profile-page/ProfilePagesContent';
|
||||||
@@ -28,7 +29,7 @@ export class ProfileLikedPage extends ProfileMediaPage {
|
|||||||
pageContent() {
|
pageContent() {
|
||||||
return [
|
return [
|
||||||
this.state.author ? (
|
this.state.author ? (
|
||||||
<ProfilePagesHeader key="ProfilePagesHeader" author={this.state.author} type="liked" />
|
<ProfilePagesHeader key="ProfilePagesHeader" author={this.state.author} type="liked" hideChannelBanner={inEmbeddedApp()} />
|
||||||
) : null,
|
) : null,
|
||||||
this.state.author ? (
|
this.state.author ? (
|
||||||
<ProfilePagesContent key="ProfilePagesContent">
|
<ProfilePagesContent key="ProfilePagesContent">
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ApiUrlConsumer } from '../utils/contexts/';
|
import { ApiUrlConsumer } from '../utils/contexts/';
|
||||||
import { PageStore } from '../utils/stores/';
|
import { PageStore } from '../utils/stores/';
|
||||||
|
import { inEmbeddedApp } from '../utils/helpers/';
|
||||||
import { MediaListWrapper } from '../components/MediaListWrapper';
|
import { MediaListWrapper } from '../components/MediaListWrapper';
|
||||||
import ProfilePagesHeader from '../components/profile-page/ProfilePagesHeader';
|
import ProfilePagesHeader from '../components/profile-page/ProfilePagesHeader';
|
||||||
import ProfilePagesContent from '../components/profile-page/ProfilePagesContent';
|
import ProfilePagesContent from '../components/profile-page/ProfilePagesContent';
|
||||||
@@ -30,7 +31,7 @@ export class ProfilePlaylistsPage extends ProfileMediaPage {
|
|||||||
pageContent() {
|
pageContent() {
|
||||||
return [
|
return [
|
||||||
this.state.author ? (
|
this.state.author ? (
|
||||||
<ProfilePagesHeader key="ProfilePagesHeader" author={this.state.author} type="playlists" />
|
<ProfilePagesHeader key="ProfilePagesHeader" author={this.state.author} type="playlists" hideChannelBanner={inEmbeddedApp()} />
|
||||||
) : null,
|
) : null,
|
||||||
this.state.author ? (
|
this.state.author ? (
|
||||||
<ProfilePagesContent key="ProfilePagesContent">
|
<ProfilePagesContent key="ProfilePagesContent">
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { ProfileMediaFilters } from '../components/search-filters/ProfileMediaFi
|
|||||||
import { ProfileMediaTags } from '../components/search-filters/ProfileMediaTags';
|
import { ProfileMediaTags } from '../components/search-filters/ProfileMediaTags';
|
||||||
import { ProfileMediaSorting } from '../components/search-filters/ProfileMediaSorting';
|
import { ProfileMediaSorting } from '../components/search-filters/ProfileMediaSorting';
|
||||||
import { BulkActionsModals } from '../components/BulkActionsModals';
|
import { BulkActionsModals } from '../components/BulkActionsModals';
|
||||||
import { translateString } from '../utils/helpers';
|
import { inEmbeddedApp, translateString } from '../utils/helpers';
|
||||||
import { withBulkActions } from '../utils/hoc/withBulkActions';
|
import { withBulkActions } from '../utils/hoc/withBulkActions';
|
||||||
|
|
||||||
import { Page } from './_Page';
|
import { Page } from './_Page';
|
||||||
@@ -19,400 +19,443 @@ import { Page } from './_Page';
|
|||||||
import '../components/profile-page/ProfilePage.scss';
|
import '../components/profile-page/ProfilePage.scss';
|
||||||
|
|
||||||
function EmptySharedByMe(props) {
|
function EmptySharedByMe(props) {
|
||||||
return (
|
return (
|
||||||
<LinksConsumer>
|
<LinksConsumer>
|
||||||
{(links) => (
|
{(links) => (
|
||||||
<div className="empty-media empty-channel-media">
|
<div className="empty-media empty-channel-media">
|
||||||
<div className="welcome-title">No shared media</div>
|
<div className="welcome-title">No shared media</div>
|
||||||
<div className="start-uploading">
|
<div className="start-uploading">Media that you have shared with others will show up here.</div>
|
||||||
Media that you have shared with others will show up here.
|
</div>
|
||||||
</div>
|
)}
|
||||||
</div>
|
</LinksConsumer>
|
||||||
)}
|
);
|
||||||
</LinksConsumer>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ProfileSharedByMePage extends Page {
|
class ProfileSharedByMePage extends Page {
|
||||||
constructor(props, pageSlug) {
|
constructor(props, pageSlug) {
|
||||||
super(props, 'string' === typeof pageSlug ? pageSlug : 'author-shared-by-me');
|
super(props, 'string' === typeof pageSlug ? pageSlug : 'author-shared-by-me');
|
||||||
|
|
||||||
this.profilePageSlug = 'string' === typeof pageSlug ? pageSlug : 'author-shared-by-me';
|
this.profilePageSlug = 'string' === typeof pageSlug ? pageSlug : 'author-shared-by-me';
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
channelMediaCount: -1,
|
channelMediaCount: -1,
|
||||||
author: ProfilePageStore.get('author-data'),
|
author: ProfilePageStore.get('author-data'),
|
||||||
uploadsPreviewItemsCount: 0,
|
uploadsPreviewItemsCount: 0,
|
||||||
title: this.props.title,
|
title: this.props.title,
|
||||||
query: ProfilePageStore.get('author-query'),
|
query: ProfilePageStore.get('author-query'),
|
||||||
requestUrl: null,
|
requestUrl: null,
|
||||||
hiddenFilters: true,
|
hiddenFilters: true,
|
||||||
hiddenTags: true,
|
hiddenTags: true,
|
||||||
hiddenSorting: true,
|
hiddenSorting: true,
|
||||||
filterArgs: '',
|
filterArgs: '',
|
||||||
availableTags: [],
|
availableTags: [],
|
||||||
selectedTag: 'all',
|
selectedTag: 'all',
|
||||||
selectedSort: 'date_added_desc',
|
selectedSort: 'date_added_desc',
|
||||||
};
|
};
|
||||||
|
|
||||||
this.authorDataLoad = this.authorDataLoad.bind(this);
|
this.authorDataLoad = this.authorDataLoad.bind(this);
|
||||||
this.onAuthorPreviewItemsCountCallback = this.onAuthorPreviewItemsCountCallback.bind(this);
|
this.onAuthorPreviewItemsCountCallback = this.onAuthorPreviewItemsCountCallback.bind(this);
|
||||||
this.getCountFunc = this.getCountFunc.bind(this);
|
this.getCountFunc = this.getCountFunc.bind(this);
|
||||||
this.changeRequestQuery = this.changeRequestQuery.bind(this);
|
this.changeRequestQuery = this.changeRequestQuery.bind(this);
|
||||||
this.onToggleFiltersClick = this.onToggleFiltersClick.bind(this);
|
this.onToggleFiltersClick = this.onToggleFiltersClick.bind(this);
|
||||||
this.onToggleTagsClick = this.onToggleTagsClick.bind(this);
|
this.onToggleTagsClick = this.onToggleTagsClick.bind(this);
|
||||||
this.onToggleSortingClick = this.onToggleSortingClick.bind(this);
|
this.onToggleSortingClick = this.onToggleSortingClick.bind(this);
|
||||||
this.onFiltersUpdate = this.onFiltersUpdate.bind(this);
|
this.onFiltersUpdate = this.onFiltersUpdate.bind(this);
|
||||||
this.onTagSelect = this.onTagSelect.bind(this);
|
this.onTagSelect = this.onTagSelect.bind(this);
|
||||||
this.onSortSelect = this.onSortSelect.bind(this);
|
this.onSortSelect = this.onSortSelect.bind(this);
|
||||||
this.onResponseDataLoaded = this.onResponseDataLoaded.bind(this);
|
this.onResponseDataLoaded = this.onResponseDataLoaded.bind(this);
|
||||||
|
|
||||||
ProfilePageStore.on('load-author-data', this.authorDataLoad);
|
ProfilePageStore.on('load-author-data', this.authorDataLoad);
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
ProfilePageActions.load_author_data();
|
|
||||||
}
|
|
||||||
|
|
||||||
authorDataLoad() {
|
|
||||||
const author = ProfilePageStore.get('author-data');
|
|
||||||
|
|
||||||
let requestUrl = this.state.requestUrl;
|
|
||||||
|
|
||||||
if (author) {
|
|
||||||
if (this.state.query) {
|
|
||||||
requestUrl = ApiUrlContext._currentValue.media + '?author=' + author.id + '&show=shared_by_me&q=' + encodeURIComponent(this.state.query) + this.state.filterArgs;
|
|
||||||
} else {
|
|
||||||
requestUrl = ApiUrlContext._currentValue.media + '?author=' + author.id + '&show=shared_by_me' + this.state.filterArgs;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
componentDidMount() {
|
||||||
author: author,
|
ProfilePageActions.load_author_data();
|
||||||
requestUrl: requestUrl,
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onAuthorPreviewItemsCountCallback(totalAuthorPreviewItems) {
|
authorDataLoad() {
|
||||||
this.setState({
|
const author = ProfilePageStore.get('author-data');
|
||||||
uploadsPreviewItemsCount: totalAuthorPreviewItems,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getCountFunc(count) {
|
let requestUrl = this.state.requestUrl;
|
||||||
this.setState(
|
|
||||||
{
|
|
||||||
channelMediaCount: count,
|
|
||||||
},
|
|
||||||
() => {
|
|
||||||
if (this.state.query) {
|
|
||||||
let title = '';
|
|
||||||
|
|
||||||
if (!count) {
|
if (author) {
|
||||||
title = 'No results for "' + this.state.query + '"';
|
if (this.state.query) {
|
||||||
} else if (1 === count) {
|
requestUrl =
|
||||||
title = '1 result for "' + this.state.query + '"';
|
ApiUrlContext._currentValue.media +
|
||||||
} else {
|
'?author=' +
|
||||||
title = count + ' results for "' + this.state.query + '"';
|
author.id +
|
||||||
}
|
'&show=shared_by_me&q=' +
|
||||||
|
encodeURIComponent(this.state.query) +
|
||||||
this.setState({
|
this.state.filterArgs;
|
||||||
title: title,
|
} else {
|
||||||
});
|
requestUrl =
|
||||||
|
ApiUrlContext._currentValue.media +
|
||||||
|
'?author=' +
|
||||||
|
author.id +
|
||||||
|
'&show=shared_by_me' +
|
||||||
|
this.state.filterArgs;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
changeRequestQuery(newQuery) {
|
this.setState({
|
||||||
if (!this.state.author) {
|
author: author,
|
||||||
return;
|
requestUrl: requestUrl,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let requestUrl;
|
onAuthorPreviewItemsCountCallback(totalAuthorPreviewItems) {
|
||||||
|
this.setState({
|
||||||
if (newQuery) {
|
uploadsPreviewItemsCount: totalAuthorPreviewItems,
|
||||||
requestUrl = ApiUrlContext._currentValue.media + '?author=' + this.state.author.id + '&show=shared_by_me&q=' + encodeURIComponent(newQuery) + this.state.filterArgs;
|
});
|
||||||
} else {
|
|
||||||
requestUrl = ApiUrlContext._currentValue.media + '?author=' + this.state.author.id + '&show=shared_by_me' + this.state.filterArgs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let title = this.state.title;
|
getCountFunc(count) {
|
||||||
|
this.setState(
|
||||||
|
{
|
||||||
|
channelMediaCount: count,
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
if (this.state.query) {
|
||||||
|
let title = '';
|
||||||
|
|
||||||
if ('' === newQuery) {
|
if (!count) {
|
||||||
title = this.props.title;
|
title = 'No results for "' + this.state.query + '"';
|
||||||
|
} else if (1 === count) {
|
||||||
|
title = '1 result for "' + this.state.query + '"';
|
||||||
|
} else {
|
||||||
|
title = count + ' results for "' + this.state.query + '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
title: title,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
changeRequestQuery(newQuery) {
|
||||||
requestUrl: requestUrl,
|
|
||||||
query: newQuery,
|
|
||||||
title: title,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onToggleFiltersClick() {
|
|
||||||
this.setState({
|
|
||||||
hiddenFilters: !this.state.hiddenFilters,
|
|
||||||
hiddenTags: true,
|
|
||||||
hiddenSorting: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onToggleTagsClick() {
|
|
||||||
this.setState({
|
|
||||||
hiddenFilters: true,
|
|
||||||
hiddenTags: !this.state.hiddenTags,
|
|
||||||
hiddenSorting: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onToggleSortingClick() {
|
|
||||||
this.setState({
|
|
||||||
hiddenFilters: true,
|
|
||||||
hiddenTags: true,
|
|
||||||
hiddenSorting: !this.state.hiddenSorting,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onTagSelect(tag) {
|
|
||||||
this.setState({ selectedTag: tag }, () => {
|
|
||||||
this.onFiltersUpdate({
|
|
||||||
media_type: this.state.filterArgs.match(/media_type=([^&]+)/)?.[1],
|
|
||||||
upload_date: this.state.filterArgs.match(/upload_date=([^&]+)/)?.[1],
|
|
||||||
duration: this.state.filterArgs.match(/duration=([^&]+)/)?.[1],
|
|
||||||
publish_state: this.state.filterArgs.match(/publish_state=([^&]+)/)?.[1],
|
|
||||||
sort_by: this.state.selectedSort,
|
|
||||||
tag: tag,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onSortSelect(sortBy) {
|
|
||||||
this.setState({ selectedSort: sortBy }, () => {
|
|
||||||
this.onFiltersUpdate({
|
|
||||||
media_type: this.state.filterArgs.match(/media_type=([^&]+)/)?.[1],
|
|
||||||
upload_date: this.state.filterArgs.match(/upload_date=([^&]+)/)?.[1],
|
|
||||||
duration: this.state.filterArgs.match(/duration=([^&]+)/)?.[1],
|
|
||||||
publish_state: this.state.filterArgs.match(/publish_state=([^&]+)/)?.[1],
|
|
||||||
sort_by: sortBy,
|
|
||||||
tag: this.state.selectedTag,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onFiltersUpdate(updatedArgs) {
|
|
||||||
const args = {
|
|
||||||
media_type: null,
|
|
||||||
upload_date: null,
|
|
||||||
duration: null,
|
|
||||||
publish_state: null,
|
|
||||||
sort_by: null,
|
|
||||||
ordering: null,
|
|
||||||
t: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
switch (updatedArgs.media_type) {
|
|
||||||
case 'video':
|
|
||||||
case 'audio':
|
|
||||||
case 'image':
|
|
||||||
case 'pdf':
|
|
||||||
args.media_type = updatedArgs.media_type;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (updatedArgs.upload_date) {
|
|
||||||
case 'today':
|
|
||||||
case 'this_week':
|
|
||||||
case 'this_month':
|
|
||||||
case 'this_year':
|
|
||||||
args.upload_date = updatedArgs.upload_date;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle duration filter
|
|
||||||
if (updatedArgs.duration && updatedArgs.duration !== 'all') {
|
|
||||||
args.duration = updatedArgs.duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle publish state filter
|
|
||||||
if (updatedArgs.publish_state && updatedArgs.publish_state !== 'all') {
|
|
||||||
args.publish_state = updatedArgs.publish_state;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (updatedArgs.sort_by) {
|
|
||||||
case 'date_added_desc':
|
|
||||||
// Default sorting, no need to add parameters
|
|
||||||
break;
|
|
||||||
case 'date_added_asc':
|
|
||||||
args.ordering = 'asc';
|
|
||||||
break;
|
|
||||||
case 'alphabetically_asc':
|
|
||||||
args.sort_by = 'title_asc';
|
|
||||||
break;
|
|
||||||
case 'alphabetically_desc':
|
|
||||||
args.sort_by = 'title_desc';
|
|
||||||
break;
|
|
||||||
case 'plays_least':
|
|
||||||
args.sort_by = 'views_asc';
|
|
||||||
break;
|
|
||||||
case 'plays_most':
|
|
||||||
args.sort_by = 'views_desc';
|
|
||||||
break;
|
|
||||||
case 'likes_least':
|
|
||||||
args.sort_by = 'likes_asc';
|
|
||||||
break;
|
|
||||||
case 'likes_most':
|
|
||||||
args.sort_by = 'likes_desc';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (updatedArgs.tag && updatedArgs.tag !== 'all') {
|
|
||||||
args.t = updatedArgs.tag;
|
|
||||||
}
|
|
||||||
|
|
||||||
const newArgs = [];
|
|
||||||
|
|
||||||
for (let arg in args) {
|
|
||||||
if (null !== args[arg]) {
|
|
||||||
newArgs.push(arg + '=' + args[arg]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState(
|
|
||||||
{
|
|
||||||
filterArgs: newArgs.length ? '&' + newArgs.join('&') : '',
|
|
||||||
},
|
|
||||||
function () {
|
|
||||||
if (!this.state.author) {
|
if (!this.state.author) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let requestUrl;
|
let requestUrl;
|
||||||
|
|
||||||
if (this.state.query) {
|
if (newQuery) {
|
||||||
requestUrl = ApiUrlContext._currentValue.media + '?author=' + this.state.author.id + '&show=shared_by_me&q=' + encodeURIComponent(this.state.query) + this.state.filterArgs;
|
requestUrl =
|
||||||
|
ApiUrlContext._currentValue.media +
|
||||||
|
'?author=' +
|
||||||
|
this.state.author.id +
|
||||||
|
'&show=shared_by_me&q=' +
|
||||||
|
encodeURIComponent(newQuery) +
|
||||||
|
this.state.filterArgs;
|
||||||
} else {
|
} else {
|
||||||
requestUrl = ApiUrlContext._currentValue.media + '?author=' + this.state.author.id + '&show=shared_by_me' + this.state.filterArgs;
|
requestUrl =
|
||||||
|
ApiUrlContext._currentValue.media +
|
||||||
|
'?author=' +
|
||||||
|
this.state.author.id +
|
||||||
|
'&show=shared_by_me' +
|
||||||
|
this.state.filterArgs;
|
||||||
|
}
|
||||||
|
|
||||||
|
let title = this.state.title;
|
||||||
|
|
||||||
|
if ('' === newQuery) {
|
||||||
|
title = this.props.title;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
requestUrl: requestUrl,
|
requestUrl: requestUrl,
|
||||||
|
query: newQuery,
|
||||||
|
title: title,
|
||||||
});
|
});
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
onResponseDataLoaded(responseData) {
|
|
||||||
if (responseData && responseData.tags) {
|
|
||||||
const tags = responseData.tags.split(',').map((tag) => tag.trim()).filter((tag) => tag);
|
|
||||||
this.setState({ availableTags: tags });
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pageContent() {
|
onToggleFiltersClick() {
|
||||||
const authorData = ProfilePageStore.get('author-data');
|
this.setState({
|
||||||
|
hiddenFilters: !this.state.hiddenFilters,
|
||||||
|
hiddenTags: true,
|
||||||
|
hiddenSorting: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const isMediaAuthor = authorData && authorData.username === MemberContext._currentValue.username;
|
onToggleTagsClick() {
|
||||||
|
this.setState({
|
||||||
|
hiddenFilters: true,
|
||||||
|
hiddenTags: !this.state.hiddenTags,
|
||||||
|
hiddenSorting: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Check if any filters are active
|
onToggleSortingClick() {
|
||||||
const hasActiveFilters = this.state.filterArgs && (
|
this.setState({
|
||||||
this.state.filterArgs.includes('media_type=') ||
|
hiddenFilters: true,
|
||||||
this.state.filterArgs.includes('upload_date=') ||
|
hiddenTags: true,
|
||||||
this.state.filterArgs.includes('duration=') ||
|
hiddenSorting: !this.state.hiddenSorting,
|
||||||
this.state.filterArgs.includes('publish_state=')
|
});
|
||||||
);
|
}
|
||||||
|
|
||||||
return [
|
onTagSelect(tag) {
|
||||||
this.state.author ? (
|
this.setState({ selectedTag: tag }, () => {
|
||||||
<ProfilePagesHeader
|
this.onFiltersUpdate({
|
||||||
key="ProfilePagesHeader"
|
media_type: this.state.filterArgs.match(/media_type=([^&]+)/)?.[1],
|
||||||
author={this.state.author}
|
upload_date: this.state.filterArgs.match(/upload_date=([^&]+)/)?.[1],
|
||||||
type="shared_by_me"
|
duration: this.state.filterArgs.match(/duration=([^&]+)/)?.[1],
|
||||||
onQueryChange={this.changeRequestQuery}
|
publish_state: this.state.filterArgs.match(/publish_state=([^&]+)/)?.[1],
|
||||||
onToggleFiltersClick={this.onToggleFiltersClick}
|
sort_by: this.state.selectedSort,
|
||||||
onToggleTagsClick={this.onToggleTagsClick}
|
tag: tag,
|
||||||
onToggleSortingClick={this.onToggleSortingClick}
|
});
|
||||||
hasActiveFilters={hasActiveFilters}
|
});
|
||||||
hasActiveTags={this.state.selectedTag !== 'all'}
|
}
|
||||||
hasActiveSort={this.state.selectedSort !== 'date_added_desc'}
|
|
||||||
/>
|
onSortSelect(sortBy) {
|
||||||
) : null,
|
this.setState({ selectedSort: sortBy }, () => {
|
||||||
this.state.author ? (
|
this.onFiltersUpdate({
|
||||||
<ProfilePagesContent key="ProfilePagesContent">
|
media_type: this.state.filterArgs.match(/media_type=([^&]+)/)?.[1],
|
||||||
<MediaListWrapper
|
upload_date: this.state.filterArgs.match(/upload_date=([^&]+)/)?.[1],
|
||||||
title={this.state.title}
|
duration: this.state.filterArgs.match(/duration=([^&]+)/)?.[1],
|
||||||
className="items-list-ver"
|
publish_state: this.state.filterArgs.match(/publish_state=([^&]+)/)?.[1],
|
||||||
showBulkActions={isMediaAuthor}
|
sort_by: sortBy,
|
||||||
selectedCount={this.props.bulkActions.selectedMedia.size}
|
tag: this.state.selectedTag,
|
||||||
totalCount={this.props.bulkActions.availableMediaIds.length}
|
});
|
||||||
onBulkAction={this.props.bulkActions.handleBulkAction}
|
});
|
||||||
onSelectAll={this.props.bulkActions.handleSelectAll}
|
}
|
||||||
onDeselectAll={this.props.bulkActions.handleDeselectAll}
|
|
||||||
>
|
onFiltersUpdate(updatedArgs) {
|
||||||
<ProfileMediaFilters hidden={this.state.hiddenFilters} tags={this.state.availableTags} onFiltersUpdate={this.onFiltersUpdate} />
|
const args = {
|
||||||
<ProfileMediaTags hidden={this.state.hiddenTags} tags={this.state.availableTags} onTagSelect={this.onTagSelect} />
|
media_type: null,
|
||||||
<ProfileMediaSorting hidden={this.state.hiddenSorting} onSortSelect={this.onSortSelect} />
|
upload_date: null,
|
||||||
<LazyLoadItemListAsync
|
duration: null,
|
||||||
key={`${this.state.requestUrl}-${this.props.bulkActions.listKey}`}
|
publish_state: null,
|
||||||
requestUrl={this.state.requestUrl}
|
sort_by: null,
|
||||||
hideAuthor={true}
|
ordering: null,
|
||||||
itemsCountCallback={this.state.requestUrl ? this.getCountFunc : null}
|
t: null,
|
||||||
hideViews={!PageStore.get('config-media-item').displayViews}
|
};
|
||||||
hideDate={!PageStore.get('config-media-item').displayPublishDate}
|
|
||||||
canEdit={isMediaAuthor}
|
switch (updatedArgs.media_type) {
|
||||||
onResponseDataLoaded={this.onResponseDataLoaded}
|
case 'video':
|
||||||
showSelection={isMediaAuthor}
|
case 'audio':
|
||||||
hasAnySelection={this.props.bulkActions.selectedMedia.size > 0}
|
case 'image':
|
||||||
selectedMedia={this.props.bulkActions.selectedMedia}
|
case 'pdf':
|
||||||
onMediaSelection={this.props.bulkActions.handleMediaSelection}
|
args.media_type = updatedArgs.media_type;
|
||||||
onItemsUpdate={this.props.bulkActions.handleItemsUpdate}
|
break;
|
||||||
/>
|
}
|
||||||
{isMediaAuthor && 0 === this.state.channelMediaCount && !this.state.query ? (
|
|
||||||
<EmptySharedByMe name={this.state.author.name} />
|
switch (updatedArgs.upload_date) {
|
||||||
) : null}
|
case 'today':
|
||||||
</MediaListWrapper>
|
case 'this_week':
|
||||||
</ProfilePagesContent>
|
case 'this_month':
|
||||||
) : null,
|
case 'this_year':
|
||||||
this.state.author && isMediaAuthor ? (
|
args.upload_date = updatedArgs.upload_date;
|
||||||
<BulkActionsModals
|
break;
|
||||||
key="BulkActionsModals"
|
}
|
||||||
{...this.props.bulkActions}
|
|
||||||
selectedMediaIds={Array.from(this.props.bulkActions.selectedMedia)}
|
// Handle duration filter
|
||||||
csrfToken={this.props.bulkActions.getCsrfToken()}
|
if (updatedArgs.duration && updatedArgs.duration !== 'all') {
|
||||||
username={this.state.author.username}
|
args.duration = updatedArgs.duration;
|
||||||
onConfirmCancel={this.props.bulkActions.handleConfirmCancel}
|
}
|
||||||
onConfirmProceed={this.props.bulkActions.handleConfirmProceed}
|
|
||||||
onPermissionModalCancel={this.props.bulkActions.handlePermissionModalCancel}
|
// Handle publish state filter
|
||||||
onPermissionModalSuccess={this.props.bulkActions.handlePermissionModalSuccess}
|
if (updatedArgs.publish_state && updatedArgs.publish_state !== 'all') {
|
||||||
onPermissionModalError={this.props.bulkActions.handlePermissionModalError}
|
args.publish_state = updatedArgs.publish_state;
|
||||||
onPlaylistModalCancel={this.props.bulkActions.handlePlaylistModalCancel}
|
}
|
||||||
onPlaylistModalSuccess={this.props.bulkActions.handlePlaylistModalSuccess}
|
|
||||||
onPlaylistModalError={this.props.bulkActions.handlePlaylistModalError}
|
switch (updatedArgs.sort_by) {
|
||||||
onChangeOwnerModalCancel={this.props.bulkActions.handleChangeOwnerModalCancel}
|
case 'date_added_desc':
|
||||||
onChangeOwnerModalSuccess={this.props.bulkActions.handleChangeOwnerModalSuccess}
|
// Default sorting, no need to add parameters
|
||||||
onChangeOwnerModalError={this.props.bulkActions.handleChangeOwnerModalError}
|
break;
|
||||||
onPublishStateModalCancel={this.props.bulkActions.handlePublishStateModalCancel}
|
case 'date_added_asc':
|
||||||
onPublishStateModalSuccess={this.props.bulkActions.handlePublishStateModalSuccess}
|
args.ordering = 'asc';
|
||||||
onPublishStateModalError={this.props.bulkActions.handlePublishStateModalError}
|
break;
|
||||||
onCategoryModalCancel={this.props.bulkActions.handleCategoryModalCancel}
|
case 'alphabetically_asc':
|
||||||
onCategoryModalSuccess={this.props.bulkActions.handleCategoryModalSuccess}
|
args.sort_by = 'title_asc';
|
||||||
onCategoryModalError={this.props.bulkActions.handleCategoryModalError}
|
break;
|
||||||
onTagModalCancel={this.props.bulkActions.handleTagModalCancel}
|
case 'alphabetically_desc':
|
||||||
onTagModalSuccess={this.props.bulkActions.handleTagModalSuccess}
|
args.sort_by = 'title_desc';
|
||||||
onTagModalError={this.props.bulkActions.handleTagModalError}
|
break;
|
||||||
/>
|
case 'plays_least':
|
||||||
) : null,
|
args.sort_by = 'views_asc';
|
||||||
];
|
break;
|
||||||
}
|
case 'plays_most':
|
||||||
|
args.sort_by = 'views_desc';
|
||||||
|
break;
|
||||||
|
case 'likes_least':
|
||||||
|
args.sort_by = 'likes_asc';
|
||||||
|
break;
|
||||||
|
case 'likes_most':
|
||||||
|
args.sort_by = 'likes_desc';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updatedArgs.tag && updatedArgs.tag !== 'all') {
|
||||||
|
args.t = updatedArgs.tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
const newArgs = [];
|
||||||
|
|
||||||
|
for (let arg in args) {
|
||||||
|
if (null !== args[arg]) {
|
||||||
|
newArgs.push(arg + '=' + args[arg]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState(
|
||||||
|
{
|
||||||
|
filterArgs: newArgs.length ? '&' + newArgs.join('&') : '',
|
||||||
|
},
|
||||||
|
function () {
|
||||||
|
if (!this.state.author) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let requestUrl;
|
||||||
|
|
||||||
|
if (this.state.query) {
|
||||||
|
requestUrl =
|
||||||
|
ApiUrlContext._currentValue.media +
|
||||||
|
'?author=' +
|
||||||
|
this.state.author.id +
|
||||||
|
'&show=shared_by_me&q=' +
|
||||||
|
encodeURIComponent(this.state.query) +
|
||||||
|
this.state.filterArgs;
|
||||||
|
} else {
|
||||||
|
requestUrl =
|
||||||
|
ApiUrlContext._currentValue.media +
|
||||||
|
'?author=' +
|
||||||
|
this.state.author.id +
|
||||||
|
'&show=shared_by_me' +
|
||||||
|
this.state.filterArgs;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
requestUrl: requestUrl,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
onResponseDataLoaded(responseData) {
|
||||||
|
if (responseData && responseData.tags) {
|
||||||
|
const tags = responseData.tags
|
||||||
|
.split(',')
|
||||||
|
.map((tag) => tag.trim())
|
||||||
|
.filter((tag) => tag);
|
||||||
|
this.setState({ availableTags: tags });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pageContent() {
|
||||||
|
const authorData = ProfilePageStore.get('author-data');
|
||||||
|
|
||||||
|
const isMediaAuthor = authorData && authorData.username === MemberContext._currentValue.username;
|
||||||
|
|
||||||
|
// Check if any filters are active
|
||||||
|
const hasActiveFilters =
|
||||||
|
this.state.filterArgs &&
|
||||||
|
(this.state.filterArgs.includes('media_type=') ||
|
||||||
|
this.state.filterArgs.includes('upload_date=') ||
|
||||||
|
this.state.filterArgs.includes('duration=') ||
|
||||||
|
this.state.filterArgs.includes('publish_state='));
|
||||||
|
|
||||||
|
return [
|
||||||
|
this.state.author ? (
|
||||||
|
<ProfilePagesHeader
|
||||||
|
key="ProfilePagesHeader"
|
||||||
|
author={this.state.author}
|
||||||
|
type="shared_by_me"
|
||||||
|
onQueryChange={this.changeRequestQuery}
|
||||||
|
onToggleFiltersClick={this.onToggleFiltersClick}
|
||||||
|
onToggleTagsClick={this.onToggleTagsClick}
|
||||||
|
onToggleSortingClick={this.onToggleSortingClick}
|
||||||
|
hasActiveFilters={hasActiveFilters}
|
||||||
|
hasActiveTags={this.state.selectedTag !== 'all'}
|
||||||
|
hasActiveSort={this.state.selectedSort !== 'date_added_desc'}
|
||||||
|
hideChannelBanner={inEmbeddedApp()}
|
||||||
|
/>
|
||||||
|
) : null,
|
||||||
|
this.state.author ? (
|
||||||
|
<ProfilePagesContent key="ProfilePagesContent">
|
||||||
|
<MediaListWrapper
|
||||||
|
title={this.state.title}
|
||||||
|
className="items-list-ver"
|
||||||
|
showBulkActions={isMediaAuthor}
|
||||||
|
selectedCount={this.props.bulkActions.selectedMedia.size}
|
||||||
|
totalCount={this.props.bulkActions.availableMediaIds.length}
|
||||||
|
onBulkAction={this.props.bulkActions.handleBulkAction}
|
||||||
|
onSelectAll={this.props.bulkActions.handleSelectAll}
|
||||||
|
onDeselectAll={this.props.bulkActions.handleDeselectAll}
|
||||||
|
>
|
||||||
|
<ProfileMediaFilters
|
||||||
|
hidden={this.state.hiddenFilters}
|
||||||
|
tags={this.state.availableTags}
|
||||||
|
onFiltersUpdate={this.onFiltersUpdate}
|
||||||
|
/>
|
||||||
|
<ProfileMediaTags
|
||||||
|
hidden={this.state.hiddenTags}
|
||||||
|
tags={this.state.availableTags}
|
||||||
|
onTagSelect={this.onTagSelect}
|
||||||
|
/>
|
||||||
|
<ProfileMediaSorting hidden={this.state.hiddenSorting} onSortSelect={this.onSortSelect} />
|
||||||
|
<LazyLoadItemListAsync
|
||||||
|
key={`${this.state.requestUrl}-${this.props.bulkActions.listKey}`}
|
||||||
|
requestUrl={this.state.requestUrl}
|
||||||
|
hideAuthor={true}
|
||||||
|
itemsCountCallback={this.state.requestUrl ? this.getCountFunc : null}
|
||||||
|
hideViews={!PageStore.get('config-media-item').displayViews}
|
||||||
|
hideDate={!PageStore.get('config-media-item').displayPublishDate}
|
||||||
|
canEdit={isMediaAuthor}
|
||||||
|
onResponseDataLoaded={this.onResponseDataLoaded}
|
||||||
|
showSelection={isMediaAuthor}
|
||||||
|
hasAnySelection={this.props.bulkActions.selectedMedia.size > 0}
|
||||||
|
selectedMedia={this.props.bulkActions.selectedMedia}
|
||||||
|
onMediaSelection={this.props.bulkActions.handleMediaSelection}
|
||||||
|
onItemsUpdate={this.props.bulkActions.handleItemsUpdate}
|
||||||
|
/>
|
||||||
|
{isMediaAuthor && 0 === this.state.channelMediaCount && !this.state.query ? (
|
||||||
|
<EmptySharedByMe name={this.state.author.name} />
|
||||||
|
) : null}
|
||||||
|
</MediaListWrapper>
|
||||||
|
</ProfilePagesContent>
|
||||||
|
) : null,
|
||||||
|
this.state.author && isMediaAuthor ? (
|
||||||
|
<BulkActionsModals
|
||||||
|
key="BulkActionsModals"
|
||||||
|
{...this.props.bulkActions}
|
||||||
|
selectedMediaIds={Array.from(this.props.bulkActions.selectedMedia)}
|
||||||
|
csrfToken={this.props.bulkActions.getCsrfToken()}
|
||||||
|
username={this.state.author.username}
|
||||||
|
onConfirmCancel={this.props.bulkActions.handleConfirmCancel}
|
||||||
|
onConfirmProceed={this.props.bulkActions.handleConfirmProceed}
|
||||||
|
onPermissionModalCancel={this.props.bulkActions.handlePermissionModalCancel}
|
||||||
|
onPermissionModalSuccess={this.props.bulkActions.handlePermissionModalSuccess}
|
||||||
|
onPermissionModalError={this.props.bulkActions.handlePermissionModalError}
|
||||||
|
onPlaylistModalCancel={this.props.bulkActions.handlePlaylistModalCancel}
|
||||||
|
onPlaylistModalSuccess={this.props.bulkActions.handlePlaylistModalSuccess}
|
||||||
|
onPlaylistModalError={this.props.bulkActions.handlePlaylistModalError}
|
||||||
|
onChangeOwnerModalCancel={this.props.bulkActions.handleChangeOwnerModalCancel}
|
||||||
|
onChangeOwnerModalSuccess={this.props.bulkActions.handleChangeOwnerModalSuccess}
|
||||||
|
onChangeOwnerModalError={this.props.bulkActions.handleChangeOwnerModalError}
|
||||||
|
onPublishStateModalCancel={this.props.bulkActions.handlePublishStateModalCancel}
|
||||||
|
onPublishStateModalSuccess={this.props.bulkActions.handlePublishStateModalSuccess}
|
||||||
|
onPublishStateModalError={this.props.bulkActions.handlePublishStateModalError}
|
||||||
|
onCategoryModalCancel={this.props.bulkActions.handleCategoryModalCancel}
|
||||||
|
onCategoryModalSuccess={this.props.bulkActions.handleCategoryModalSuccess}
|
||||||
|
onCategoryModalError={this.props.bulkActions.handleCategoryModalError}
|
||||||
|
onTagModalCancel={this.props.bulkActions.handleTagModalCancel}
|
||||||
|
onTagModalSuccess={this.props.bulkActions.handleTagModalSuccess}
|
||||||
|
onTagModalError={this.props.bulkActions.handleTagModalError}
|
||||||
|
/>
|
||||||
|
) : null,
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProfileSharedByMePage.propTypes = {
|
ProfileSharedByMePage.propTypes = {
|
||||||
title: PropTypes.string.isRequired,
|
title: PropTypes.string.isRequired,
|
||||||
bulkActions: PropTypes.object.isRequired,
|
bulkActions: PropTypes.object.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
ProfileSharedByMePage.defaultProps = {
|
ProfileSharedByMePage.defaultProps = {
|
||||||
title: 'Shared by me',
|
title: 'Shared by me',
|
||||||
};
|
};
|
||||||
|
|
||||||
// Wrap with HOC and export as named export for compatibility
|
// Wrap with HOC and export as named export for compatibility
|
||||||
|
|||||||
@@ -10,364 +10,404 @@ import { LazyLoadItemListAsync } from '../components/item-list/LazyLoadItemListA
|
|||||||
import { ProfileMediaFilters } from '../components/search-filters/ProfileMediaFilters';
|
import { ProfileMediaFilters } from '../components/search-filters/ProfileMediaFilters';
|
||||||
import { ProfileMediaTags } from '../components/search-filters/ProfileMediaTags';
|
import { ProfileMediaTags } from '../components/search-filters/ProfileMediaTags';
|
||||||
import { ProfileMediaSorting } from '../components/search-filters/ProfileMediaSorting';
|
import { ProfileMediaSorting } from '../components/search-filters/ProfileMediaSorting';
|
||||||
import { translateString } from '../utils/helpers';
|
import { inEmbeddedApp, translateString } from '../utils/helpers';
|
||||||
|
|
||||||
import { Page } from './_Page';
|
import { Page } from './_Page';
|
||||||
|
|
||||||
import '../components/profile-page/ProfilePage.scss';
|
import '../components/profile-page/ProfilePage.scss';
|
||||||
|
|
||||||
function EmptySharedWithMe(props) {
|
function EmptySharedWithMe(props) {
|
||||||
return (
|
return (
|
||||||
<LinksConsumer>
|
<LinksConsumer>
|
||||||
{(links) => (
|
{(links) => (
|
||||||
<div className="empty-media empty-channel-media">
|
<div className="empty-media empty-channel-media">
|
||||||
<div className="welcome-title">No shared media</div>
|
<div className="welcome-title">No shared media</div>
|
||||||
<div className="start-uploading">
|
<div className="start-uploading">Media that others have shared with you will show up here.</div>
|
||||||
Media that others have shared with you will show up here.
|
</div>
|
||||||
</div>
|
)}
|
||||||
</div>
|
</LinksConsumer>
|
||||||
)}
|
);
|
||||||
</LinksConsumer>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ProfileSharedWithMePage extends Page {
|
export class ProfileSharedWithMePage extends Page {
|
||||||
constructor(props, pageSlug) {
|
constructor(props, pageSlug) {
|
||||||
super(props, 'string' === typeof pageSlug ? pageSlug : 'author-shared-with-me');
|
super(props, 'string' === typeof pageSlug ? pageSlug : 'author-shared-with-me');
|
||||||
|
|
||||||
this.profilePageSlug = 'string' === typeof pageSlug ? pageSlug : 'author-shared-with-me';
|
this.profilePageSlug = 'string' === typeof pageSlug ? pageSlug : 'author-shared-with-me';
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
channelMediaCount: -1,
|
channelMediaCount: -1,
|
||||||
author: ProfilePageStore.get('author-data'),
|
author: ProfilePageStore.get('author-data'),
|
||||||
uploadsPreviewItemsCount: 0,
|
uploadsPreviewItemsCount: 0,
|
||||||
title: this.props.title,
|
title: this.props.title,
|
||||||
query: ProfilePageStore.get('author-query'),
|
query: ProfilePageStore.get('author-query'),
|
||||||
requestUrl: null,
|
requestUrl: null,
|
||||||
hiddenFilters: true,
|
hiddenFilters: true,
|
||||||
hiddenTags: true,
|
hiddenTags: true,
|
||||||
hiddenSorting: true,
|
hiddenSorting: true,
|
||||||
filterArgs: '',
|
filterArgs: '',
|
||||||
availableTags: [],
|
availableTags: [],
|
||||||
selectedTag: 'all',
|
selectedTag: 'all',
|
||||||
selectedSort: 'date_added_desc',
|
selectedSort: 'date_added_desc',
|
||||||
};
|
};
|
||||||
|
|
||||||
this.authorDataLoad = this.authorDataLoad.bind(this);
|
this.authorDataLoad = this.authorDataLoad.bind(this);
|
||||||
this.onAuthorPreviewItemsCountCallback = this.onAuthorPreviewItemsCountCallback.bind(this);
|
this.onAuthorPreviewItemsCountCallback = this.onAuthorPreviewItemsCountCallback.bind(this);
|
||||||
this.getCountFunc = this.getCountFunc.bind(this);
|
this.getCountFunc = this.getCountFunc.bind(this);
|
||||||
this.changeRequestQuery = this.changeRequestQuery.bind(this);
|
this.changeRequestQuery = this.changeRequestQuery.bind(this);
|
||||||
this.onToggleFiltersClick = this.onToggleFiltersClick.bind(this);
|
this.onToggleFiltersClick = this.onToggleFiltersClick.bind(this);
|
||||||
this.onToggleTagsClick = this.onToggleTagsClick.bind(this);
|
this.onToggleTagsClick = this.onToggleTagsClick.bind(this);
|
||||||
this.onToggleSortingClick = this.onToggleSortingClick.bind(this);
|
this.onToggleSortingClick = this.onToggleSortingClick.bind(this);
|
||||||
this.onFiltersUpdate = this.onFiltersUpdate.bind(this);
|
this.onFiltersUpdate = this.onFiltersUpdate.bind(this);
|
||||||
this.onTagSelect = this.onTagSelect.bind(this);
|
this.onTagSelect = this.onTagSelect.bind(this);
|
||||||
this.onSortSelect = this.onSortSelect.bind(this);
|
this.onSortSelect = this.onSortSelect.bind(this);
|
||||||
this.onResponseDataLoaded = this.onResponseDataLoaded.bind(this);
|
this.onResponseDataLoaded = this.onResponseDataLoaded.bind(this);
|
||||||
|
|
||||||
ProfilePageStore.on('load-author-data', this.authorDataLoad);
|
ProfilePageStore.on('load-author-data', this.authorDataLoad);
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
ProfilePageActions.load_author_data();
|
|
||||||
}
|
|
||||||
|
|
||||||
authorDataLoad() {
|
|
||||||
const author = ProfilePageStore.get('author-data');
|
|
||||||
|
|
||||||
let requestUrl = this.state.requestUrl;
|
|
||||||
|
|
||||||
if (author) {
|
|
||||||
if (this.state.query) {
|
|
||||||
requestUrl = ApiUrlContext._currentValue.media + '?author=' + author.id + '&show=shared_with_me&q=' + encodeURIComponent(this.state.query) + this.state.filterArgs;
|
|
||||||
} else {
|
|
||||||
requestUrl = ApiUrlContext._currentValue.media + '?author=' + author.id + '&show=shared_with_me' + this.state.filterArgs;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
componentDidMount() {
|
||||||
author: author,
|
ProfilePageActions.load_author_data();
|
||||||
requestUrl: requestUrl,
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onAuthorPreviewItemsCountCallback(totalAuthorPreviewItems) {
|
authorDataLoad() {
|
||||||
this.setState({
|
const author = ProfilePageStore.get('author-data');
|
||||||
uploadsPreviewItemsCount: totalAuthorPreviewItems,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getCountFunc(count) {
|
let requestUrl = this.state.requestUrl;
|
||||||
this.setState(
|
|
||||||
{
|
|
||||||
channelMediaCount: count,
|
|
||||||
},
|
|
||||||
() => {
|
|
||||||
if (this.state.query) {
|
|
||||||
let title = '';
|
|
||||||
|
|
||||||
if (!count) {
|
if (author) {
|
||||||
title = 'No results for "' + this.state.query + '"';
|
if (this.state.query) {
|
||||||
} else if (1 === count) {
|
requestUrl =
|
||||||
title = '1 result for "' + this.state.query + '"';
|
ApiUrlContext._currentValue.media +
|
||||||
} else {
|
'?author=' +
|
||||||
title = count + ' results for "' + this.state.query + '"';
|
author.id +
|
||||||
}
|
'&show=shared_with_me&q=' +
|
||||||
|
encodeURIComponent(this.state.query) +
|
||||||
this.setState({
|
this.state.filterArgs;
|
||||||
title: title,
|
} else {
|
||||||
});
|
requestUrl =
|
||||||
|
ApiUrlContext._currentValue.media +
|
||||||
|
'?author=' +
|
||||||
|
author.id +
|
||||||
|
'&show=shared_with_me' +
|
||||||
|
this.state.filterArgs;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
changeRequestQuery(newQuery) {
|
this.setState({
|
||||||
if (!this.state.author) {
|
author: author,
|
||||||
return;
|
requestUrl: requestUrl,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let requestUrl;
|
onAuthorPreviewItemsCountCallback(totalAuthorPreviewItems) {
|
||||||
|
this.setState({
|
||||||
if (newQuery) {
|
uploadsPreviewItemsCount: totalAuthorPreviewItems,
|
||||||
requestUrl = ApiUrlContext._currentValue.media + '?author=' + this.state.author.id + '&show=shared_with_me&q=' + encodeURIComponent(newQuery) + this.state.filterArgs;
|
});
|
||||||
} else {
|
|
||||||
requestUrl = ApiUrlContext._currentValue.media + '?author=' + this.state.author.id + '&show=shared_with_me' + this.state.filterArgs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let title = this.state.title;
|
getCountFunc(count) {
|
||||||
|
this.setState(
|
||||||
|
{
|
||||||
|
channelMediaCount: count,
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
if (this.state.query) {
|
||||||
|
let title = '';
|
||||||
|
|
||||||
if ('' === newQuery) {
|
if (!count) {
|
||||||
title = this.props.title;
|
title = 'No results for "' + this.state.query + '"';
|
||||||
|
} else if (1 === count) {
|
||||||
|
title = '1 result for "' + this.state.query + '"';
|
||||||
|
} else {
|
||||||
|
title = count + ' results for "' + this.state.query + '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
title: title,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
changeRequestQuery(newQuery) {
|
||||||
requestUrl: requestUrl,
|
|
||||||
query: newQuery,
|
|
||||||
title: title,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onToggleFiltersClick() {
|
|
||||||
this.setState({
|
|
||||||
hiddenFilters: !this.state.hiddenFilters,
|
|
||||||
hiddenTags: true,
|
|
||||||
hiddenSorting: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onToggleTagsClick() {
|
|
||||||
this.setState({
|
|
||||||
hiddenFilters: true,
|
|
||||||
hiddenTags: !this.state.hiddenTags,
|
|
||||||
hiddenSorting: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onToggleSortingClick() {
|
|
||||||
this.setState({
|
|
||||||
hiddenFilters: true,
|
|
||||||
hiddenTags: true,
|
|
||||||
hiddenSorting: !this.state.hiddenSorting,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onTagSelect(tag) {
|
|
||||||
this.setState({ selectedTag: tag }, () => {
|
|
||||||
this.onFiltersUpdate({
|
|
||||||
media_type: this.state.filterArgs.match(/media_type=([^&]+)/)?.[1],
|
|
||||||
upload_date: this.state.filterArgs.match(/upload_date=([^&]+)/)?.[1],
|
|
||||||
duration: this.state.filterArgs.match(/duration=([^&]+)/)?.[1],
|
|
||||||
publish_state: this.state.filterArgs.match(/publish_state=([^&]+)/)?.[1],
|
|
||||||
sort_by: this.state.selectedSort,
|
|
||||||
tag: tag,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onSortSelect(sortBy) {
|
|
||||||
this.setState({ selectedSort: sortBy }, () => {
|
|
||||||
this.onFiltersUpdate({
|
|
||||||
media_type: this.state.filterArgs.match(/media_type=([^&]+)/)?.[1],
|
|
||||||
upload_date: this.state.filterArgs.match(/upload_date=([^&]+)/)?.[1],
|
|
||||||
duration: this.state.filterArgs.match(/duration=([^&]+)/)?.[1],
|
|
||||||
publish_state: this.state.filterArgs.match(/publish_state=([^&]+)/)?.[1],
|
|
||||||
sort_by: sortBy,
|
|
||||||
tag: this.state.selectedTag,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onFiltersUpdate(updatedArgs) {
|
|
||||||
const args = {
|
|
||||||
media_type: null,
|
|
||||||
upload_date: null,
|
|
||||||
duration: null,
|
|
||||||
publish_state: null,
|
|
||||||
sort_by: null,
|
|
||||||
ordering: null,
|
|
||||||
t: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
switch (updatedArgs.media_type) {
|
|
||||||
case 'video':
|
|
||||||
case 'audio':
|
|
||||||
case 'image':
|
|
||||||
case 'pdf':
|
|
||||||
args.media_type = updatedArgs.media_type;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (updatedArgs.upload_date) {
|
|
||||||
case 'today':
|
|
||||||
case 'this_week':
|
|
||||||
case 'this_month':
|
|
||||||
case 'this_year':
|
|
||||||
args.upload_date = updatedArgs.upload_date;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle duration filter
|
|
||||||
if (updatedArgs.duration && updatedArgs.duration !== 'all') {
|
|
||||||
args.duration = updatedArgs.duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle publish state filter
|
|
||||||
if (updatedArgs.publish_state && updatedArgs.publish_state !== 'all') {
|
|
||||||
args.publish_state = updatedArgs.publish_state;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (updatedArgs.sort_by) {
|
|
||||||
case 'date_added_desc':
|
|
||||||
// Default sorting, no need to add parameters
|
|
||||||
break;
|
|
||||||
case 'date_added_asc':
|
|
||||||
args.ordering = 'asc';
|
|
||||||
break;
|
|
||||||
case 'alphabetically_asc':
|
|
||||||
args.sort_by = 'title_asc';
|
|
||||||
break;
|
|
||||||
case 'alphabetically_desc':
|
|
||||||
args.sort_by = 'title_desc';
|
|
||||||
break;
|
|
||||||
case 'plays_least':
|
|
||||||
args.sort_by = 'views_asc';
|
|
||||||
break;
|
|
||||||
case 'plays_most':
|
|
||||||
args.sort_by = 'views_desc';
|
|
||||||
break;
|
|
||||||
case 'likes_least':
|
|
||||||
args.sort_by = 'likes_asc';
|
|
||||||
break;
|
|
||||||
case 'likes_most':
|
|
||||||
args.sort_by = 'likes_desc';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (updatedArgs.tag && updatedArgs.tag !== 'all') {
|
|
||||||
args.t = updatedArgs.tag;
|
|
||||||
}
|
|
||||||
|
|
||||||
const newArgs = [];
|
|
||||||
|
|
||||||
for (let arg in args) {
|
|
||||||
if (null !== args[arg]) {
|
|
||||||
newArgs.push(arg + '=' + args[arg]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState(
|
|
||||||
{
|
|
||||||
filterArgs: newArgs.length ? '&' + newArgs.join('&') : '',
|
|
||||||
},
|
|
||||||
function () {
|
|
||||||
if (!this.state.author) {
|
if (!this.state.author) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let requestUrl;
|
let requestUrl;
|
||||||
|
|
||||||
if (this.state.query) {
|
if (newQuery) {
|
||||||
requestUrl = ApiUrlContext._currentValue.media + '?author=' + this.state.author.id + '&show=shared_with_me&q=' + encodeURIComponent(this.state.query) + this.state.filterArgs;
|
requestUrl =
|
||||||
|
ApiUrlContext._currentValue.media +
|
||||||
|
'?author=' +
|
||||||
|
this.state.author.id +
|
||||||
|
'&show=shared_with_me&q=' +
|
||||||
|
encodeURIComponent(newQuery) +
|
||||||
|
this.state.filterArgs;
|
||||||
} else {
|
} else {
|
||||||
requestUrl = ApiUrlContext._currentValue.media + '?author=' + this.state.author.id + '&show=shared_with_me' + this.state.filterArgs;
|
requestUrl =
|
||||||
|
ApiUrlContext._currentValue.media +
|
||||||
|
'?author=' +
|
||||||
|
this.state.author.id +
|
||||||
|
'&show=shared_with_me' +
|
||||||
|
this.state.filterArgs;
|
||||||
|
}
|
||||||
|
|
||||||
|
let title = this.state.title;
|
||||||
|
|
||||||
|
if ('' === newQuery) {
|
||||||
|
title = this.props.title;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
requestUrl: requestUrl,
|
requestUrl: requestUrl,
|
||||||
|
query: newQuery,
|
||||||
|
title: title,
|
||||||
});
|
});
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
onResponseDataLoaded(responseData) {
|
|
||||||
if (responseData && responseData.tags) {
|
|
||||||
const tags = responseData.tags.split(',').map((tag) => tag.trim()).filter((tag) => tag);
|
|
||||||
this.setState({ availableTags: tags });
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pageContent() {
|
onToggleFiltersClick() {
|
||||||
const authorData = ProfilePageStore.get('author-data');
|
this.setState({
|
||||||
|
hiddenFilters: !this.state.hiddenFilters,
|
||||||
|
hiddenTags: true,
|
||||||
|
hiddenSorting: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const isMediaAuthor = authorData && authorData.username === MemberContext._currentValue.username;
|
onToggleTagsClick() {
|
||||||
|
this.setState({
|
||||||
|
hiddenFilters: true,
|
||||||
|
hiddenTags: !this.state.hiddenTags,
|
||||||
|
hiddenSorting: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Check if any filters are active
|
onToggleSortingClick() {
|
||||||
const hasActiveFilters = this.state.filterArgs && (
|
this.setState({
|
||||||
this.state.filterArgs.includes('media_type=') ||
|
hiddenFilters: true,
|
||||||
this.state.filterArgs.includes('upload_date=') ||
|
hiddenTags: true,
|
||||||
this.state.filterArgs.includes('duration=') ||
|
hiddenSorting: !this.state.hiddenSorting,
|
||||||
this.state.filterArgs.includes('publish_state=')
|
});
|
||||||
);
|
}
|
||||||
|
|
||||||
return [
|
onTagSelect(tag) {
|
||||||
this.state.author ? (
|
this.setState({ selectedTag: tag }, () => {
|
||||||
<ProfilePagesHeader
|
this.onFiltersUpdate({
|
||||||
key="ProfilePagesHeader"
|
media_type: this.state.filterArgs.match(/media_type=([^&]+)/)?.[1],
|
||||||
author={this.state.author}
|
upload_date: this.state.filterArgs.match(/upload_date=([^&]+)/)?.[1],
|
||||||
type="shared_with_me"
|
duration: this.state.filterArgs.match(/duration=([^&]+)/)?.[1],
|
||||||
onQueryChange={this.changeRequestQuery}
|
publish_state: this.state.filterArgs.match(/publish_state=([^&]+)/)?.[1],
|
||||||
onToggleFiltersClick={this.onToggleFiltersClick}
|
sort_by: this.state.selectedSort,
|
||||||
onToggleTagsClick={this.onToggleTagsClick}
|
tag: tag,
|
||||||
onToggleSortingClick={this.onToggleSortingClick}
|
});
|
||||||
hasActiveFilters={hasActiveFilters}
|
});
|
||||||
hasActiveTags={this.state.selectedTag !== 'all'}
|
}
|
||||||
hasActiveSort={this.state.selectedSort !== 'date_added_desc'}
|
|
||||||
/>
|
onSortSelect(sortBy) {
|
||||||
) : null,
|
this.setState({ selectedSort: sortBy }, () => {
|
||||||
this.state.author ? (
|
this.onFiltersUpdate({
|
||||||
<ProfilePagesContent key="ProfilePagesContent">
|
media_type: this.state.filterArgs.match(/media_type=([^&]+)/)?.[1],
|
||||||
<MediaListWrapper
|
upload_date: this.state.filterArgs.match(/upload_date=([^&]+)/)?.[1],
|
||||||
title={this.state.title}
|
duration: this.state.filterArgs.match(/duration=([^&]+)/)?.[1],
|
||||||
className="items-list-ver"
|
publish_state: this.state.filterArgs.match(/publish_state=([^&]+)/)?.[1],
|
||||||
>
|
sort_by: sortBy,
|
||||||
<ProfileMediaFilters hidden={this.state.hiddenFilters} tags={this.state.availableTags} onFiltersUpdate={this.onFiltersUpdate} />
|
tag: this.state.selectedTag,
|
||||||
<ProfileMediaTags hidden={this.state.hiddenTags} tags={this.state.availableTags} onTagSelect={this.onTagSelect} />
|
});
|
||||||
<ProfileMediaSorting hidden={this.state.hiddenSorting} onSortSelect={this.onSortSelect} />
|
});
|
||||||
<LazyLoadItemListAsync
|
}
|
||||||
key={this.state.requestUrl}
|
|
||||||
requestUrl={this.state.requestUrl}
|
onFiltersUpdate(updatedArgs) {
|
||||||
hideAuthor={true}
|
const args = {
|
||||||
itemsCountCallback={this.state.requestUrl ? this.getCountFunc : null}
|
media_type: null,
|
||||||
hideViews={!PageStore.get('config-media-item').displayViews}
|
upload_date: null,
|
||||||
hideDate={!PageStore.get('config-media-item').displayPublishDate}
|
duration: null,
|
||||||
canEdit={false}
|
publish_state: null,
|
||||||
onResponseDataLoaded={this.onResponseDataLoaded}
|
sort_by: null,
|
||||||
/>
|
ordering: null,
|
||||||
{isMediaAuthor && 0 === this.state.channelMediaCount && !this.state.query ? (
|
t: null,
|
||||||
<EmptySharedWithMe name={this.state.author.name} />
|
};
|
||||||
) : null}
|
|
||||||
</MediaListWrapper>
|
switch (updatedArgs.media_type) {
|
||||||
</ProfilePagesContent>
|
case 'video':
|
||||||
) : null,
|
case 'audio':
|
||||||
];
|
case 'image':
|
||||||
}
|
case 'pdf':
|
||||||
|
args.media_type = updatedArgs.media_type;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (updatedArgs.upload_date) {
|
||||||
|
case 'today':
|
||||||
|
case 'this_week':
|
||||||
|
case 'this_month':
|
||||||
|
case 'this_year':
|
||||||
|
args.upload_date = updatedArgs.upload_date;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle duration filter
|
||||||
|
if (updatedArgs.duration && updatedArgs.duration !== 'all') {
|
||||||
|
args.duration = updatedArgs.duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle publish state filter
|
||||||
|
if (updatedArgs.publish_state && updatedArgs.publish_state !== 'all') {
|
||||||
|
args.publish_state = updatedArgs.publish_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (updatedArgs.sort_by) {
|
||||||
|
case 'date_added_desc':
|
||||||
|
// Default sorting, no need to add parameters
|
||||||
|
break;
|
||||||
|
case 'date_added_asc':
|
||||||
|
args.ordering = 'asc';
|
||||||
|
break;
|
||||||
|
case 'alphabetically_asc':
|
||||||
|
args.sort_by = 'title_asc';
|
||||||
|
break;
|
||||||
|
case 'alphabetically_desc':
|
||||||
|
args.sort_by = 'title_desc';
|
||||||
|
break;
|
||||||
|
case 'plays_least':
|
||||||
|
args.sort_by = 'views_asc';
|
||||||
|
break;
|
||||||
|
case 'plays_most':
|
||||||
|
args.sort_by = 'views_desc';
|
||||||
|
break;
|
||||||
|
case 'likes_least':
|
||||||
|
args.sort_by = 'likes_asc';
|
||||||
|
break;
|
||||||
|
case 'likes_most':
|
||||||
|
args.sort_by = 'likes_desc';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updatedArgs.tag && updatedArgs.tag !== 'all') {
|
||||||
|
args.t = updatedArgs.tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
const newArgs = [];
|
||||||
|
|
||||||
|
for (let arg in args) {
|
||||||
|
if (null !== args[arg]) {
|
||||||
|
newArgs.push(arg + '=' + args[arg]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState(
|
||||||
|
{
|
||||||
|
filterArgs: newArgs.length ? '&' + newArgs.join('&') : '',
|
||||||
|
},
|
||||||
|
function () {
|
||||||
|
if (!this.state.author) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let requestUrl;
|
||||||
|
|
||||||
|
if (this.state.query) {
|
||||||
|
requestUrl =
|
||||||
|
ApiUrlContext._currentValue.media +
|
||||||
|
'?author=' +
|
||||||
|
this.state.author.id +
|
||||||
|
'&show=shared_with_me&q=' +
|
||||||
|
encodeURIComponent(this.state.query) +
|
||||||
|
this.state.filterArgs;
|
||||||
|
} else {
|
||||||
|
requestUrl =
|
||||||
|
ApiUrlContext._currentValue.media +
|
||||||
|
'?author=' +
|
||||||
|
this.state.author.id +
|
||||||
|
'&show=shared_with_me' +
|
||||||
|
this.state.filterArgs;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
requestUrl: requestUrl,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
onResponseDataLoaded(responseData) {
|
||||||
|
if (responseData && responseData.tags) {
|
||||||
|
const tags = responseData.tags
|
||||||
|
.split(',')
|
||||||
|
.map((tag) => tag.trim())
|
||||||
|
.filter((tag) => tag);
|
||||||
|
this.setState({ availableTags: tags });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pageContent() {
|
||||||
|
const authorData = ProfilePageStore.get('author-data');
|
||||||
|
|
||||||
|
const isMediaAuthor = authorData && authorData.username === MemberContext._currentValue.username;
|
||||||
|
|
||||||
|
// Check if any filters are active
|
||||||
|
const hasActiveFilters =
|
||||||
|
this.state.filterArgs &&
|
||||||
|
(this.state.filterArgs.includes('media_type=') ||
|
||||||
|
this.state.filterArgs.includes('upload_date=') ||
|
||||||
|
this.state.filterArgs.includes('duration=') ||
|
||||||
|
this.state.filterArgs.includes('publish_state='));
|
||||||
|
|
||||||
|
return [
|
||||||
|
this.state.author ? (
|
||||||
|
<ProfilePagesHeader
|
||||||
|
key="ProfilePagesHeader"
|
||||||
|
author={this.state.author}
|
||||||
|
type="shared_with_me"
|
||||||
|
onQueryChange={this.changeRequestQuery}
|
||||||
|
onToggleFiltersClick={this.onToggleFiltersClick}
|
||||||
|
onToggleTagsClick={this.onToggleTagsClick}
|
||||||
|
onToggleSortingClick={this.onToggleSortingClick}
|
||||||
|
hasActiveFilters={hasActiveFilters}
|
||||||
|
hasActiveTags={this.state.selectedTag !== 'all'}
|
||||||
|
hasActiveSort={this.state.selectedSort !== 'date_added_desc'}
|
||||||
|
hideChannelBanner={inEmbeddedApp()}
|
||||||
|
/>
|
||||||
|
) : null,
|
||||||
|
this.state.author ? (
|
||||||
|
<ProfilePagesContent key="ProfilePagesContent">
|
||||||
|
<MediaListWrapper title={this.state.title} className="items-list-ver">
|
||||||
|
<ProfileMediaFilters
|
||||||
|
hidden={this.state.hiddenFilters}
|
||||||
|
tags={this.state.availableTags}
|
||||||
|
onFiltersUpdate={this.onFiltersUpdate}
|
||||||
|
/>
|
||||||
|
<ProfileMediaTags
|
||||||
|
hidden={this.state.hiddenTags}
|
||||||
|
tags={this.state.availableTags}
|
||||||
|
onTagSelect={this.onTagSelect}
|
||||||
|
/>
|
||||||
|
<ProfileMediaSorting hidden={this.state.hiddenSorting} onSortSelect={this.onSortSelect} />
|
||||||
|
<LazyLoadItemListAsync
|
||||||
|
key={this.state.requestUrl}
|
||||||
|
requestUrl={this.state.requestUrl}
|
||||||
|
hideAuthor={true}
|
||||||
|
itemsCountCallback={this.state.requestUrl ? this.getCountFunc : null}
|
||||||
|
hideViews={!PageStore.get('config-media-item').displayViews}
|
||||||
|
hideDate={!PageStore.get('config-media-item').displayPublishDate}
|
||||||
|
canEdit={false}
|
||||||
|
onResponseDataLoaded={this.onResponseDataLoaded}
|
||||||
|
/>
|
||||||
|
{isMediaAuthor && 0 === this.state.channelMediaCount && !this.state.query ? (
|
||||||
|
<EmptySharedWithMe name={this.state.author.name} />
|
||||||
|
) : null}
|
||||||
|
</MediaListWrapper>
|
||||||
|
</ProfilePagesContent>
|
||||||
|
) : null,
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProfileSharedWithMePage.propTypes = {
|
ProfileSharedWithMePage.propTypes = {
|
||||||
title: PropTypes.string.isRequired,
|
title: PropTypes.string.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
ProfileSharedWithMePage.defaultProps = {
|
ProfileSharedWithMePage.defaultProps = {
|
||||||
title: 'Shared with me',
|
title: 'Shared with me',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { PageStore, MediaPageStore } from '../utils/stores/';
|
import { PageStore, MediaPageStore } from '../utils/stores/';
|
||||||
import { MediaPageActions } from '../utils/actions/';
|
import { MediaPageActions } from '../utils/actions/';
|
||||||
|
import { inEmbeddedApp } from '../utils/helpers/';
|
||||||
import ViewerError from '../components/media-page/ViewerError';
|
import ViewerError from '../components/media-page/ViewerError';
|
||||||
import ViewerInfo from '../components/media-page/ViewerInfo';
|
import ViewerInfo from '../components/media-page/ViewerInfo';
|
||||||
import ViewerSidebar from '../components/media-page/ViewerSidebar';
|
import ViewerSidebar from '../components/media-page/ViewerSidebar';
|
||||||
@@ -10,102 +11,102 @@ import '../components/media-page/MediaPage.scss';
|
|||||||
const wideLayoutBreakpoint = 1216;
|
const wideLayoutBreakpoint = 1216;
|
||||||
|
|
||||||
export class _MediaPage extends Page {
|
export class _MediaPage extends Page {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props, 'media');
|
super(props, 'media');
|
||||||
|
|
||||||
const isWideLayout = wideLayoutBreakpoint <= window.innerWidth;
|
const isWideLayout = wideLayoutBreakpoint <= window.innerWidth;
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
mediaLoaded: false,
|
mediaLoaded: false,
|
||||||
mediaLoadFailed: false,
|
mediaLoadFailed: false,
|
||||||
wideLayout: isWideLayout,
|
wideLayout: isWideLayout,
|
||||||
infoAndSidebarViewType: !isWideLayout ? 0 : 1,
|
infoAndSidebarViewType: !isWideLayout ? 0 : 1,
|
||||||
viewerClassname: 'cf viewer-section viewer-wide',
|
viewerClassname: 'cf viewer-section viewer-wide',
|
||||||
viewerNestedClassname: 'viewer-section-nested',
|
viewerNestedClassname: 'viewer-section-nested',
|
||||||
pagePlaylistLoaded: false,
|
pagePlaylistLoaded: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.onWindowResize = this.onWindowResize.bind(this);
|
this.onWindowResize = this.onWindowResize.bind(this);
|
||||||
this.onMediaLoad = this.onMediaLoad.bind(this);
|
this.onMediaLoad = this.onMediaLoad.bind(this);
|
||||||
this.onMediaLoadError = this.onMediaLoadError.bind(this);
|
this.onMediaLoadError = this.onMediaLoadError.bind(this);
|
||||||
this.onPagePlaylistLoad = this.onPagePlaylistLoad.bind(this);
|
this.onPagePlaylistLoad = this.onPagePlaylistLoad.bind(this);
|
||||||
|
|
||||||
MediaPageStore.on('loaded_media_data', this.onMediaLoad);
|
MediaPageStore.on('loaded_media_data', this.onMediaLoad);
|
||||||
MediaPageStore.on('loaded_media_error', this.onMediaLoadError);
|
MediaPageStore.on('loaded_media_error', this.onMediaLoadError);
|
||||||
MediaPageStore.on('loaded_page_playlist_data', this.onPagePlaylistLoad);
|
MediaPageStore.on('loaded_page_playlist_data', this.onPagePlaylistLoad);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
MediaPageActions.loadMediaData();
|
MediaPageActions.loadMediaData();
|
||||||
// FIXME: Is not neccessary to check on every window dimension for changes...
|
// FIXME: Is not neccessary to check on every window dimension for changes...
|
||||||
PageStore.on('window_resize', this.onWindowResize);
|
PageStore.on('window_resize', this.onWindowResize);
|
||||||
}
|
}
|
||||||
|
|
||||||
onPagePlaylistLoad() {
|
onPagePlaylistLoad() {
|
||||||
this.setState({
|
this.setState({
|
||||||
pagePlaylistLoaded: true,
|
pagePlaylistLoaded: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onWindowResize() {
|
onWindowResize() {
|
||||||
const isWideLayout = wideLayoutBreakpoint <= window.innerWidth;
|
const isWideLayout = wideLayoutBreakpoint <= window.innerWidth;
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
wideLayout: isWideLayout,
|
wideLayout: isWideLayout,
|
||||||
infoAndSidebarViewType: !isWideLayout || (MediaPageStore.isVideo() && this.state.theaterMode) ? 0 : 1,
|
infoAndSidebarViewType: !isWideLayout || (MediaPageStore.isVideo() && this.state.theaterMode) ? 0 : 1,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onMediaLoad() {
|
onMediaLoad() {
|
||||||
this.setState({ mediaLoaded: true });
|
this.setState({ mediaLoaded: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
onMediaLoadError() {
|
onMediaLoadError() {
|
||||||
this.setState({ mediaLoadFailed: true });
|
this.setState({ mediaLoadFailed: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
viewerContainerContent() {
|
viewerContainerContent() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
mediaType() {
|
mediaType() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pageContent() {
|
pageContent() {
|
||||||
return this.state.mediaLoadFailed ? (
|
return this.state.mediaLoadFailed ? (
|
||||||
<div className={this.state.viewerClassname}>
|
<div className={this.state.viewerClassname}>
|
||||||
<ViewerError />
|
<ViewerError />
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className={this.state.viewerClassname}>
|
<div className={this.state.viewerClassname}>
|
||||||
<div className="viewer-container" key="viewer-container">
|
<div className="viewer-container" key="viewer-container">
|
||||||
{this.state.mediaLoaded ? this.viewerContainerContent() : null}
|
{this.state.mediaLoaded ? this.viewerContainerContent() : null}
|
||||||
</div>
|
</div>
|
||||||
<div key="viewer-section-nested" className={this.state.viewerNestedClassname}>
|
<div key="viewer-section-nested" className={this.state.viewerNestedClassname}>
|
||||||
{!this.state.infoAndSidebarViewType
|
{!this.state.infoAndSidebarViewType
|
||||||
? [
|
? [
|
||||||
<ViewerInfo key="viewer-info" />,
|
<ViewerInfo key="viewer-info" />,
|
||||||
this.state.pagePlaylistLoaded ? (
|
!inEmbeddedApp() && this.state.pagePlaylistLoaded ? (
|
||||||
<ViewerSidebar
|
<ViewerSidebar
|
||||||
key="viewer-sidebar"
|
key="viewer-sidebar"
|
||||||
mediaId={MediaPageStore.get('media-id')}
|
mediaId={MediaPageStore.get('media-id')}
|
||||||
playlistData={MediaPageStore.get('playlist-data')}
|
playlistData={MediaPageStore.get('playlist-data')}
|
||||||
/>
|
/>
|
||||||
) : null,
|
) : null,
|
||||||
]
|
]
|
||||||
: [
|
: [
|
||||||
this.state.pagePlaylistLoaded ? (
|
!inEmbeddedApp() && this.state.pagePlaylistLoaded ? (
|
||||||
<ViewerSidebar
|
<ViewerSidebar
|
||||||
key="viewer-sidebar"
|
key="viewer-sidebar"
|
||||||
mediaId={MediaPageStore.get('media-id')}
|
mediaId={MediaPageStore.get('media-id')}
|
||||||
playlistData={MediaPageStore.get('playlist-data')}
|
playlistData={MediaPageStore.get('playlist-data')}
|
||||||
/>
|
/>
|
||||||
) : null,
|
) : null,
|
||||||
<ViewerInfo key="viewer-info" />,
|
<ViewerInfo key="viewer-info" />,
|
||||||
]}
|
]}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import React from 'react';
|
|||||||
// FIXME: 'VideoViewerStore' is used only in case of video media, but is included in every media page code.
|
// FIXME: 'VideoViewerStore' is used only in case of video media, but is included in every media page code.
|
||||||
import { PageStore, MediaPageStore, VideoViewerStore } from '../utils/stores/';
|
import { PageStore, MediaPageStore, VideoViewerStore } from '../utils/stores/';
|
||||||
import { MediaPageActions } from '../utils/actions/';
|
import { MediaPageActions } from '../utils/actions/';
|
||||||
|
import { inEmbeddedApp } from '../utils/helpers/';
|
||||||
import ViewerInfoVideo from '../components/media-page/ViewerInfoVideo';
|
import ViewerInfoVideo from '../components/media-page/ViewerInfoVideo';
|
||||||
import ViewerError from '../components/media-page/ViewerError';
|
import ViewerError from '../components/media-page/ViewerError';
|
||||||
import ViewerSidebar from '../components/media-page/ViewerSidebar';
|
import ViewerSidebar from '../components/media-page/ViewerSidebar';
|
||||||
@@ -11,118 +12,119 @@ import _MediaPage from './_MediaPage';
|
|||||||
const wideLayoutBreakpoint = 1216;
|
const wideLayoutBreakpoint = 1216;
|
||||||
|
|
||||||
export class _VideoMediaPage extends Page {
|
export class _VideoMediaPage extends Page {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props, 'media');
|
super(props, 'media');
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
wideLayout: wideLayoutBreakpoint <= window.innerWidth,
|
wideLayout: wideLayoutBreakpoint <= window.innerWidth,
|
||||||
mediaLoaded: false,
|
mediaLoaded: false,
|
||||||
mediaLoadFailed: false,
|
mediaLoadFailed: false,
|
||||||
isVideoMedia: false,
|
isVideoMedia: false,
|
||||||
theaterMode: false, // FIXME: Used only in case of video media, but is included in every media page code.
|
theaterMode: false, // FIXME: Used only in case of video media, but is included in every media page code.
|
||||||
pagePlaylistLoaded: false,
|
pagePlaylistLoaded: false,
|
||||||
pagePlaylistData: MediaPageStore.get('playlist-data'),
|
pagePlaylistData: MediaPageStore.get('playlist-data'),
|
||||||
};
|
};
|
||||||
|
|
||||||
this.onWindowResize = this.onWindowResize.bind(this);
|
this.onWindowResize = this.onWindowResize.bind(this);
|
||||||
this.onMediaLoad = this.onMediaLoad.bind(this);
|
this.onMediaLoad = this.onMediaLoad.bind(this);
|
||||||
this.onMediaLoadError = this.onMediaLoadError.bind(this);
|
this.onMediaLoadError = this.onMediaLoadError.bind(this);
|
||||||
this.onPagePlaylistLoad = this.onPagePlaylistLoad.bind(this);
|
this.onPagePlaylistLoad = this.onPagePlaylistLoad.bind(this);
|
||||||
|
|
||||||
MediaPageStore.on('loaded_media_data', this.onMediaLoad);
|
MediaPageStore.on('loaded_media_data', this.onMediaLoad);
|
||||||
MediaPageStore.on('loaded_media_error', this.onMediaLoadError);
|
MediaPageStore.on('loaded_media_error', this.onMediaLoadError);
|
||||||
MediaPageStore.on('loaded_page_playlist_data', this.onPagePlaylistLoad);
|
MediaPageStore.on('loaded_page_playlist_data', this.onPagePlaylistLoad);
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
MediaPageActions.loadMediaData();
|
|
||||||
// FIXME: Is not neccessary to check on every window dimension for changes...
|
|
||||||
PageStore.on('window_resize', this.onWindowResize);
|
|
||||||
}
|
|
||||||
|
|
||||||
onWindowResize() {
|
|
||||||
this.setState({
|
|
||||||
wideLayout: wideLayoutBreakpoint <= window.innerWidth,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onPagePlaylistLoad() {
|
|
||||||
this.setState({
|
|
||||||
pagePlaylistLoaded: true,
|
|
||||||
pagePlaylistData: MediaPageStore.get('playlist-data'),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onMediaLoad() {
|
|
||||||
const isVideoMedia = 'video' === MediaPageStore.get('media-type') || 'audio' === MediaPageStore.get('media-type');
|
|
||||||
|
|
||||||
if (isVideoMedia) {
|
|
||||||
this.onViewerModeChange = this.onViewerModeChange.bind(this);
|
|
||||||
|
|
||||||
VideoViewerStore.on('changed_viewer_mode', this.onViewerModeChange);
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
mediaLoaded: true,
|
|
||||||
isVideoMedia: isVideoMedia,
|
|
||||||
theaterMode: VideoViewerStore.get('in-theater-mode'),
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.setState({
|
|
||||||
mediaLoaded: true,
|
|
||||||
isVideoMedia: isVideoMedia,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
onViewerModeChange() {
|
componentDidMount() {
|
||||||
this.setState({ theaterMode: VideoViewerStore.get('in-theater-mode') });
|
MediaPageActions.loadMediaData();
|
||||||
}
|
// FIXME: Is not neccessary to check on every window dimension for changes...
|
||||||
|
PageStore.on('window_resize', this.onWindowResize);
|
||||||
|
}
|
||||||
|
|
||||||
onMediaLoadError(a) {
|
onWindowResize() {
|
||||||
this.setState({ mediaLoadFailed: true });
|
this.setState({
|
||||||
}
|
wideLayout: wideLayoutBreakpoint <= window.innerWidth,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
pageContent() {
|
onPagePlaylistLoad() {
|
||||||
const viewerClassname = 'cf viewer-section' + (this.state.theaterMode ? ' theater-mode' : ' viewer-wide');
|
this.setState({
|
||||||
const viewerNestedClassname = 'viewer-section-nested' + (this.state.theaterMode ? ' viewer-section' : '');
|
pagePlaylistLoaded: true,
|
||||||
|
pagePlaylistData: MediaPageStore.get('playlist-data'),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return this.state.mediaLoadFailed ? (
|
onMediaLoad() {
|
||||||
<div className={viewerClassname}>
|
const isVideoMedia =
|
||||||
<ViewerError />
|
'video' === MediaPageStore.get('media-type') || 'audio' === MediaPageStore.get('media-type');
|
||||||
</div>
|
|
||||||
) : (
|
if (isVideoMedia) {
|
||||||
<div className={viewerClassname}>
|
this.onViewerModeChange = this.onViewerModeChange.bind(this);
|
||||||
{[
|
|
||||||
<div className="viewer-container" key="viewer-container">
|
VideoViewerStore.on('changed_viewer_mode', this.onViewerModeChange);
|
||||||
{this.state.mediaLoaded && this.state.pagePlaylistLoaded
|
|
||||||
? this.viewerContainerContent(MediaPageStore.get('media-data'))
|
this.setState({
|
||||||
: null}
|
mediaLoaded: true,
|
||||||
</div>,
|
isVideoMedia: isVideoMedia,
|
||||||
<div key="viewer-section-nested" className={viewerNestedClassname}>
|
theaterMode: VideoViewerStore.get('in-theater-mode'),
|
||||||
{!this.state.wideLayout || (this.state.isVideoMedia && this.state.theaterMode)
|
});
|
||||||
? [
|
} else {
|
||||||
<ViewerInfoVideo key="viewer-info" />,
|
this.setState({
|
||||||
this.state.pagePlaylistLoaded ? (
|
mediaLoaded: true,
|
||||||
<ViewerSidebar
|
isVideoMedia: isVideoMedia,
|
||||||
key="viewer-sidebar"
|
});
|
||||||
mediaId={MediaPageStore.get('media-id')}
|
}
|
||||||
playlistData={MediaPageStore.get('playlist-data')}
|
}
|
||||||
/>
|
|
||||||
) : null,
|
onViewerModeChange() {
|
||||||
]
|
this.setState({ theaterMode: VideoViewerStore.get('in-theater-mode') });
|
||||||
: [
|
}
|
||||||
this.state.pagePlaylistLoaded ? (
|
|
||||||
<ViewerSidebar
|
onMediaLoadError(a) {
|
||||||
key="viewer-sidebar"
|
this.setState({ mediaLoadFailed: true });
|
||||||
mediaId={MediaPageStore.get('media-id')}
|
}
|
||||||
playlistData={MediaPageStore.get('playlist-data')}
|
|
||||||
/>
|
pageContent() {
|
||||||
) : null,
|
const viewerClassname = 'cf viewer-section' + (this.state.theaterMode ? ' theater-mode' : ' viewer-wide');
|
||||||
<ViewerInfoVideo key="viewer-info" />,
|
const viewerNestedClassname = 'viewer-section-nested' + (this.state.theaterMode ? ' viewer-section' : '');
|
||||||
|
|
||||||
|
return this.state.mediaLoadFailed ? (
|
||||||
|
<div className={viewerClassname}>
|
||||||
|
<ViewerError />
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className={viewerClassname}>
|
||||||
|
{[
|
||||||
|
<div className="viewer-container" key="viewer-container">
|
||||||
|
{this.state.mediaLoaded && this.state.pagePlaylistLoaded
|
||||||
|
? this.viewerContainerContent(MediaPageStore.get('media-data'))
|
||||||
|
: null}
|
||||||
|
</div>,
|
||||||
|
<div key="viewer-section-nested" className={viewerNestedClassname}>
|
||||||
|
{!this.state.wideLayout || (this.state.isVideoMedia && this.state.theaterMode)
|
||||||
|
? [
|
||||||
|
<ViewerInfoVideo key="viewer-info" />,
|
||||||
|
!inEmbeddedApp() && this.state.pagePlaylistLoaded ? (
|
||||||
|
<ViewerSidebar
|
||||||
|
key="viewer-sidebar"
|
||||||
|
mediaId={MediaPageStore.get('media-id')}
|
||||||
|
playlistData={MediaPageStore.get('playlist-data')}
|
||||||
|
/>
|
||||||
|
) : null,
|
||||||
|
]
|
||||||
|
: [
|
||||||
|
!inEmbeddedApp() && this.state.pagePlaylistLoaded ? (
|
||||||
|
<ViewerSidebar
|
||||||
|
key="viewer-sidebar"
|
||||||
|
mediaId={MediaPageStore.get('media-id')}
|
||||||
|
playlistData={MediaPageStore.get('playlist-data')}
|
||||||
|
/>
|
||||||
|
) : null,
|
||||||
|
<ViewerInfoVideo key="viewer-info" />,
|
||||||
|
]}
|
||||||
|
</div>,
|
||||||
]}
|
]}
|
||||||
</div>,
|
</div>
|
||||||
]}
|
);
|
||||||
</div>
|
}
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,101 +1,103 @@
|
|||||||
import React, { createContext, useContext, useEffect, useState } from 'react';
|
import React, { createContext, useContext, useEffect, useMemo, useState } from 'react';
|
||||||
import { BrowserCache } from '../classes/';
|
import { BrowserCache } from '../classes/';
|
||||||
import { PageStore } from '../stores/';
|
import { PageStore } from '../stores/';
|
||||||
import { addClassname, removeClassname } from '../helpers/';
|
import { addClassname, removeClassname, inEmbeddedApp } from '../helpers/';
|
||||||
import SiteContext from './SiteContext';
|
import SiteContext from './SiteContext';
|
||||||
|
|
||||||
let slidingSidebarTimeout;
|
let slidingSidebarTimeout;
|
||||||
|
|
||||||
function onSidebarVisibilityChange(visibleSidebar) {
|
function onSidebarVisibilityChange(visibleSidebar) {
|
||||||
clearTimeout(slidingSidebarTimeout);
|
clearTimeout(slidingSidebarTimeout);
|
||||||
|
|
||||||
addClassname(document.body, 'sliding-sidebar');
|
addClassname(document.body, 'sliding-sidebar');
|
||||||
|
|
||||||
slidingSidebarTimeout = setTimeout(function () {
|
|
||||||
if ('media' === PageStore.get('current-page')) {
|
|
||||||
if (visibleSidebar) {
|
|
||||||
addClassname(document.body, 'overflow-hidden');
|
|
||||||
} else {
|
|
||||||
removeClassname(document.body, 'overflow-hidden');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!visibleSidebar || 767 < window.innerWidth) {
|
|
||||||
removeClassname(document.body, 'overflow-hidden');
|
|
||||||
} else {
|
|
||||||
addClassname(document.body, 'overflow-hidden');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (visibleSidebar) {
|
|
||||||
addClassname(document.body, 'visible-sidebar');
|
|
||||||
} else {
|
|
||||||
removeClassname(document.body, 'visible-sidebar');
|
|
||||||
}
|
|
||||||
|
|
||||||
slidingSidebarTimeout = setTimeout(function () {
|
slidingSidebarTimeout = setTimeout(function () {
|
||||||
slidingSidebarTimeout = null;
|
if ('media' === PageStore.get('current-page')) {
|
||||||
removeClassname(document.body, 'sliding-sidebar');
|
if (visibleSidebar) {
|
||||||
}, 220);
|
addClassname(document.body, 'overflow-hidden');
|
||||||
}, 20);
|
} else {
|
||||||
|
removeClassname(document.body, 'overflow-hidden');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!visibleSidebar || 767 < window.innerWidth) {
|
||||||
|
removeClassname(document.body, 'overflow-hidden');
|
||||||
|
} else {
|
||||||
|
addClassname(document.body, 'overflow-hidden');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (visibleSidebar) {
|
||||||
|
addClassname(document.body, 'visible-sidebar');
|
||||||
|
} else {
|
||||||
|
removeClassname(document.body, 'visible-sidebar');
|
||||||
|
}
|
||||||
|
|
||||||
|
slidingSidebarTimeout = setTimeout(function () {
|
||||||
|
slidingSidebarTimeout = null;
|
||||||
|
removeClassname(document.body, 'sliding-sidebar');
|
||||||
|
}, 220);
|
||||||
|
}, 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const LayoutContext = createContext();
|
export const LayoutContext = createContext();
|
||||||
|
|
||||||
export const LayoutProvider = ({ children }) => {
|
export const LayoutProvider = ({ children }) => {
|
||||||
const site = useContext(SiteContext);
|
const site = useContext(SiteContext);
|
||||||
const cache = new BrowserCache('MediaCMS[' + site.id + '][layout]', 86400);
|
const cache = new BrowserCache('MediaCMS[' + site.id + '][layout]', 86400);
|
||||||
|
|
||||||
const enabledSidebar = !!(document.getElementById('app-sidebar') || document.querySelector('.page-sidebar'));
|
const isMediaPage = useMemo(() => PageStore.get('current-page') === 'media', []);
|
||||||
|
const isEmbeddedApp = useMemo(() => inEmbeddedApp(), []);
|
||||||
|
|
||||||
const [visibleSidebar, setVisibleSidebar] = useState(cache.get('visible-sidebar'));
|
const enabledSidebar = Boolean(document.getElementById('app-sidebar') || document.querySelector('.page-sidebar'));
|
||||||
const [visibleMobileSearch, setVisibleMobileSearch] = useState(false);
|
|
||||||
|
|
||||||
const toggleMobileSearch = () => {
|
const [visibleSidebar, setVisibleSidebar] = useState(cache.get('visible-sidebar'));
|
||||||
setVisibleMobileSearch(!visibleMobileSearch);
|
const [visibleMobileSearch, setVisibleMobileSearch] = useState(false);
|
||||||
};
|
|
||||||
|
|
||||||
const toggleSidebar = () => {
|
const toggleMobileSearch = () => {
|
||||||
const newval = !visibleSidebar;
|
setVisibleMobileSearch(!visibleMobileSearch);
|
||||||
onSidebarVisibilityChange(newval);
|
};
|
||||||
setVisibleSidebar(newval);
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
const toggleSidebar = () => {
|
||||||
if (visibleSidebar) {
|
const newval = !visibleSidebar;
|
||||||
addClassname(document.body, 'visible-sidebar');
|
onSidebarVisibilityChange(newval);
|
||||||
} else {
|
setVisibleSidebar(newval);
|
||||||
removeClassname(document.body, 'visible-sidebar');
|
};
|
||||||
}
|
|
||||||
if ('media' !== PageStore.get('current-page') && 1023 < window.innerWidth) {
|
|
||||||
cache.set('visible-sidebar', visibleSidebar);
|
|
||||||
}
|
|
||||||
}, [visibleSidebar]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
PageStore.once('page_init', () => {
|
if (!isEmbeddedApp && visibleSidebar) {
|
||||||
if ('media' === PageStore.get('current-page')) {
|
addClassname(document.body, 'visible-sidebar');
|
||||||
setVisibleSidebar(false);
|
} else {
|
||||||
removeClassname(document.body, 'visible-sidebar');
|
removeClassname(document.body, 'visible-sidebar');
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
setVisibleSidebar(
|
if (!isEmbeddedApp && !isMediaPage && 1023 < window.innerWidth) {
|
||||||
'media' !== PageStore.get('current-page') &&
|
cache.set('visible-sidebar', visibleSidebar);
|
||||||
1023 < window.innerWidth &&
|
}
|
||||||
(null === visibleSidebar || visibleSidebar)
|
}, [isEmbeddedApp, isMediaPage, visibleSidebar]);
|
||||||
);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const value = {
|
useEffect(() => {
|
||||||
enabledSidebar,
|
PageStore.once('page_init', () => {
|
||||||
visibleSidebar,
|
if (isEmbeddedApp || isMediaPage) {
|
||||||
setVisibleSidebar,
|
setVisibleSidebar(false);
|
||||||
visibleMobileSearch,
|
removeClassname(document.body, 'visible-sidebar');
|
||||||
toggleMobileSearch,
|
}
|
||||||
toggleSidebar,
|
});
|
||||||
};
|
|
||||||
|
|
||||||
return <LayoutContext.Provider value={value}>{children}</LayoutContext.Provider>;
|
setVisibleSidebar(
|
||||||
|
!isEmbeddedApp && !isMediaPage && 1023 < window.innerWidth && (null === visibleSidebar || visibleSidebar)
|
||||||
|
);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const value = {
|
||||||
|
enabledSidebar,
|
||||||
|
visibleSidebar,
|
||||||
|
setVisibleSidebar,
|
||||||
|
visibleMobileSearch,
|
||||||
|
toggleMobileSearch,
|
||||||
|
toggleSidebar,
|
||||||
|
};
|
||||||
|
|
||||||
|
return <LayoutContext.Provider value={value}>{children}</LayoutContext.Provider>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const LayoutConsumer = LayoutContext.Consumer;
|
export const LayoutConsumer = LayoutContext.Consumer;
|
||||||
|
|||||||
20
frontend/src/static/js/utils/helpers/embeddedApp.ts
Normal file
20
frontend/src/static/js/utils/helpers/embeddedApp.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
export function inEmbeddedApp() {
|
||||||
|
try {
|
||||||
|
const params = new URL(globalThis.location.href).searchParams;
|
||||||
|
const mode = params.get('mode');
|
||||||
|
|
||||||
|
if (mode === 'embed_mode') {
|
||||||
|
sessionStorage.setItem('media_cms_embed_mode', 'true');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode === 'standard') {
|
||||||
|
sessionStorage.removeItem('media_cms_embed_mode');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sessionStorage.getItem('media_cms_embed_mode') === 'true';
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,3 +14,4 @@ export * from './quickSort';
|
|||||||
export * from './requests';
|
export * from './requests';
|
||||||
export { translateString } from './translate';
|
export { translateString } from './translate';
|
||||||
export { replaceString } from './replacementStrings';
|
export { replaceString } from './replacementStrings';
|
||||||
|
export * from './embeddedApp';
|
||||||
|
|||||||
@@ -3,64 +3,83 @@ import ReactDOM from 'react-dom';
|
|||||||
import { ThemeProvider } from './contexts/ThemeContext';
|
import { ThemeProvider } from './contexts/ThemeContext';
|
||||||
import { LayoutProvider } from './contexts/LayoutContext';
|
import { LayoutProvider } from './contexts/LayoutContext';
|
||||||
import { UserProvider } from './contexts/UserContext';
|
import { UserProvider } from './contexts/UserContext';
|
||||||
|
import { inEmbeddedApp } from './helpers';
|
||||||
|
|
||||||
const AppProviders = ({ children }) => (
|
const AppProviders = ({ children }) => (
|
||||||
<LayoutProvider>
|
<LayoutProvider>
|
||||||
<ThemeProvider>
|
<ThemeProvider>
|
||||||
<UserProvider>{children}</UserProvider>
|
<UserProvider>{children}</UserProvider>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
</LayoutProvider>
|
</LayoutProvider>
|
||||||
);
|
);
|
||||||
|
|
||||||
import { PageHeader, PageSidebar } from '../components/page-layout';
|
import { PageHeader, PageSidebar } from '../components/page-layout';
|
||||||
|
|
||||||
export function renderPage(idSelector, PageComponent) {
|
export function renderPage(idSelector, PageComponent) {
|
||||||
const appHeader = document.getElementById('app-header');
|
if (inEmbeddedApp()) {
|
||||||
const appSidebar = document.getElementById('app-sidebar');
|
globalThis.document.body.classList.add('embedded-app');
|
||||||
const appContent = idSelector ? document.getElementById(idSelector) : undefined;
|
globalThis.document.body.classList.remove('visible-sidebar');
|
||||||
|
|
||||||
if (appContent && PageComponent) {
|
const appContent = idSelector ? document.getElementById(idSelector) : undefined;
|
||||||
ReactDOM.render(
|
|
||||||
<AppProviders>
|
if (appContent && PageComponent) {
|
||||||
{appHeader ? ReactDOM.createPortal(<PageHeader />, appHeader) : null}
|
ReactDOM.render(
|
||||||
{appSidebar ? ReactDOM.createPortal(<PageSidebar />, appSidebar) : null}
|
<AppProviders>
|
||||||
<PageComponent />
|
<PageComponent />
|
||||||
</AppProviders>,
|
</AppProviders>,
|
||||||
appContent
|
appContent
|
||||||
);
|
);
|
||||||
} else if (appHeader && appSidebar) {
|
}
|
||||||
ReactDOM.render(
|
|
||||||
<AppProviders>
|
return;
|
||||||
{ReactDOM.createPortal(<PageHeader />, appHeader)}
|
}
|
||||||
<PageSidebar />
|
|
||||||
</AppProviders>,
|
const appContent = idSelector ? document.getElementById(idSelector) : undefined;
|
||||||
appSidebar
|
const appHeader = document.getElementById('app-header');
|
||||||
);
|
const appSidebar = document.getElementById('app-sidebar');
|
||||||
} else if (appHeader) {
|
|
||||||
ReactDOM.render(
|
if (appContent && PageComponent) {
|
||||||
<LayoutProvider>
|
ReactDOM.render(
|
||||||
<ThemeProvider>
|
<AppProviders>
|
||||||
<UserProvider>
|
{appHeader ? ReactDOM.createPortal(<PageHeader />, appHeader) : null}
|
||||||
<PageHeader />
|
{appSidebar ? ReactDOM.createPortal(<PageSidebar />, appSidebar) : null}
|
||||||
</UserProvider>
|
<PageComponent />
|
||||||
</ThemeProvider>
|
</AppProviders>,
|
||||||
</LayoutProvider>,
|
appContent
|
||||||
appSidebar
|
);
|
||||||
);
|
} else if (appHeader && appSidebar) {
|
||||||
} else if (appSidebar) {
|
ReactDOM.render(
|
||||||
ReactDOM.render(
|
<AppProviders>
|
||||||
<AppProviders>
|
{ReactDOM.createPortal(<PageHeader />, appHeader)}
|
||||||
<PageSidebar />
|
<PageSidebar />
|
||||||
</AppProviders>,
|
</AppProviders>,
|
||||||
appSidebar
|
appSidebar
|
||||||
);
|
);
|
||||||
}
|
} else if (appHeader) {
|
||||||
|
ReactDOM.render(
|
||||||
|
<LayoutProvider>
|
||||||
|
<ThemeProvider>
|
||||||
|
<UserProvider>
|
||||||
|
<PageHeader />
|
||||||
|
</UserProvider>
|
||||||
|
</ThemeProvider>
|
||||||
|
</LayoutProvider>,
|
||||||
|
appSidebar
|
||||||
|
);
|
||||||
|
} else if (appSidebar) {
|
||||||
|
ReactDOM.render(
|
||||||
|
<AppProviders>
|
||||||
|
<PageSidebar />
|
||||||
|
</AppProviders>,
|
||||||
|
appSidebar
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function renderEmbedPage(idSelector, PageComponent) {
|
export function renderEmbedPage(idSelector, PageComponent) {
|
||||||
const appContent = idSelector ? document.getElementById(idSelector) : undefined;
|
const appContent = idSelector ? document.getElementById(idSelector) : undefined;
|
||||||
|
|
||||||
if (appContent && PageComponent) {
|
if (appContent && PageComponent) {
|
||||||
ReactDOM.render(<PageComponent />, appContent);
|
ReactDOM.render(<PageComponent />, appContent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user