mirror of
https://github.com/mediacms-io/mediacms.git
synced 2026-02-04 06:22:59 -05:00
wtv
This commit is contained in:
@@ -1 +1 @@
|
||||
VERSION = "8"
|
||||
VERSION = "8.07"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { translateString } from '../utils/helpers/';
|
||||
import { translateString, inEmbeddedApp } from '../utils/helpers/';
|
||||
|
||||
interface MediaListHeaderProps {
|
||||
title?: string;
|
||||
@@ -11,10 +11,12 @@ interface MediaListHeaderProps {
|
||||
|
||||
export const MediaListHeader: React.FC<MediaListHeaderProps> = (props) => {
|
||||
const viewAllText = props.viewAllText || translateString('VIEW ALL');
|
||||
const isEmbedMode = inEmbeddedApp();
|
||||
|
||||
return (
|
||||
<div className={(props.className ? props.className + ' ' : '') + 'media-list-header'} style={props.style}>
|
||||
<h2>{props.title}</h2>
|
||||
{props.viewAllLink ? (
|
||||
{!isEmbedMode && props.viewAllLink ? (
|
||||
<h3>
|
||||
{' '}
|
||||
<a href={props.viewAllLink} title={viewAllText}>
|
||||
|
||||
@@ -1,18 +1,50 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useMediaItem } from '../../utils/hooks/';
|
||||
import { PositiveInteger, PositiveIntegerOrZero } from '../../utils/helpers/';
|
||||
import { PositiveInteger, PositiveIntegerOrZero, inEmbeddedApp } from '../../utils/helpers/';
|
||||
import { MediaItemThumbnailLink, itemClassname } from './includes/items/';
|
||||
import { Item } from './Item';
|
||||
|
||||
export function MediaItem(props) {
|
||||
const type = props.type;
|
||||
const isEmbedMode = inEmbeddedApp();
|
||||
|
||||
const [titleComponent, descriptionComponent, thumbnailUrl, UnderThumbWrapper, editMediaComponent, metaComponents, viewMediaComponent] =
|
||||
const [titleComponentOrig, descriptionComponent, thumbnailUrl, UnderThumbWrapperOrig, editMediaComponent, metaComponents, viewMediaComponent] =
|
||||
useMediaItem({ ...props, type });
|
||||
|
||||
// In embed mode, override components to remove links
|
||||
const ItemTitle = ({ title }) => (
|
||||
<h3>
|
||||
<span>{title}</span>
|
||||
</h3>
|
||||
);
|
||||
|
||||
const ItemMain = ({ children }) => <div className="item-main">{children}</div>;
|
||||
|
||||
const titleComponent = isEmbedMode
|
||||
? () => <ItemTitle title={props.title} />
|
||||
: titleComponentOrig;
|
||||
|
||||
const UnderThumbWrapper = isEmbedMode ? ItemMain : UnderThumbWrapperOrig;
|
||||
|
||||
function thumbnailComponent() {
|
||||
if (isEmbedMode) {
|
||||
// In embed mode, render thumbnail without link
|
||||
const thumbStyle = thumbnailUrl ? { backgroundImage: "url('" + thumbnailUrl + "')" } : null;
|
||||
return (
|
||||
<div
|
||||
key="item-thumb"
|
||||
className={'item-thumb' + (!thumbnailUrl ? ' no-thumb' : '')}
|
||||
style={thumbStyle}
|
||||
>
|
||||
{thumbnailUrl ? (
|
||||
<div key="item-type-icon" className="item-type-icon">
|
||||
<div></div>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return <MediaItemThumbnailLink src={thumbnailUrl} title={props.title} link={props.link} />;
|
||||
}
|
||||
|
||||
@@ -23,13 +55,15 @@ export function MediaItem(props) {
|
||||
);
|
||||
|
||||
const finalClassname = containerClassname +
|
||||
(props.showSelection ? ' with-selection' : '') +
|
||||
(props.showSelection && !isEmbedMode ? ' with-selection' : '') +
|
||||
(props.isSelected ? ' selected' : '') +
|
||||
(props.hasAnySelection ? ' has-any-selection' : '');
|
||||
(props.hasAnySelection || isEmbedMode ? ' has-any-selection' : '');
|
||||
|
||||
const handleItemClick = (e) => {
|
||||
// If there's any selection active, clicking the item should toggle selection
|
||||
if (props.hasAnySelection && props.onCheckboxChange) {
|
||||
const isEmbedMode = inEmbeddedApp();
|
||||
|
||||
// In embed mode or if there's any selection active, clicking the item should toggle selection
|
||||
if ((isEmbedMode || props.hasAnySelection) && props.onCheckboxChange) {
|
||||
// Check if clicking on the checkbox itself, edit icon, or view icon
|
||||
if (e.target.closest('.item-selection-checkbox') ||
|
||||
e.target.closest('.item-edit-icon') ||
|
||||
@@ -59,16 +93,24 @@ export function MediaItem(props) {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{editMediaComponent()}
|
||||
{viewMediaComponent()}
|
||||
{!isEmbedMode && editMediaComponent()}
|
||||
{!isEmbedMode && viewMediaComponent()}
|
||||
|
||||
{thumbnailComponent()}
|
||||
|
||||
{isEmbedMode ? (
|
||||
<UnderThumbWrapper>
|
||||
{titleComponent()}
|
||||
{metaComponents()}
|
||||
{descriptionComponent()}
|
||||
</UnderThumbWrapper>
|
||||
) : (
|
||||
<UnderThumbWrapper title={props.title} link={props.link}>
|
||||
{titleComponent()}
|
||||
{metaComponents()}
|
||||
{descriptionComponent()}
|
||||
</UnderThumbWrapper>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useMediaItem } from '../../utils/hooks/';
|
||||
import { PositiveIntegerOrZero } from '../../utils/helpers/';
|
||||
import { PositiveIntegerOrZero, inEmbeddedApp } from '../../utils/helpers/';
|
||||
import { MediaDurationInfo } from '../../utils/classes/';
|
||||
import { MediaPlaylistOptions } from '../media-playlist-options/MediaPlaylistOptions';
|
||||
import { MediaItemDuration, MediaItemPlaylistIndex, itemClassname } from './includes/items/';
|
||||
@@ -9,10 +9,26 @@ import { MediaItem } from './MediaItem';
|
||||
|
||||
export function MediaItemAudio(props) {
|
||||
const type = props.type;
|
||||
const isEmbedMode = inEmbeddedApp();
|
||||
|
||||
const [titleComponent, descriptionComponent, thumbnailUrl, UnderThumbWrapper, editMediaComponent, metaComponents, viewMediaComponent] =
|
||||
const [titleComponentOrig, descriptionComponent, thumbnailUrl, UnderThumbWrapperOrig, editMediaComponent, metaComponents, viewMediaComponent] =
|
||||
useMediaItem({ ...props, type });
|
||||
|
||||
// In embed mode, override components to remove links
|
||||
const ItemTitle = ({ title }) => (
|
||||
<h3>
|
||||
<span>{title}</span>
|
||||
</h3>
|
||||
);
|
||||
|
||||
const ItemMain = ({ children }) => <div className="item-main">{children}</div>;
|
||||
|
||||
const titleComponent = isEmbedMode
|
||||
? () => <ItemTitle title={props.title} />
|
||||
: titleComponentOrig;
|
||||
|
||||
const UnderThumbWrapper = isEmbedMode ? ItemMain : UnderThumbWrapperOrig;
|
||||
|
||||
const _MediaDurationInfo = new MediaDurationInfo();
|
||||
|
||||
_MediaDurationInfo.update(props.duration);
|
||||
@@ -22,6 +38,21 @@ export function MediaItemAudio(props) {
|
||||
const durationISO8601 = _MediaDurationInfo.ISO8601();
|
||||
|
||||
function thumbnailComponent() {
|
||||
if (isEmbedMode) {
|
||||
// In embed mode, render thumbnail without link
|
||||
return (
|
||||
<div
|
||||
key="item-thumb"
|
||||
className={'item-thumb' + (!thumbnailUrl ? ' no-thumb' : '')}
|
||||
style={!thumbnailUrl ? null : { backgroundImage: "url('" + thumbnailUrl + "')" }}
|
||||
>
|
||||
{props.inPlaylistView ? null : (
|
||||
<MediaItemDuration ariaLabel={duration} time={durationISO8601} text={durationStr} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const attr = {
|
||||
key: 'item-thumb',
|
||||
href: props.link,
|
||||
@@ -66,13 +97,13 @@ export function MediaItemAudio(props) {
|
||||
);
|
||||
|
||||
const finalClassname = containerClassname +
|
||||
(props.showSelection ? ' with-selection' : '') +
|
||||
(props.showSelection && !isEmbedMode ? ' with-selection' : '') +
|
||||
(props.isSelected ? ' selected' : '') +
|
||||
(props.hasAnySelection ? ' has-any-selection' : '');
|
||||
(props.hasAnySelection || isEmbedMode ? ' has-any-selection' : '');
|
||||
|
||||
const handleItemClick = (e) => {
|
||||
// If there's any selection active, clicking the item should toggle selection
|
||||
if (props.hasAnySelection && props.onCheckboxChange) {
|
||||
// In embed mode or if there's any selection active, clicking the item should toggle selection
|
||||
if ((isEmbedMode || props.hasAnySelection) && props.onCheckboxChange) {
|
||||
// Check if clicking on the checkbox itself, edit icon, or view icon
|
||||
if (e.target.closest('.item-selection-checkbox') ||
|
||||
e.target.closest('.item-edit-icon') ||
|
||||
@@ -104,16 +135,24 @@ export function MediaItemAudio(props) {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{editMediaComponent()}
|
||||
{viewMediaComponent()}
|
||||
{!isEmbedMode && editMediaComponent()}
|
||||
{!isEmbedMode && viewMediaComponent()}
|
||||
|
||||
{thumbnailComponent()}
|
||||
|
||||
{isEmbedMode ? (
|
||||
<UnderThumbWrapper>
|
||||
{titleComponent()}
|
||||
{metaComponents()}
|
||||
{descriptionComponent()}
|
||||
</UnderThumbWrapper>
|
||||
) : (
|
||||
<UnderThumbWrapper title={props.title} link={props.link}>
|
||||
{titleComponent()}
|
||||
{metaComponents()}
|
||||
{descriptionComponent()}
|
||||
</UnderThumbWrapper>
|
||||
)}
|
||||
|
||||
{playlistOptionsComponent()}
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useMediaItem } from '../../utils/hooks/';
|
||||
import { PositiveIntegerOrZero } from '../../utils/helpers/';
|
||||
import { PositiveIntegerOrZero, inEmbeddedApp } from '../../utils/helpers/';
|
||||
import { MediaDurationInfo } from '../../utils/classes/';
|
||||
import { MediaPlaylistOptions } from '../media-playlist-options/MediaPlaylistOptions.jsx';
|
||||
import { MediaItemVideoPlayer, MediaItemDuration, MediaItemVideoPreviewer, MediaItemPlaylistIndex, itemClassname } from './includes/items/';
|
||||
@@ -9,10 +9,26 @@ import { MediaItem } from './MediaItem';
|
||||
|
||||
export function MediaItemVideo(props) {
|
||||
const type = props.type;
|
||||
const isEmbedMode = inEmbeddedApp();
|
||||
|
||||
const [titleComponent, descriptionComponent, thumbnailUrl, UnderThumbWrapper, editMediaComponent, metaComponents, viewMediaComponent] =
|
||||
const [titleComponentOrig, descriptionComponent, thumbnailUrl, UnderThumbWrapperOrig, editMediaComponent, metaComponents, viewMediaComponent] =
|
||||
useMediaItem({ ...props, type });
|
||||
|
||||
// In embed mode, override components to remove links
|
||||
const ItemTitle = ({ title }) => (
|
||||
<h3>
|
||||
<span>{title}</span>
|
||||
</h3>
|
||||
);
|
||||
|
||||
const ItemMain = ({ children }) => <div className="item-main">{children}</div>;
|
||||
|
||||
const titleComponent = isEmbedMode
|
||||
? () => <ItemTitle title={props.title} />
|
||||
: titleComponentOrig;
|
||||
|
||||
const UnderThumbWrapper = isEmbedMode ? ItemMain : UnderThumbWrapperOrig;
|
||||
|
||||
const _MediaDurationInfo = new MediaDurationInfo();
|
||||
|
||||
_MediaDurationInfo.update(props.duration);
|
||||
@@ -26,6 +42,24 @@ export function MediaItemVideo(props) {
|
||||
}
|
||||
|
||||
function thumbnailComponent() {
|
||||
if (isEmbedMode) {
|
||||
// In embed mode, render thumbnail without link
|
||||
return (
|
||||
<div
|
||||
key="item-thumb"
|
||||
className={'item-thumb' + (!thumbnailUrl ? ' no-thumb' : '')}
|
||||
style={!thumbnailUrl ? null : { backgroundImage: "url('" + thumbnailUrl + "')" }}
|
||||
>
|
||||
{props.inPlaylistView ? null : (
|
||||
<MediaItemDuration ariaLabel={duration} time={durationISO8601} text={durationStr} />
|
||||
)}
|
||||
{props.inPlaylistView || props.inPlaylistPage ? null : (
|
||||
<MediaItemVideoPreviewer url={props.preview_thumbnail} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const attr = {
|
||||
key: 'item-thumb',
|
||||
href: props.link,
|
||||
@@ -73,13 +107,13 @@ export function MediaItemVideo(props) {
|
||||
);
|
||||
|
||||
const finalClassname = containerClassname +
|
||||
(props.showSelection ? ' with-selection' : '') +
|
||||
(props.showSelection && !isEmbedMode ? ' with-selection' : '') +
|
||||
(props.isSelected ? ' selected' : '') +
|
||||
(props.hasAnySelection ? ' has-any-selection' : '');
|
||||
(props.hasAnySelection || isEmbedMode ? ' has-any-selection' : '');
|
||||
|
||||
const handleItemClick = (e) => {
|
||||
// If there's any selection active, clicking the item should toggle selection
|
||||
if (props.hasAnySelection && props.onCheckboxChange) {
|
||||
// In embed mode or if there's any selection active, clicking the item should toggle selection
|
||||
if ((isEmbedMode || props.hasAnySelection) && props.onCheckboxChange) {
|
||||
// Check if clicking on the checkbox itself, edit icon, or view icon
|
||||
if (e.target.closest('.item-selection-checkbox') ||
|
||||
e.target.closest('.item-edit-icon') ||
|
||||
@@ -111,20 +145,28 @@ export function MediaItemVideo(props) {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{editMediaComponent()}
|
||||
{viewMediaComponent()}
|
||||
{!isEmbedMode && editMediaComponent()}
|
||||
{!isEmbedMode && viewMediaComponent()}
|
||||
|
||||
{props.hasMediaViewer ? videoViewerComponent() : thumbnailComponent()}
|
||||
|
||||
{isEmbedMode ? (
|
||||
<UnderThumbWrapper>
|
||||
{titleComponent()}
|
||||
{metaComponents()}
|
||||
{descriptionComponent()}
|
||||
</UnderThumbWrapper>
|
||||
) : (
|
||||
<UnderThumbWrapper title={props.title} link={props.link}>
|
||||
{titleComponent()}
|
||||
{metaComponents()}
|
||||
{descriptionComponent()}
|
||||
</UnderThumbWrapper>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{playlistOptionsComponent()}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { LinksContext, MemberContext, SiteContext } from '../../utils/contexts/'
|
||||
import { PageStore, ProfilePageStore } from '../../utils/stores/';
|
||||
import { PageActions, ProfilePageActions } from '../../utils/actions/';
|
||||
import { CircleIconButton, PopupMain } from '../_shared';
|
||||
import { translateString } from '../../utils/helpers/';
|
||||
import { translateString, inEmbeddedApp } from '../../utils/helpers/';
|
||||
|
||||
class ProfileSearchBar extends React.PureComponent {
|
||||
constructor(props) {
|
||||
@@ -372,18 +372,22 @@ class NavMenuInlineTabs extends React.PureComponent {
|
||||
}
|
||||
|
||||
render() {
|
||||
const isEmbedMode = inEmbeddedApp();
|
||||
|
||||
return (
|
||||
<nav ref="tabsNav" className="profile-nav items-list-outer list-inline list-slider">
|
||||
<div className="profile-nav-inner items-list-outer">
|
||||
{this.state.displayPrev ? this.previousBtn : null}
|
||||
|
||||
<ul className="items-list-wrap" ref="itemsListWrap">
|
||||
{!isEmbedMode ? (
|
||||
<InlineTab
|
||||
id="about"
|
||||
isActive={'about' === this.props.type}
|
||||
label={translateString('About')}
|
||||
link={LinksContext._currentValue.profile.about}
|
||||
/>
|
||||
) : null}
|
||||
<InlineTab
|
||||
id="media"
|
||||
isActive={'media' === this.props.type}
|
||||
@@ -407,7 +411,7 @@ class NavMenuInlineTabs extends React.PureComponent {
|
||||
/>
|
||||
) : null}
|
||||
|
||||
{MemberContext._currentValue.can.saveMedia ? (
|
||||
{!isEmbedMode && MemberContext._currentValue.can.saveMedia ? (
|
||||
<InlineTab
|
||||
id="playlists"
|
||||
isActive={'playlists' === this.props.type}
|
||||
@@ -768,7 +772,15 @@ export default function ProfilePagesHeader(props) {
|
||||
)}
|
||||
|
||||
<div className="profile-info-nav-wrap">
|
||||
{props.author.thumbnail_url || props.author.name ? (
|
||||
{inEmbeddedApp() ? (
|
||||
<div className="profile-info">
|
||||
<div className="profile-info-inner">
|
||||
<div>
|
||||
<h1>{translateString('Embed Media')}</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : props.author.thumbnail_url || props.author.name ? (
|
||||
<div className="profile-info">
|
||||
<div className="profile-info-inner">
|
||||
<div>
|
||||
|
||||
@@ -202,13 +202,29 @@ export class ProfileMediaPage extends Page {
|
||||
}
|
||||
|
||||
handleMediaSelection(mediaId, isSelected) {
|
||||
const isEmbedMode = inEmbeddedApp();
|
||||
|
||||
this.setState((prevState) => {
|
||||
const newSelectedMedia = new Set(prevState.selectedMedia);
|
||||
const newSelectedMedia = new Set();
|
||||
|
||||
// In embed mode, only allow single selection
|
||||
if (isEmbedMode) {
|
||||
if (isSelected) {
|
||||
newSelectedMedia.add(mediaId);
|
||||
console.log('Selected media item:', mediaId);
|
||||
}
|
||||
} else {
|
||||
// Normal mode: allow multiple selection
|
||||
newSelectedMedia.clear();
|
||||
prevState.selectedMedia.forEach((id) => newSelectedMedia.add(id));
|
||||
|
||||
if (isSelected) {
|
||||
newSelectedMedia.add(mediaId);
|
||||
} else {
|
||||
newSelectedMedia.delete(mediaId);
|
||||
}
|
||||
}
|
||||
|
||||
return { selectedMedia: newSelectedMedia };
|
||||
});
|
||||
}
|
||||
@@ -917,6 +933,7 @@ export class ProfileMediaPage extends Page {
|
||||
const authorData = ProfilePageStore.get('author-data');
|
||||
|
||||
const isMediaAuthor = authorData && authorData.username === MemberContext._currentValue.username;
|
||||
const isEmbedMode = inEmbeddedApp();
|
||||
|
||||
// Check if any filters are active (excluding default sort and tags)
|
||||
const hasActiveFilters =
|
||||
@@ -948,15 +965,16 @@ export class ProfileMediaPage extends Page {
|
||||
this.state.author ? (
|
||||
<ProfilePagesContent key="ProfilePagesContent">
|
||||
<MediaListWrapper
|
||||
title={this.state.title}
|
||||
title={isEmbedMode ? undefined : this.state.title}
|
||||
className="items-list-ver"
|
||||
showBulkActions={isMediaAuthor}
|
||||
style={isEmbedMode ? { marginTop: '24px' } : undefined}
|
||||
showBulkActions={!isEmbedMode && isMediaAuthor}
|
||||
selectedCount={this.state.selectedMedia.size}
|
||||
totalCount={this.state.availableMediaIds.length}
|
||||
onBulkAction={this.handleBulkAction}
|
||||
onSelectAll={this.handleSelectAll}
|
||||
onDeselectAll={this.handleDeselectAll}
|
||||
showAddMediaButton={isMediaAuthor}
|
||||
showAddMediaButton={!isEmbedMode && isMediaAuthor}
|
||||
>
|
||||
<ProfileMediaFilters
|
||||
hidden={this.state.hiddenFilters}
|
||||
@@ -979,7 +997,7 @@ export class ProfileMediaPage extends Page {
|
||||
hideViews={!PageStore.get('config-media-item').displayViews}
|
||||
hideDate={!PageStore.get('config-media-item').displayPublishDate}
|
||||
canEdit={isMediaAuthor}
|
||||
showSelection={isMediaAuthor}
|
||||
showSelection={isMediaAuthor || isEmbedMode}
|
||||
hasAnySelection={this.state.selectedMedia.size > 0}
|
||||
selectedMedia={this.state.selectedMedia}
|
||||
onMediaSelection={this.handleMediaSelection}
|
||||
|
||||
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