import React, { useRef, useState, useEffect } from 'react'; import PropTypes from 'prop-types'; import { usePopup } from '../../utils/hooks/'; 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 { constructor(props) { super(props); this.state = { visibleForm: false, queryVal: ProfilePageStore.get('author-query') || '', }; this.onChange = this.onChange.bind(this); this.onInputFocus = this.onInputFocus.bind(this); this.onInputBlur = this.onInputBlur.bind(this); this.showForm = this.showForm.bind(this); this.hideForm = this.hideForm.bind(this); this.onFormSubmit = this.onFormSubmit.bind(this); this.updateTimeout = null; this.pendingUpdate = false; } updateQuery(value) { this.pendingUpdateValue = null; this.setState( { queryVal: value, }, function () { if ('function' === typeof this.props.onQueryChange) { this.props.onQueryChange(this.state.queryVal); } } ); } onChange(ev) { this.pendingEvent = ev; const newValue = ev.target.value || ''; this.setState( { queryVal: newValue, }, function () { if (this.updateTimeout) { return; } this.pendingEvent = null; // Only trigger search if 3+ characters or empty (to reset) if ('function' === typeof this.props.onQueryChange) { if (newValue.length >= 3 || newValue.length === 0) { this.props.onQueryChange(newValue); } } this.updateTimeout = setTimeout( function () { this.updateTimeout = null; if (this.pendingEvent) { this.onChange(this.pendingEvent); } }.bind(this), 100 ); } ); } /*onKeydown(e){ let found = false, key = e.keyCode || e.charCode; switch( key ){ case 38: // Arrow Up. found = this.getItemsArr(this.state.predictionItems.length-1); break; case 40: // Arrow Down. found = this.getItemsArr(0); break; } if( found ){ found.focus(); e.preventDefault(); e.stopPropagation(); } }*/ onInputFocus() { // console.log('FOCUS'); /*if( this.state.predictionItems.length ){ this.refs.SearchInput.onkeydown = this.refs.SearchInput.onkeydown || this.onKeydown; }*/ } onInputBlur() { this.hideForm(); } showForm() { this.setState( { visibleForm: true, }, function () { if ('function' === typeof this.props.toggleSearchField) { this.props.toggleSearchField(); } } ); } hideForm() { this.setState( { visibleForm: false, }, function () { if ('function' === typeof this.props.toggleSearchField) { this.props.toggleSearchField(); } } ); } onFormSubmit(ev) { if ('' === this.refs.SearchInput.value.trim()) { ev.preventDefault(); ev.stopPropagation(); } } render() { const hasSearchText = this.state.queryVal && this.state.queryVal.length > 0; // Determine the correct action URL based on page type let actionUrl = LinksContext._currentValue.profile.media; if (this.props.type === 'shared_by_me') { actionUrl = LinksContext._currentValue.profile.shared_by_me; } else if (this.props.type === 'shared_with_me') { actionUrl = LinksContext._currentValue.profile.shared_with_me; } if (!this.state.visibleForm) { return ( search {hasSearchText ? ( ) : null} ); } return (
search {hasSearchText ? ( ) : null}
); } } ProfileSearchBar.propTypes = { onQueryChange: PropTypes.func, type: PropTypes.string, }; ProfileSearchBar.defaultProps = {}; function InlineTab(props) { return (
  • {props.label}
  • ); } InlineTab.propTypes = { id: PropTypes.string.isRequired, label: PropTypes.string.isRequired, link: PropTypes.string.isRequired, isActive: PropTypes.bool.isRequired, }; class NavMenuInlineTabs extends React.PureComponent { constructor(props) { super(props); this.state = { displayNext: false, 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.onToggleSearchField = this.onToggleSearchField.bind(this); PageStore.on('window_resize', this.updateSlider); this.sliderRecalTimeout = null; PageStore.on( 'changed_page_sidebar_visibility', function () { clearTimeout(this.sliderRecalTimeout); // NOTE: 200ms is transition duration, set in CSS. this.sliderRecalTimeout = setTimeout( function () { this.updateSliderButtonsView(); this.sliderRecalTimeout = setTimeout( function () { this.sliderRecalTimeout = null; this.updateSlider(); }.bind(this), 50 ); }.bind(this), 150 ); }.bind(this) ); this.previousBtn = ( keyboard_arrow_left ); this.nextBtn = ( keyboard_arrow_right ); this.userIsAuthor = !MemberContext._currentValue.is.anonymous && ProfilePageStore.get('author-data').username === MemberContext._currentValue.username; } componentDidMount() { this.updateSlider(); } nextSlide() { this.inlineSlider.nextSlide(); this.updateSliderButtonsView(); this.inlineSlider.scrollToCurrentSlide(); } prevSlide() { this.inlineSlider.previousSlide(); this.updateSliderButtonsView(); this.inlineSlider.scrollToCurrentSlide(); } 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() { this.setState({ displayPrev: this.inlineSlider.hasPreviousSlide(), displayNext: this.inlineSlider.hasNextSlide(), }); } onToggleSearchField() { this.updateSlider(); } render() { return ( ); } } NavMenuInlineTabs.propTypes = { type: PropTypes.string.isRequired, onQueryChange: PropTypes.func, onToggleFiltersClick: PropTypes.func, onToggleTagsClick: PropTypes.func, onToggleSortingClick: PropTypes.func, hasActiveFilters: PropTypes.bool, hasActiveTags: PropTypes.bool, hasActiveSort: PropTypes.bool, }; function AddBannerButton(props) { let link = props.link; if (window.MediaCMS.site.devEnv) { link = '/edit-channel.html'; } return ( add_photo_alternate ); } function EditBannerButton(props) { let link = props.link; if (window.MediaCMS.site.devEnv) { link = '/edit-channel.html'; } return ( edit ); } function EditProfileButton(props) { let link = props.link; if (window.MediaCMS.site.devEnv) { link = '/edit-profile.html'; } return ( edit ); } export default function ProfilePagesHeader(props) { const [popupContentRef, PopupContent, PopupTrigger] = usePopup(); const profilePageHeaderRef = useRef(null); const profileNavRef = useRef(null); const [fixedNav, setFixedNav] = useState(false); const positions = { profileNavTop: 0, }; const userIsAdmin = !MemberContext._currentValue.is.anonymous && MemberContext._currentValue.is.admin; const userIsAuthor = !MemberContext._currentValue.is.anonymous && ProfilePageStore.get('author-data').username === MemberContext._currentValue.username; const userCanEditProfile = userIsAuthor || (!MemberContext._currentValue.is.anonymous && MemberContext._currentValue.can.editProfile); const userCanDeleteProfile = userIsAdmin || userIsAuthor || (!MemberContext._currentValue.is.anonymous && MemberContext._currentValue.can.deleteProfile); function updateProfileNavTopPosition() { positions.profileHeaderTop = profilePageHeaderRef.current.offsetTop; positions.profileNavTop = positions.profileHeaderTop + profilePageHeaderRef.current.offsetHeight - profileNavRef.current.refs.tabsNav.offsetHeight; } function updateFixedNavPosition() { setFixedNav(positions.profileHeaderTop + window.scrollY > positions.profileNavTop); } function cancelProfileRemoval() { popupContentRef.current.toggle(); } function proceedMediaRemoval() { ProfilePageActions.remove_profile(); popupContentRef.current.toggle(); } function onProfileDelete(username) { // FIXME: Without delay creates conflict [ Uncaught Error: Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch. ]. setTimeout(function () { PageActions.addNotification('Profile removed. Redirecting...', 'profileDelete'); setTimeout(function () { window.location.href = SiteContext._currentValue.url; }, 2000); }, 100); if (void 0 !== username) { console.info("Removed user's profile '" + username + '"'); } } function onProfileDeleteFail(username) { // FIXME: Without delay creates conflict [ Uncaught Error: Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch. ]. setTimeout(function () { PageActions.addNotification('Profile removal failed', 'profileDeleteFail'); }, 100); if (void 0 !== username) { console.info('Profile "' + username + '"' + ' removal failed'); } } function onWindowResize() { updateProfileNavTopPosition(); updateFixedNavPosition(); } function onWindowScroll() { updateFixedNavPosition(); } useEffect(() => { if (userCanDeleteProfile) { ProfilePageStore.on('profile_delete', onProfileDelete); ProfilePageStore.on('profile_delete_fail', onProfileDeleteFail); } PageStore.on('resize', onWindowResize); PageStore.on('changed_page_sidebar_visibility', onWindowResize); PageStore.on('window_scroll', onWindowScroll); updateProfileNavTopPosition(); updateFixedNavPosition(); return () => { if (userCanDeleteProfile) { ProfilePageStore.removeListener('profile_delete', onProfileDelete); ProfilePageStore.removeListener('profile_delete_fail', onProfileDeleteFail); } PageStore.removeListener('resize', onWindowResize); PageStore.removeListener('changed_page_sidebar_visibility', onWindowResize); PageStore.removeListener('window_scroll', onWindowScroll); }; }, []); return (
    {props.author.banner_thumbnail_url ? ( ) : null} {userCanDeleteProfile && !userIsAuthor ? (
    Profile removal You're willing to remove profile permanently?

    ) : null} {userCanEditProfile && userIsAuthor ? ( props.author.banner_thumbnail_url ? ( ) : ( ) ) : null}
    {props.author.thumbnail_url || props.author.name ? (
    {props.author.thumbnail_url ? : null}
    {props.author.name ? (

    {props.author.name}

    {userCanEditProfile && !userIsAuthor ? : null}
    ) : null}
    ) : null}
    ); } ProfilePagesHeader.propTypes = { author: PropTypes.object.isRequired, type: PropTypes.string.isRequired, onQueryChange: PropTypes.func, onToggleFiltersClick: PropTypes.func, onToggleTagsClick: PropTypes.func, onToggleSortingClick: PropTypes.func, hasActiveFilters: PropTypes.bool, hasActiveTags: PropTypes.bool, hasActiveSort: PropTypes.bool, }; ProfilePagesHeader.defaultProps = { type: 'media', };