mirror of
https://github.com/mediacms-io/mediacms.git
synced 2025-11-05 23:18:53 -05:00
Compare commits
2 Commits
e0f8e839cf
...
7324a0def7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7324a0def7 | ||
|
|
675b6eb977 |
@ -1 +1 @@
|
||||
VERSION = "7.3.0"
|
||||
VERSION = "11.555.0"
|
||||
|
||||
@ -200,6 +200,18 @@ class MediaList(APIView):
|
||||
media = self._get_media_queryset(request)
|
||||
already_sorted = True
|
||||
|
||||
if query:
|
||||
query = helpers.clean_query(query)
|
||||
q_parts = [q_part.rstrip("y") for q_part in query.split() if q_part not in STOP_WORDS]
|
||||
if q_parts:
|
||||
query = SearchQuery(q_parts[0] + ":*", search_type="raw")
|
||||
for part in q_parts[1:]:
|
||||
query &= SearchQuery(part + ":*", search_type="raw")
|
||||
else:
|
||||
query = None
|
||||
if query:
|
||||
media = media.filter(search=query)
|
||||
|
||||
if tag:
|
||||
media = media.filter(tags__title=tag)
|
||||
|
||||
@ -222,9 +234,6 @@ class MediaList(APIView):
|
||||
if publish_state and publish_state in ['private', 'public', 'unlisted']:
|
||||
media = media.filter(state=publish_state)
|
||||
|
||||
if query:
|
||||
media = media.filter(title__icontains=query)
|
||||
|
||||
if not already_sorted:
|
||||
media = media.order_by(f"{ordering}{sort_by}")
|
||||
|
||||
|
||||
@ -467,6 +467,9 @@
|
||||
max-width: 100%;
|
||||
margin: 0 auto;
|
||||
clear: both;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
.sliding-sidebar & {
|
||||
transition-property: width;
|
||||
@ -474,44 +477,54 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.items-list-outer .previous-slide,
|
||||
&.items-list-outer .next-slide {
|
||||
top: 4px;
|
||||
bottom: 4px;
|
||||
padding: 0 !important;
|
||||
.previous-slide,
|
||||
.next-slide {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 4px !important;
|
||||
margin: 0;
|
||||
background-color: var(--profile-page-header-bg-color);
|
||||
height: $_authorPage-navHeight;
|
||||
flex-shrink: 0;
|
||||
z-index: 2;
|
||||
|
||||
.circle-icon-button {
|
||||
margin: 0;
|
||||
background-color: var(--profile-page-header-bg-color);
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
&.items-list-outer .previous-slide {
|
||||
left: -0.75em;
|
||||
left: -1px;
|
||||
.previous-slide {
|
||||
padding-right: 8px !important;
|
||||
}
|
||||
|
||||
&.items-list-outer .next-slide {
|
||||
right: -0.75em;
|
||||
right: -1px;
|
||||
.next-slide {
|
||||
padding-left: 8px !important;
|
||||
}
|
||||
|
||||
ul {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
float: left;
|
||||
flex: 1;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
// Remove whitespace between inline-block elements on mobile
|
||||
@media screen and (max-width: 768px) {
|
||||
font-size: 0;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
font-size: 0;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
scroll-behavior: smooth;
|
||||
min-width: 0; // Allow flex item to shrink
|
||||
|
||||
// Hide scrollbar but keep functionality
|
||||
scrollbar-width: none; // Firefox
|
||||
-ms-overflow-style: none; // IE/Edge
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none; // Chrome/Safari
|
||||
}
|
||||
|
||||
li {
|
||||
@ -519,10 +532,7 @@
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
vertical-align: bottom;
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
display: block;
|
||||
@ -591,36 +601,54 @@
|
||||
}
|
||||
|
||||
&.media-search {
|
||||
display: flex !important;
|
||||
align-items: center;
|
||||
|
||||
> * {
|
||||
position: relative;
|
||||
display: table;
|
||||
float: left;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: auto;
|
||||
height: 3rem;
|
||||
|
||||
> span {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
form {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: transparent;
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
input[type='text'] {
|
||||
width: 178px;
|
||||
max-width: 178px;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
font-weight: 500;
|
||||
border-width: 0 0 2px;
|
||||
border-color: var(--profile-page-nav-link-text-color);
|
||||
background-color: transparent;
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
box-shadow: none;
|
||||
font-size: 14px;
|
||||
color: var(--profile-page-nav-link-text-color);
|
||||
|
||||
&::placeholder {
|
||||
color: var(--profile-page-nav-link-text-color);
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
border-bottom-color: var(--profile-page-nav-link-active-after-bg-color);
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,7 +5,6 @@ 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 ItemsInlineSlider from '../item-list/includes/itemLists/ItemsInlineSlider';
|
||||
import { translateString } from '../../utils/helpers/';
|
||||
|
||||
class ProfileSearchBar extends React.PureComponent {
|
||||
@ -26,6 +25,7 @@ class ProfileSearchBar extends React.PureComponent {
|
||||
|
||||
this.updateTimeout = null;
|
||||
this.pendingUpdate = false;
|
||||
this.justShown = false;
|
||||
}
|
||||
|
||||
updateQuery(value) {
|
||||
@ -104,10 +104,15 @@ class ProfileSearchBar extends React.PureComponent {
|
||||
}
|
||||
|
||||
onInputBlur() {
|
||||
// Don't hide immediately after showing to prevent race condition
|
||||
if (this.justShown) {
|
||||
return;
|
||||
}
|
||||
this.hideForm();
|
||||
}
|
||||
|
||||
showForm() {
|
||||
this.justShown = true;
|
||||
this.setState(
|
||||
{
|
||||
visibleForm: true,
|
||||
@ -116,6 +121,10 @@ class ProfileSearchBar extends React.PureComponent {
|
||||
if ('function' === typeof this.props.toggleSearchField) {
|
||||
this.props.toggleSearchField();
|
||||
}
|
||||
// Reset the flag after a short delay
|
||||
setTimeout(() => {
|
||||
this.justShown = false;
|
||||
}, 200);
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -244,12 +253,11 @@ class NavMenuInlineTabs extends React.PureComponent {
|
||||
displayPrev: false,
|
||||
};
|
||||
|
||||
this.inlineSlider = null;
|
||||
|
||||
this.nextSlide = this.nextSlide.bind(this);
|
||||
this.prevSlide = this.prevSlide.bind(this);
|
||||
|
||||
this.updateSlider = this.updateSlider.bind(this, false);
|
||||
this.updateSlider = this.updateSlider.bind(this);
|
||||
this.updateSliderButtonsView = this.updateSliderButtonsView.bind(this);
|
||||
|
||||
this.onToggleSearchField = this.onToggleSearchField.bind(this);
|
||||
|
||||
@ -303,44 +311,57 @@ class NavMenuInlineTabs extends React.PureComponent {
|
||||
|
||||
componentDidMount() {
|
||||
this.updateSlider();
|
||||
if (this.refs.itemsListWrap) {
|
||||
this.refs.itemsListWrap.addEventListener('scroll', this.updateSliderButtonsView.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.refs.itemsListWrap) {
|
||||
this.refs.itemsListWrap.removeEventListener('scroll', this.updateSliderButtonsView.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
nextSlide() {
|
||||
this.inlineSlider.nextSlide();
|
||||
this.updateSliderButtonsView();
|
||||
this.inlineSlider.scrollToCurrentSlide();
|
||||
if (!this.refs.itemsListWrap) return;
|
||||
const scrollAmount = this.refs.itemsListWrap.offsetWidth * 0.7; // Scroll 70% of visible width
|
||||
this.refs.itemsListWrap.scrollLeft += scrollAmount;
|
||||
setTimeout(() => this.updateSliderButtonsView(), 50);
|
||||
}
|
||||
|
||||
prevSlide() {
|
||||
this.inlineSlider.previousSlide();
|
||||
this.updateSliderButtonsView();
|
||||
this.inlineSlider.scrollToCurrentSlide();
|
||||
if (!this.refs.itemsListWrap) return;
|
||||
const scrollAmount = this.refs.itemsListWrap.offsetWidth * 0.7; // Scroll 70% of visible width
|
||||
this.refs.itemsListWrap.scrollLeft -= scrollAmount;
|
||||
setTimeout(() => this.updateSliderButtonsView(), 50);
|
||||
}
|
||||
|
||||
updateSlider(afterItemsUpdate) {
|
||||
if (!this.inlineSlider) {
|
||||
this.inlineSlider = new ItemsInlineSlider(this.refs.itemsListWrap, '.profile-nav ul li');
|
||||
}
|
||||
|
||||
this.inlineSlider.updateDataState(document.querySelectorAll('.profile-nav ul li').length, true, !afterItemsUpdate);
|
||||
|
||||
this.updateSliderButtonsView();
|
||||
|
||||
if (this.pendingChangeSlide) {
|
||||
this.pendingChangeSlide = false;
|
||||
this.inlineSlider.scrollToCurrentSlide();
|
||||
}
|
||||
}
|
||||
|
||||
updateSliderButtonsView() {
|
||||
if (!this.refs.itemsListWrap) return;
|
||||
|
||||
const container = this.refs.itemsListWrap;
|
||||
const scrollLeft = container.scrollLeft;
|
||||
const scrollWidth = container.scrollWidth;
|
||||
const clientWidth = container.clientWidth;
|
||||
|
||||
// Show prev arrow if we can scroll left
|
||||
const canScrollLeft = scrollLeft > 1;
|
||||
|
||||
// Show next arrow if we can scroll right
|
||||
const canScrollRight = scrollLeft < scrollWidth - clientWidth - 1;
|
||||
|
||||
this.setState({
|
||||
displayPrev: this.inlineSlider.hasPreviousSlide(),
|
||||
displayNext: this.inlineSlider.hasNextSlide(),
|
||||
displayPrev: canScrollLeft,
|
||||
displayNext: canScrollRight,
|
||||
});
|
||||
}
|
||||
|
||||
onToggleSearchField() {
|
||||
this.updateSlider();
|
||||
setTimeout(() => this.updateSlider(), 100);
|
||||
}
|
||||
|
||||
render() {
|
||||
@ -404,9 +425,11 @@ class NavMenuInlineTabs extends React.PureComponent {
|
||||
/>
|
||||
) : null}
|
||||
|
||||
{!['about', 'playlists'].includes(this.props.type) ? (
|
||||
<li className="media-search">
|
||||
<ProfileSearchBar onQueryChange={this.props.onQueryChange} toggleSearchField={this.onToggleSearchField} type={this.props.type} />
|
||||
</li>
|
||||
) : null}
|
||||
{this.props.onToggleFiltersClick && ['media', 'shared_by_me', 'shared_with_me'].includes(this.props.type) ? (
|
||||
<li className="media-filters-toggle">
|
||||
<span style={{ display: 'flex', alignItems: 'center', cursor: 'pointer', position: 'relative' }} onClick={this.props.onToggleFiltersClick} title={translateString('Filters')}>
|
||||
|
||||
@ -868,15 +868,6 @@ export class ProfileMediaPage extends Page {
|
||||
const hasActiveTags = this.state.selectedTag && this.state.selectedTag !== 'all';
|
||||
const hasActiveSort = this.state.selectedSort && this.state.selectedSort !== 'date_added_desc';
|
||||
|
||||
console.log('Filter Debug:', {
|
||||
filterArgs: this.state.filterArgs,
|
||||
selectedTag: this.state.selectedTag,
|
||||
selectedSort: this.state.selectedSort,
|
||||
hasActiveFilters,
|
||||
hasActiveTags,
|
||||
hasActiveSort
|
||||
});
|
||||
|
||||
return [
|
||||
this.state.author ? (
|
||||
<ProfilePagesHeader
|
||||
|
||||
1768
frontend/yarn.lock
1768
frontend/yarn.lock
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user