mirror of
https://github.com/mediacms-io/mediacms.git
synced 2026-03-16 09:51:56 -04:00
all
This commit is contained in:
1
LTI_README.md
Normal file
1
LTI_README.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Django admin → /admin/lti/ltiplatform/ --> Change to: https://YOUR_MOODLE/filter/mediacms/lti_auth.php
|
||||||
@@ -1 +1 @@
|
|||||||
VERSION = "8.37"
|
VERSION = "8.91"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from datetime import datetime, timedelta
|
|||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.postgres.search import SearchQuery
|
from django.contrib.postgres.search import SearchQuery
|
||||||
from django.db.models import Count, Q
|
from django.db.models import Count, Prefetch, Q, prefetch_related_objects
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
from drf_yasg import openapi
|
from drf_yasg import openapi
|
||||||
from drf_yasg.utils import swagger_auto_schema
|
from drf_yasg.utils import swagger_auto_schema
|
||||||
@@ -113,6 +113,8 @@ class MediaList(APIView):
|
|||||||
upload_date = params.get('upload_date', '').strip()
|
upload_date = params.get('upload_date', '').strip()
|
||||||
duration = params.get('duration', '').strip()
|
duration = params.get('duration', '').strip()
|
||||||
publish_state = params.get('publish_state', '').strip()
|
publish_state = params.get('publish_state', '').strip()
|
||||||
|
shared_user = params.get('shared_user', '').strip()
|
||||||
|
shared_group = params.get('shared_group', '').strip()
|
||||||
query = params.get("q", "").strip().lower()
|
query = params.get("q", "").strip().lower()
|
||||||
|
|
||||||
parsed_combined = False
|
parsed_combined = False
|
||||||
@@ -153,6 +155,7 @@ class MediaList(APIView):
|
|||||||
gte = datetime(year, 1, 1)
|
gte = datetime(year, 1, 1)
|
||||||
|
|
||||||
already_sorted = False
|
already_sorted = False
|
||||||
|
include_sharing_info = False
|
||||||
pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
|
pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
|
||||||
|
|
||||||
if show_param == "recommended":
|
if show_param == "recommended":
|
||||||
@@ -173,6 +176,7 @@ class MediaList(APIView):
|
|||||||
conditions |= Q(category__in=rbac_categories, user=self.request.user)
|
conditions |= Q(category__in=rbac_categories, user=self.request.user)
|
||||||
|
|
||||||
media = base_queryset.filter(conditions).distinct()
|
media = base_queryset.filter(conditions).distinct()
|
||||||
|
include_sharing_info = True
|
||||||
elif show_param == "shared_with_me":
|
elif show_param == "shared_with_me":
|
||||||
if not self.request.user.is_authenticated:
|
if not self.request.user.is_authenticated:
|
||||||
media = Media.objects.none()
|
media = Media.objects.none()
|
||||||
@@ -192,6 +196,8 @@ class MediaList(APIView):
|
|||||||
user = get_object_or_404(user_queryset, username=author_param)
|
user = get_object_or_404(user_queryset, username=author_param)
|
||||||
if self.request.user == user or is_mediacms_editor(self.request.user):
|
if self.request.user == user or is_mediacms_editor(self.request.user):
|
||||||
media = Media.objects.filter(user=user).prefetch_related("user", "tags")
|
media = Media.objects.filter(user=user).prefetch_related("user", "tags")
|
||||||
|
if self.request.user == user:
|
||||||
|
include_sharing_info = True
|
||||||
else:
|
else:
|
||||||
media = self._get_media_queryset(request, user)
|
media = self._get_media_queryset(request, user)
|
||||||
already_sorted = True
|
already_sorted = True
|
||||||
@@ -242,6 +248,12 @@ class MediaList(APIView):
|
|||||||
elif publish_state in ['private', 'public', 'unlisted']:
|
elif publish_state in ['private', 'public', 'unlisted']:
|
||||||
media = media.filter(state=publish_state)
|
media = media.filter(state=publish_state)
|
||||||
|
|
||||||
|
if shared_user and include_sharing_info:
|
||||||
|
media = media.filter(permissions__user__username=shared_user).distinct()
|
||||||
|
|
||||||
|
if shared_group and include_sharing_info:
|
||||||
|
media = media.filter(category__is_rbac_category=True, category__rbac_groups__name=shared_group).distinct()
|
||||||
|
|
||||||
if not already_sorted:
|
if not already_sorted:
|
||||||
media = media.order_by(f"{ordering}{sort_by}")
|
media = media.order_by(f"{ordering}{sort_by}")
|
||||||
|
|
||||||
@@ -251,6 +263,15 @@ class MediaList(APIView):
|
|||||||
|
|
||||||
page = paginator.paginate_queryset(media, request)
|
page = paginator.paginate_queryset(media, request)
|
||||||
|
|
||||||
|
prefetch_related_objects(page, 'tags')
|
||||||
|
|
||||||
|
if include_sharing_info:
|
||||||
|
prefetch_related_objects(
|
||||||
|
page,
|
||||||
|
Prefetch('permissions', queryset=MediaPermission.objects.select_related('user')),
|
||||||
|
Prefetch('category', queryset=Category.objects.filter(is_rbac_category=True).prefetch_related('rbac_groups'), to_attr='rbac_categories_prefetched'),
|
||||||
|
)
|
||||||
|
|
||||||
serializer = MediaSerializer(page, many=True, context={"request": request})
|
serializer = MediaSerializer(page, many=True, context={"request": request})
|
||||||
|
|
||||||
tags_set = set()
|
tags_set = set()
|
||||||
@@ -261,6 +282,19 @@ class MediaList(APIView):
|
|||||||
|
|
||||||
response = paginator.get_paginated_response(serializer.data)
|
response = paginator.get_paginated_response(serializer.data)
|
||||||
response.data['tags'] = tags
|
response.data['tags'] = tags
|
||||||
|
|
||||||
|
if include_sharing_info:
|
||||||
|
shared_users = {}
|
||||||
|
shared_groups = {}
|
||||||
|
for media_obj in page:
|
||||||
|
for perm in media_obj.permissions.all():
|
||||||
|
shared_users[perm.user.username] = {"username": perm.user.username, "name": perm.user.name or perm.user.username}
|
||||||
|
for cat in getattr(media_obj, 'rbac_categories_prefetched', []):
|
||||||
|
for group in cat.rbac_groups.all():
|
||||||
|
shared_groups[group.name] = {"name": group.name}
|
||||||
|
response.data['shared_users'] = list(shared_users.values())
|
||||||
|
response.data['shared_groups'] = list(shared_groups.values())
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@swagger_auto_schema(
|
@swagger_auto_schema(
|
||||||
|
|||||||
@@ -576,6 +576,7 @@
|
|||||||
// Ensure icon buttons are visible on mobile
|
// Ensure icon buttons are visible on mobile
|
||||||
&.media-search,
|
&.media-search,
|
||||||
&.media-filters-toggle,
|
&.media-filters-toggle,
|
||||||
|
&.media-sharing-toggle,
|
||||||
&.media-tags-toggle,
|
&.media-tags-toggle,
|
||||||
&.media-sorting-toggle {
|
&.media-sorting-toggle {
|
||||||
@media screen and (max-width: 768px) {
|
@media screen and (max-width: 768px) {
|
||||||
@@ -901,6 +902,13 @@ $-max-width: $-hor-spaces + ( 2 * $item-width ) - 1;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mi-sharing-filter-options {
|
||||||
|
> .active button,
|
||||||
|
> * button:hover {
|
||||||
|
background-color: #3b82f6 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$-hor-spaces: 2 * $side-empty-space;
|
$-hor-spaces: 2 * $side-empty-space;
|
||||||
$-max-width: $-hor-spaces + ( 2 * $item-width ) - 1;
|
$-max-width: $-hor-spaces + ( 2 * $item-width ) - 1;
|
||||||
|
|
||||||
|
|||||||
@@ -491,6 +491,39 @@ class NavMenuInlineTabs extends React.PureComponent {
|
|||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
) : null}
|
) : null}
|
||||||
|
{this.props.onToggleSharingClick &&
|
||||||
|
['media', 'shared_by_me'].includes(this.props.type) ? (
|
||||||
|
<li className="media-sharing-toggle">
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
cursor: 'pointer',
|
||||||
|
position: 'relative',
|
||||||
|
}}
|
||||||
|
onClick={this.props.onToggleSharingClick}
|
||||||
|
title={translateString('Shared with')}
|
||||||
|
>
|
||||||
|
<CircleIconButton buttonShadow={false}>
|
||||||
|
<i className="material-icons">people</i>
|
||||||
|
</CircleIconButton>
|
||||||
|
{this.props.hasActiveSharing ? (
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
top: '8px',
|
||||||
|
right: '8px',
|
||||||
|
width: '8px',
|
||||||
|
height: '8px',
|
||||||
|
borderRadius: '50%',
|
||||||
|
backgroundColor: 'var(--default-theme-color)',
|
||||||
|
border: '2px solid white',
|
||||||
|
}}
|
||||||
|
></span>
|
||||||
|
) : null}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
) : null}
|
||||||
{this.props.onToggleTagsClick &&
|
{this.props.onToggleTagsClick &&
|
||||||
['media', 'shared_by_me', 'shared_with_me'].includes(this.props.type) ? (
|
['media', 'shared_by_me', 'shared_with_me'].includes(this.props.type) ? (
|
||||||
<li className="media-tags-toggle">
|
<li className="media-tags-toggle">
|
||||||
@@ -570,9 +603,11 @@ NavMenuInlineTabs.propTypes = {
|
|||||||
type: PropTypes.string.isRequired,
|
type: PropTypes.string.isRequired,
|
||||||
onQueryChange: PropTypes.func,
|
onQueryChange: PropTypes.func,
|
||||||
onToggleFiltersClick: PropTypes.func,
|
onToggleFiltersClick: PropTypes.func,
|
||||||
|
onToggleSharingClick: PropTypes.func,
|
||||||
onToggleTagsClick: PropTypes.func,
|
onToggleTagsClick: PropTypes.func,
|
||||||
onToggleSortingClick: PropTypes.func,
|
onToggleSortingClick: PropTypes.func,
|
||||||
hasActiveFilters: PropTypes.bool,
|
hasActiveFilters: PropTypes.bool,
|
||||||
|
hasActiveSharing: PropTypes.bool,
|
||||||
hasActiveTags: PropTypes.bool,
|
hasActiveTags: PropTypes.bool,
|
||||||
hasActiveSort: PropTypes.bool,
|
hasActiveSort: PropTypes.bool,
|
||||||
};
|
};
|
||||||
@@ -776,9 +811,11 @@ export default function ProfilePagesHeader(props) {
|
|||||||
type={props.type}
|
type={props.type}
|
||||||
onQueryChange={props.onQueryChange}
|
onQueryChange={props.onQueryChange}
|
||||||
onToggleFiltersClick={props.onToggleFiltersClick}
|
onToggleFiltersClick={props.onToggleFiltersClick}
|
||||||
|
onToggleSharingClick={userIsAuthor ? props.onToggleSharingClick : undefined}
|
||||||
onToggleTagsClick={props.onToggleTagsClick}
|
onToggleTagsClick={props.onToggleTagsClick}
|
||||||
onToggleSortingClick={props.onToggleSortingClick}
|
onToggleSortingClick={props.onToggleSortingClick}
|
||||||
hasActiveFilters={props.hasActiveFilters}
|
hasActiveFilters={props.hasActiveFilters}
|
||||||
|
hasActiveSharing={props.hasActiveSharing}
|
||||||
hasActiveTags={props.hasActiveTags}
|
hasActiveTags={props.hasActiveTags}
|
||||||
hasActiveSort={props.hasActiveSort}
|
hasActiveSort={props.hasActiveSort}
|
||||||
/>
|
/>
|
||||||
@@ -792,9 +829,11 @@ ProfilePagesHeader.propTypes = {
|
|||||||
type: PropTypes.string.isRequired,
|
type: PropTypes.string.isRequired,
|
||||||
onQueryChange: PropTypes.func,
|
onQueryChange: PropTypes.func,
|
||||||
onToggleFiltersClick: PropTypes.func,
|
onToggleFiltersClick: PropTypes.func,
|
||||||
|
onToggleSharingClick: PropTypes.func,
|
||||||
onToggleTagsClick: PropTypes.func,
|
onToggleTagsClick: PropTypes.func,
|
||||||
onToggleSortingClick: PropTypes.func,
|
onToggleSortingClick: PropTypes.func,
|
||||||
hasActiveFilters: PropTypes.bool,
|
hasActiveFilters: PropTypes.bool,
|
||||||
|
hasActiveSharing: PropTypes.bool,
|
||||||
hasActiveTags: PropTypes.bool,
|
hasActiveTags: PropTypes.bool,
|
||||||
hasActiveSort: PropTypes.bool,
|
hasActiveSort: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,101 @@
|
|||||||
|
import React, { useState, useEffect, useRef } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { PageStore } from '../../utils/stores/';
|
||||||
|
import { FilterOptions } from '../_shared';
|
||||||
|
import { translateString } from '../../utils/helpers/';
|
||||||
|
import '../management-table/ManageItemList-filters.scss';
|
||||||
|
|
||||||
|
export function ProfileMediaSharing(props) {
|
||||||
|
const [isHidden, setIsHidden] = useState(props.hidden);
|
||||||
|
|
||||||
|
const containerRef = useRef(null);
|
||||||
|
const innerContainerRef = useRef(null);
|
||||||
|
|
||||||
|
function onWindowResize() {
|
||||||
|
if (!isHidden && containerRef.current && innerContainerRef.current) {
|
||||||
|
containerRef.current.style.height = 24 + innerContainerRef.current.offsetHeight + 'px';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setIsHidden(props.hidden);
|
||||||
|
onWindowResize();
|
||||||
|
}, [props.hidden, props.sharedUsers, props.sharedGroups]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
PageStore.on('window_resize', onWindowResize);
|
||||||
|
return () => PageStore.removeListener('window_resize', onWindowResize);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
function onUserSelect(ev) {
|
||||||
|
const username = ev.currentTarget.getAttribute('value');
|
||||||
|
const newValue = (username === 'all' || username === props.selectedSharingValue) ? null : username;
|
||||||
|
props.onSharingSelect(newValue ? 'user' : null, newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onGroupSelect(ev) {
|
||||||
|
const name = ev.currentTarget.getAttribute('value');
|
||||||
|
const newValue = (name === 'all' || name === props.selectedSharingValue) ? null : name;
|
||||||
|
props.onSharingSelect(newValue ? 'group' : null, newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasUsers = props.sharedUsers && props.sharedUsers.length > 0;
|
||||||
|
const hasGroups = props.sharedGroups && props.sharedGroups.length > 0;
|
||||||
|
|
||||||
|
const usersOptions = [
|
||||||
|
{ id: 'all', title: translateString('All') },
|
||||||
|
...(props.sharedUsers || []).map((u) => ({ id: u.username, title: u.name })),
|
||||||
|
];
|
||||||
|
const groupsOptions = [
|
||||||
|
{ id: 'all', title: translateString('All') },
|
||||||
|
...(props.sharedGroups || []).map((g) => ({ id: g.name, title: g.name })),
|
||||||
|
];
|
||||||
|
|
||||||
|
const selectedUser = props.selectedSharingType === 'user' ? props.selectedSharingValue : 'all';
|
||||||
|
const selectedGroup = props.selectedSharingType === 'group' ? props.selectedSharingValue : 'all';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div ref={containerRef} className={'mi-filters-row' + (isHidden ? ' hidden' : '')}>
|
||||||
|
<div ref={innerContainerRef} className="mi-filters-row-inner">
|
||||||
|
{hasUsers ? (
|
||||||
|
<div className="mi-filter mi-filter-full-width">
|
||||||
|
<div className="mi-filter-title">{translateString('SHARED WITH USERS')}</div>
|
||||||
|
<div className="mi-filter-options mi-filter-options-horizontal mi-sharing-filter-options">
|
||||||
|
<FilterOptions id="shared_user" options={usersOptions} selected={selectedUser} onSelect={onUserSelect} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{hasGroups ? (
|
||||||
|
<div className="mi-filter mi-filter-full-width">
|
||||||
|
<div className="mi-filter-title">{translateString('SHARED WITH GROUPS')}</div>
|
||||||
|
<div className="mi-filter-options mi-filter-options-horizontal mi-sharing-filter-options">
|
||||||
|
<FilterOptions id="shared_group" options={groupsOptions} selected={selectedGroup} onSelect={onGroupSelect} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{!hasUsers && !hasGroups ? (
|
||||||
|
<div className="mi-filter mi-filter-full-width">
|
||||||
|
<div className="mi-filter-title">{translateString('NOT SHARED WITH ANYONE')}</div>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ProfileMediaSharing.propTypes = {
|
||||||
|
hidden: PropTypes.bool,
|
||||||
|
sharedUsers: PropTypes.array,
|
||||||
|
sharedGroups: PropTypes.array,
|
||||||
|
onSharingSelect: PropTypes.func,
|
||||||
|
selectedSharingType: PropTypes.string,
|
||||||
|
selectedSharingValue: PropTypes.string,
|
||||||
|
};
|
||||||
|
|
||||||
|
ProfileMediaSharing.defaultProps = {
|
||||||
|
hidden: false,
|
||||||
|
sharedUsers: [],
|
||||||
|
sharedGroups: [],
|
||||||
|
selectedSharingType: null,
|
||||||
|
selectedSharingValue: null,
|
||||||
|
};
|
||||||
@@ -11,6 +11,7 @@ import { LazyLoadItemListAsync } from '../components/item-list/LazyLoadItemListA
|
|||||||
import { BulkActionsModals } from '../components/BulkActionsModals';
|
import { BulkActionsModals } from '../components/BulkActionsModals';
|
||||||
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 { ProfileMediaSharing } from '../components/search-filters/ProfileMediaSharing';
|
||||||
import { ProfileMediaSorting } from '../components/search-filters/ProfileMediaSorting';
|
import { ProfileMediaSorting } from '../components/search-filters/ProfileMediaSorting';
|
||||||
import { withBulkActions } from '../utils/hoc/withBulkActions';
|
import { withBulkActions } from '../utils/hoc/withBulkActions';
|
||||||
|
|
||||||
@@ -35,10 +36,15 @@ class ProfileMediaPage extends Page {
|
|||||||
hiddenFilters: true,
|
hiddenFilters: true,
|
||||||
hiddenTags: true,
|
hiddenTags: true,
|
||||||
hiddenSorting: true,
|
hiddenSorting: true,
|
||||||
|
hiddenSharing: true,
|
||||||
filterArgs: '',
|
filterArgs: '',
|
||||||
availableTags: [],
|
availableTags: [],
|
||||||
selectedTag: 'all',
|
selectedTag: 'all',
|
||||||
selectedSort: 'date_added_desc',
|
selectedSort: 'date_added_desc',
|
||||||
|
sharedUsers: [],
|
||||||
|
sharedGroups: [],
|
||||||
|
selectedSharingType: null,
|
||||||
|
selectedSharingValue: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.authorDataLoad = this.authorDataLoad.bind(this);
|
this.authorDataLoad = this.authorDataLoad.bind(this);
|
||||||
@@ -49,9 +55,11 @@ class ProfileMediaPage extends Page {
|
|||||||
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.onToggleSharingClick = this.onToggleSharingClick.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.onSharingSelect = this.onSharingSelect.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);
|
||||||
@@ -178,6 +186,7 @@ class ProfileMediaPage extends Page {
|
|||||||
hiddenFilters: !this.state.hiddenFilters,
|
hiddenFilters: !this.state.hiddenFilters,
|
||||||
hiddenTags: true,
|
hiddenTags: true,
|
||||||
hiddenSorting: true,
|
hiddenSorting: true,
|
||||||
|
hiddenSharing: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,6 +195,7 @@ class ProfileMediaPage extends Page {
|
|||||||
hiddenFilters: true,
|
hiddenFilters: true,
|
||||||
hiddenTags: !this.state.hiddenTags,
|
hiddenTags: !this.state.hiddenTags,
|
||||||
hiddenSorting: true,
|
hiddenSorting: true,
|
||||||
|
hiddenSharing: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,6 +204,16 @@ class ProfileMediaPage extends Page {
|
|||||||
hiddenFilters: true,
|
hiddenFilters: true,
|
||||||
hiddenTags: true,
|
hiddenTags: true,
|
||||||
hiddenSorting: !this.state.hiddenSorting,
|
hiddenSorting: !this.state.hiddenSorting,
|
||||||
|
hiddenSharing: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onToggleSharingClick() {
|
||||||
|
this.setState({
|
||||||
|
hiddenFilters: true,
|
||||||
|
hiddenTags: true,
|
||||||
|
hiddenSorting: true,
|
||||||
|
hiddenSharing: !this.state.hiddenSharing,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,6 +234,8 @@ class ProfileMediaPage extends Page {
|
|||||||
: null,
|
: null,
|
||||||
sort_by: this.state.selectedSort,
|
sort_by: this.state.selectedSort,
|
||||||
tag: tag,
|
tag: tag,
|
||||||
|
sharing_type: this.state.selectedSharingType,
|
||||||
|
sharing_value: this.state.selectedSharingValue,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -235,6 +257,31 @@ class ProfileMediaPage extends Page {
|
|||||||
: null,
|
: null,
|
||||||
sort_by: sortOption,
|
sort_by: sortOption,
|
||||||
tag: this.state.selectedTag,
|
tag: this.state.selectedTag,
|
||||||
|
sharing_type: this.state.selectedSharingType,
|
||||||
|
sharing_value: this.state.selectedSharingValue,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onSharingSelect(type, value) {
|
||||||
|
this.setState({ selectedSharingType: type, selectedSharingValue: value }, () => {
|
||||||
|
this.onFiltersUpdate({
|
||||||
|
media_type: this.state.filterArgs.includes('media_type')
|
||||||
|
? this.state.filterArgs.match(/media_type=([^&]*)/)?.[1]
|
||||||
|
: null,
|
||||||
|
upload_date: this.state.filterArgs.includes('upload_date')
|
||||||
|
? this.state.filterArgs.match(/upload_date=([^&]*)/)?.[1]
|
||||||
|
: null,
|
||||||
|
duration: this.state.filterArgs.includes('duration')
|
||||||
|
? this.state.filterArgs.match(/duration=([^&]*)/)?.[1]
|
||||||
|
: null,
|
||||||
|
publish_state: this.state.filterArgs.includes('publish_state')
|
||||||
|
? this.state.filterArgs.match(/publish_state=([^&]*)/)?.[1]
|
||||||
|
: null,
|
||||||
|
sort_by: this.state.selectedSort,
|
||||||
|
tag: this.state.selectedTag,
|
||||||
|
sharing_type: type,
|
||||||
|
sharing_value: value,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -248,6 +295,8 @@ class ProfileMediaPage extends Page {
|
|||||||
sort_by: null,
|
sort_by: null,
|
||||||
ordering: null,
|
ordering: null,
|
||||||
t: null,
|
t: null,
|
||||||
|
shared_user: null,
|
||||||
|
shared_group: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
switch (updatedArgs.media_type) {
|
switch (updatedArgs.media_type) {
|
||||||
@@ -306,6 +355,12 @@ class ProfileMediaPage extends Page {
|
|||||||
args.t = updatedArgs.tag;
|
args.t = updatedArgs.tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (updatedArgs.sharing_type === 'user' && updatedArgs.sharing_value) {
|
||||||
|
args.shared_user = updatedArgs.sharing_value;
|
||||||
|
} else if (updatedArgs.sharing_type === 'group' && updatedArgs.sharing_value) {
|
||||||
|
args.shared_group = updatedArgs.sharing_value;
|
||||||
|
}
|
||||||
|
|
||||||
const newArgs = [];
|
const newArgs = [];
|
||||||
|
|
||||||
for (let arg in args) {
|
for (let arg in args) {
|
||||||
@@ -353,6 +408,12 @@ class ProfileMediaPage extends Page {
|
|||||||
.filter((tag) => tag);
|
.filter((tag) => tag);
|
||||||
this.setState({ availableTags: tags });
|
this.setState({ availableTags: tags });
|
||||||
}
|
}
|
||||||
|
if (responseData && responseData.shared_users !== undefined) {
|
||||||
|
this.setState({
|
||||||
|
sharedUsers: responseData.shared_users || [],
|
||||||
|
sharedGroups: responseData.shared_groups || [],
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pageContent() {
|
pageContent() {
|
||||||
@@ -381,9 +442,11 @@ class ProfileMediaPage extends Page {
|
|||||||
onToggleFiltersClick={this.onToggleFiltersClick}
|
onToggleFiltersClick={this.onToggleFiltersClick}
|
||||||
onToggleTagsClick={this.onToggleTagsClick}
|
onToggleTagsClick={this.onToggleTagsClick}
|
||||||
onToggleSortingClick={this.onToggleSortingClick}
|
onToggleSortingClick={this.onToggleSortingClick}
|
||||||
|
onToggleSharingClick={this.onToggleSharingClick}
|
||||||
hasActiveFilters={hasActiveFilters}
|
hasActiveFilters={hasActiveFilters}
|
||||||
hasActiveTags={hasActiveTags}
|
hasActiveTags={hasActiveTags}
|
||||||
hasActiveSort={hasActiveSort}
|
hasActiveSort={hasActiveSort}
|
||||||
|
hasActiveSharing={!!this.state.selectedSharingValue}
|
||||||
hideChannelBanner={inEmbeddedApp()}
|
hideChannelBanner={inEmbeddedApp()}
|
||||||
/>
|
/>
|
||||||
) : null,
|
) : null,
|
||||||
@@ -414,6 +477,14 @@ class ProfileMediaPage extends Page {
|
|||||||
onTagSelect={this.onTagSelect}
|
onTagSelect={this.onTagSelect}
|
||||||
/>
|
/>
|
||||||
<ProfileMediaSorting hidden={this.state.hiddenSorting} onSortSelect={this.onSortSelect} />
|
<ProfileMediaSorting hidden={this.state.hiddenSorting} onSortSelect={this.onSortSelect} />
|
||||||
|
<ProfileMediaSharing
|
||||||
|
hidden={this.state.hiddenSharing}
|
||||||
|
sharedUsers={this.state.sharedUsers}
|
||||||
|
sharedGroups={this.state.sharedGroups}
|
||||||
|
onSharingSelect={this.onSharingSelect}
|
||||||
|
selectedSharingType={this.state.selectedSharingType}
|
||||||
|
selectedSharingValue={this.state.selectedSharingValue}
|
||||||
|
/>
|
||||||
<LazyLoadItemListAsync
|
<LazyLoadItemListAsync
|
||||||
key={`${this.state.requestUrl}-${this.props.bulkActions.listKey}`}
|
key={`${this.state.requestUrl}-${this.props.bulkActions.listKey}`}
|
||||||
requestUrl={this.state.requestUrl}
|
requestUrl={this.state.requestUrl}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import ProfilePagesContent from '../components/profile-page/ProfilePagesContent'
|
|||||||
import { LazyLoadItemListAsync } from '../components/item-list/LazyLoadItemListAsync';
|
import { LazyLoadItemListAsync } from '../components/item-list/LazyLoadItemListAsync';
|
||||||
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 { ProfileMediaSharing } from '../components/search-filters/ProfileMediaSharing';
|
||||||
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 { inEmbeddedApp, inSelectMediaEmbedMode } from '../utils/helpers';
|
import { inEmbeddedApp, inSelectMediaEmbedMode } from '../utils/helpers';
|
||||||
@@ -47,11 +48,16 @@ class ProfileSharedByMePage extends Page {
|
|||||||
hiddenFilters: true,
|
hiddenFilters: true,
|
||||||
hiddenTags: true,
|
hiddenTags: true,
|
||||||
hiddenSorting: true,
|
hiddenSorting: true,
|
||||||
|
hiddenSharing: true,
|
||||||
filterArgs: '',
|
filterArgs: '',
|
||||||
availableTags: [],
|
availableTags: [],
|
||||||
selectedTag: 'all',
|
selectedTag: 'all',
|
||||||
selectedSort: 'date_added_desc',
|
selectedSort: 'date_added_desc',
|
||||||
selectedMedia: new Set(), // For select media mode
|
selectedMedia: new Set(), // For select media mode
|
||||||
|
sharedUsers: [],
|
||||||
|
sharedGroups: [],
|
||||||
|
selectedSharingType: null,
|
||||||
|
selectedSharingValue: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.authorDataLoad = this.authorDataLoad.bind(this);
|
this.authorDataLoad = this.authorDataLoad.bind(this);
|
||||||
@@ -61,9 +67,11 @@ class ProfileSharedByMePage extends Page {
|
|||||||
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.onToggleSharingClick = this.onToggleSharingClick.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.onSharingSelect = this.onSharingSelect.bind(this);
|
||||||
this.onResponseDataLoaded = this.onResponseDataLoaded.bind(this);
|
this.onResponseDataLoaded = this.onResponseDataLoaded.bind(this);
|
||||||
this.handleMediaSelection = this.handleMediaSelection.bind(this);
|
this.handleMediaSelection = this.handleMediaSelection.bind(this);
|
||||||
|
|
||||||
@@ -177,6 +185,7 @@ class ProfileSharedByMePage extends Page {
|
|||||||
hiddenFilters: !this.state.hiddenFilters,
|
hiddenFilters: !this.state.hiddenFilters,
|
||||||
hiddenTags: true,
|
hiddenTags: true,
|
||||||
hiddenSorting: true,
|
hiddenSorting: true,
|
||||||
|
hiddenSharing: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,6 +194,7 @@ class ProfileSharedByMePage extends Page {
|
|||||||
hiddenFilters: true,
|
hiddenFilters: true,
|
||||||
hiddenTags: !this.state.hiddenTags,
|
hiddenTags: !this.state.hiddenTags,
|
||||||
hiddenSorting: true,
|
hiddenSorting: true,
|
||||||
|
hiddenSharing: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,6 +203,16 @@ class ProfileSharedByMePage extends Page {
|
|||||||
hiddenFilters: true,
|
hiddenFilters: true,
|
||||||
hiddenTags: true,
|
hiddenTags: true,
|
||||||
hiddenSorting: !this.state.hiddenSorting,
|
hiddenSorting: !this.state.hiddenSorting,
|
||||||
|
hiddenSharing: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onToggleSharingClick() {
|
||||||
|
this.setState({
|
||||||
|
hiddenFilters: true,
|
||||||
|
hiddenTags: true,
|
||||||
|
hiddenSorting: true,
|
||||||
|
hiddenSharing: !this.state.hiddenSharing,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,6 +225,8 @@ class ProfileSharedByMePage extends Page {
|
|||||||
publish_state: this.state.filterArgs.match(/publish_state=([^&]+)/)?.[1],
|
publish_state: this.state.filterArgs.match(/publish_state=([^&]+)/)?.[1],
|
||||||
sort_by: this.state.selectedSort,
|
sort_by: this.state.selectedSort,
|
||||||
tag: tag,
|
tag: tag,
|
||||||
|
sharing_type: this.state.selectedSharingType,
|
||||||
|
sharing_value: this.state.selectedSharingValue,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -218,6 +240,23 @@ class ProfileSharedByMePage extends Page {
|
|||||||
publish_state: this.state.filterArgs.match(/publish_state=([^&]+)/)?.[1],
|
publish_state: this.state.filterArgs.match(/publish_state=([^&]+)/)?.[1],
|
||||||
sort_by: sortBy,
|
sort_by: sortBy,
|
||||||
tag: this.state.selectedTag,
|
tag: this.state.selectedTag,
|
||||||
|
sharing_type: this.state.selectedSharingType,
|
||||||
|
sharing_value: this.state.selectedSharingValue,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onSharingSelect(type, value) {
|
||||||
|
this.setState({ selectedSharingType: type, selectedSharingValue: value }, () => {
|
||||||
|
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: this.state.selectedTag,
|
||||||
|
sharing_type: type,
|
||||||
|
sharing_value: value,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -231,6 +270,8 @@ class ProfileSharedByMePage extends Page {
|
|||||||
sort_by: null,
|
sort_by: null,
|
||||||
ordering: null,
|
ordering: null,
|
||||||
t: null,
|
t: null,
|
||||||
|
shared_user: null,
|
||||||
|
shared_group: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
switch (updatedArgs.media_type) {
|
switch (updatedArgs.media_type) {
|
||||||
@@ -292,6 +333,12 @@ class ProfileSharedByMePage extends Page {
|
|||||||
args.t = updatedArgs.tag;
|
args.t = updatedArgs.tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (updatedArgs.sharing_type === 'user' && updatedArgs.sharing_value) {
|
||||||
|
args.shared_user = updatedArgs.sharing_value;
|
||||||
|
} else if (updatedArgs.sharing_type === 'group' && updatedArgs.sharing_value) {
|
||||||
|
args.shared_group = updatedArgs.sharing_value;
|
||||||
|
}
|
||||||
|
|
||||||
const newArgs = [];
|
const newArgs = [];
|
||||||
|
|
||||||
for (let arg in args) {
|
for (let arg in args) {
|
||||||
@@ -343,6 +390,12 @@ class ProfileSharedByMePage extends Page {
|
|||||||
.filter((tag) => tag);
|
.filter((tag) => tag);
|
||||||
this.setState({ availableTags: tags });
|
this.setState({ availableTags: tags });
|
||||||
}
|
}
|
||||||
|
if (responseData && responseData.shared_users !== undefined) {
|
||||||
|
this.setState({
|
||||||
|
sharedUsers: responseData.shared_users || [],
|
||||||
|
sharedGroups: responseData.shared_groups || [],
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleMediaSelection(mediaId, isSelected) {
|
handleMediaSelection(mediaId, isSelected) {
|
||||||
@@ -413,9 +466,11 @@ class ProfileSharedByMePage extends Page {
|
|||||||
onToggleFiltersClick={this.onToggleFiltersClick}
|
onToggleFiltersClick={this.onToggleFiltersClick}
|
||||||
onToggleTagsClick={this.onToggleTagsClick}
|
onToggleTagsClick={this.onToggleTagsClick}
|
||||||
onToggleSortingClick={this.onToggleSortingClick}
|
onToggleSortingClick={this.onToggleSortingClick}
|
||||||
|
onToggleSharingClick={this.onToggleSharingClick}
|
||||||
hasActiveFilters={hasActiveFilters}
|
hasActiveFilters={hasActiveFilters}
|
||||||
hasActiveTags={this.state.selectedTag !== 'all'}
|
hasActiveTags={this.state.selectedTag !== 'all'}
|
||||||
hasActiveSort={this.state.selectedSort !== 'date_added_desc'}
|
hasActiveSort={this.state.selectedSort !== 'date_added_desc'}
|
||||||
|
hasActiveSharing={!!this.state.selectedSharingValue}
|
||||||
hideChannelBanner={inEmbeddedApp()}
|
hideChannelBanner={inEmbeddedApp()}
|
||||||
/>
|
/>
|
||||||
) : null,
|
) : null,
|
||||||
@@ -443,6 +498,14 @@ class ProfileSharedByMePage extends Page {
|
|||||||
onTagSelect={this.onTagSelect}
|
onTagSelect={this.onTagSelect}
|
||||||
/>
|
/>
|
||||||
<ProfileMediaSorting hidden={this.state.hiddenSorting} onSortSelect={this.onSortSelect} />
|
<ProfileMediaSorting hidden={this.state.hiddenSorting} onSortSelect={this.onSortSelect} />
|
||||||
|
<ProfileMediaSharing
|
||||||
|
hidden={this.state.hiddenSharing}
|
||||||
|
sharedUsers={this.state.sharedUsers}
|
||||||
|
sharedGroups={this.state.sharedGroups}
|
||||||
|
onSharingSelect={this.onSharingSelect}
|
||||||
|
selectedSharingType={this.state.selectedSharingType}
|
||||||
|
selectedSharingValue={this.state.selectedSharingValue}
|
||||||
|
/>
|
||||||
<LazyLoadItemListAsync
|
<LazyLoadItemListAsync
|
||||||
key={isSelectMediaMode ? this.state.requestUrl : `${this.state.requestUrl}-${this.props.bulkActions.listKey}`}
|
key={isSelectMediaMode ? this.state.requestUrl : `${this.state.requestUrl}-${this.props.bulkActions.listKey}`}
|
||||||
requestUrl={this.state.requestUrl}
|
requestUrl={this.state.requestUrl}
|
||||||
|
|||||||
Reference in New Issue
Block a user