Merge remote-tracking branch 'origin/redux-toolkit-move' into rtm-temp
This commit is contained in:
commit
70293cd8de
11 changed files with 84 additions and 190 deletions
|
|
@ -1,8 +1,7 @@
|
|||
import React, { useMemo, useContext, useState, useRef } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { useStore } from 'App/mstore';
|
||||
import TimeTracker from 'Components/Session_/Player/Controls/TimeTracker';
|
||||
import stl from 'Components/Session_/Player/Controls/timeline.module.css';
|
||||
import { setTimelinePointer, setTimelineHoverTime } from 'Duck/sessions';
|
||||
import DraggableCircle from 'Components/Session_/Player/Controls/components/DraggableCircle';
|
||||
import CustomDragLayer, { OnDragCallback } from 'Components/Session_/Player/Controls/components/CustomDragLayer';
|
||||
import { debounce } from 'App/utils';
|
||||
|
|
@ -11,13 +10,11 @@ import { PlayerContext, ILivePlayerContext } from 'App/components/Session/player
|
|||
import { observer } from 'mobx-react-lite';
|
||||
import { Duration } from 'luxon';
|
||||
|
||||
interface IProps {
|
||||
setTimelineHoverTime: (t: number) => void
|
||||
startedAt: number
|
||||
tooltipVisible: boolean
|
||||
}
|
||||
|
||||
function Timeline(props: IProps) {
|
||||
function Timeline() {
|
||||
const { sessionStore } = useStore();
|
||||
const startedAt = sessionStore.current.startedAt ?? 0;
|
||||
const tooltipVisible = sessionStore.timeLineTooltip.isVisible;
|
||||
const setTimelineHoverTime = sessionStore.setTimelineTooltip;
|
||||
// @ts-ignore
|
||||
const { player, store } = useContext<ILivePlayerContext>(PlayerContext)
|
||||
const [wasPlaying, setWasPlaying] = useState(false)
|
||||
|
|
@ -35,7 +32,7 @@ function Timeline(props: IProps) {
|
|||
const scale = 100 / endTime;
|
||||
|
||||
const debouncedJump = useMemo(() => debounce(player.jump, 500), [])
|
||||
const debouncedTooltipChange = useMemo(() => debounce(props.setTimelineHoverTime, 50), [])
|
||||
const debouncedTooltipChange = useMemo(() => debounce(setTimelineHoverTime, 50), [])
|
||||
|
||||
const onDragEnd = () => {
|
||||
if (!liveTimeTravel) return;
|
||||
|
|
@ -59,7 +56,7 @@ function Timeline(props: IProps) {
|
|||
};
|
||||
|
||||
const getLiveTime = (e: React.MouseEvent) => {
|
||||
const duration = new Date().getTime() - props.startedAt;
|
||||
const duration = new Date().getTime() - startedAt;
|
||||
// @ts-ignore type mismatch from react?
|
||||
const p = e.nativeEvent.offsetX / e.target.offsetWidth;
|
||||
const time = Math.max(Math.round(p * duration), 0);
|
||||
|
|
@ -69,7 +66,7 @@ function Timeline(props: IProps) {
|
|||
|
||||
const showTimeTooltip = (e: React.MouseEvent<HTMLDivElement>) => {
|
||||
if (e.target !== progressRef.current && e.target !== timelineRef.current) {
|
||||
return props.tooltipVisible && hideTimeTooltip();
|
||||
return tooltipVisible && hideTimeTooltip();
|
||||
}
|
||||
|
||||
const [time, duration] = getLiveTime(e);
|
||||
|
|
@ -136,7 +133,7 @@ function Timeline(props: IProps) {
|
|||
onMouseEnter={showTimeTooltip}
|
||||
onMouseLeave={hideTimeTooltip}
|
||||
>
|
||||
<TooltipContainer live />
|
||||
<TooltipContainer />
|
||||
<DraggableCircle
|
||||
left={time * scale}
|
||||
onDrop={onDragEnd}
|
||||
|
|
@ -156,10 +153,4 @@ function Timeline(props: IProps) {
|
|||
)
|
||||
}
|
||||
|
||||
export default connect(
|
||||
(state: any) => ({
|
||||
startedAt: state.getIn(['sessions', 'current']).startedAt || 0,
|
||||
tooltipVisible: state.getIn(['sessions', 'timeLineTooltip', 'isVisible']),
|
||||
}),
|
||||
{ setTimelinePointer, setTimelineHoverTime }
|
||||
)(observer(Timeline))
|
||||
export default observer(Timeline)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import { sessions as sessionsRoute, liveSession as liveSessionRoute, withSiteId } from 'App/routes';
|
||||
import { BackLink, Link } from 'UI';
|
||||
import { toggleFavorite, setSessionPath } from 'Duck/sessions';
|
||||
import { sessions as sessionsRoute, withSiteId } from 'App/routes';
|
||||
import { BackLink } from 'UI';
|
||||
import cn from 'classnames';
|
||||
import SessionMetaList from 'Shared/SessionItem/SessionMetaList';
|
||||
import UserCard from '../ReplayPlayer/EventsBlock/UserCard';
|
||||
|
|
@ -23,10 +22,10 @@ function PlayerBlockHeader(props: any) {
|
|||
|
||||
const playerState = store?.get?.() || { width: 0, height: 0, showEvents: false };
|
||||
const { width = 0, height = 0, showEvents = false } = playerState;
|
||||
const { customFieldStore, projectsStore } = useStore();
|
||||
const { customFieldStore, projectsStore, sessionStore } = useStore();
|
||||
const session = sessionStore.current;
|
||||
const siteId = projectsStore.siteId!;
|
||||
const {
|
||||
session,
|
||||
fullscreen,
|
||||
metaList,
|
||||
setActiveTab,
|
||||
|
|
@ -100,18 +99,12 @@ function PlayerBlockHeader(props: any) {
|
|||
|
||||
const PlayerHeaderCont = connect(
|
||||
(state: any) => {
|
||||
const session = state.getIn(['sessions', 'current']);
|
||||
|
||||
return {
|
||||
session,
|
||||
sessionPath: state.getIn(['sessions', 'sessionPath']),
|
||||
funnelRef: state.getIn(['funnels', 'navRef']),
|
||||
metaList: state.getIn(['customFields', 'list']).map((i: any) => i.key),
|
||||
};
|
||||
},
|
||||
{
|
||||
toggleFavorite,
|
||||
setSessionPath,
|
||||
}
|
||||
)(observer(PlayerBlockHeader));
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { findDOMNode } from 'react-dom';
|
||||
import cn from 'classnames';
|
||||
import { EscapeButton } from 'UI';
|
||||
|
|
@ -18,7 +17,6 @@ import { MobileExceptions } from 'Components/Session_/Exceptions/Exceptions';
|
|||
import MobileControls from './MobileControls';
|
||||
import Overlay from './MobileOverlay'
|
||||
import stl from 'Components/Session_/Player/player.module.css';
|
||||
import { updateLastPlayedSession } from 'Duck/sessions';
|
||||
import { MobileOverviewPanel } from 'Components/Session_/OverviewPanel';
|
||||
import MobileConsolePanel from 'Shared/DevTools/ConsolePanel/MobileConsolePanel';
|
||||
import { MobilePlayerContext } from 'App/components/Session/playerContext';
|
||||
|
|
@ -32,32 +30,28 @@ import { useStore } from 'App/mstore';
|
|||
interface IProps {
|
||||
fullView: boolean;
|
||||
isMultiview?: boolean;
|
||||
nextId: string;
|
||||
sessionId: string;
|
||||
activeTab: string;
|
||||
updateLastPlayedSession: (id: string) => void
|
||||
videoURL: string[];
|
||||
setActiveTab: (tab: string) => void;
|
||||
userDevice: string;
|
||||
screenWidth: number;
|
||||
screenHeight: number;
|
||||
platform: string;
|
||||
bottomBlock: any;
|
||||
fullscreen?: boolean;
|
||||
}
|
||||
|
||||
function Player(props: IProps) {
|
||||
const defaultHeight = getDefaultPanelHeight()
|
||||
const [panelHeight, setPanelHeight] = React.useState(defaultHeight);
|
||||
const {
|
||||
nextId,
|
||||
activeTab,
|
||||
fullView,
|
||||
videoURL,
|
||||
userDevice,
|
||||
screenWidth,
|
||||
screenHeight,
|
||||
platform,
|
||||
} = props;
|
||||
const { uiPlayerStore } = useStore();
|
||||
const { uiPlayerStore, sessionStore } = useStore();
|
||||
const nextId = sessionStore.nextId;
|
||||
const sessionId = sessionStore.current.sessionId;
|
||||
const userDevice = sessionStore.current.userDevice;
|
||||
const videoURL = sessionStore.current.videoURL;
|
||||
const platform = sessionStore.current.platform;
|
||||
const screenWidth = sessionStore.current.screenWidth!;
|
||||
const screenHeight = sessionStore.current.screenHeight!;
|
||||
const updateLastPlayedSession = sessionStore.updateLastPlayedSession;
|
||||
const fullscreenOff = uiPlayerStore.fullscreenOff;
|
||||
const fullscreen = uiPlayerStore.fullscreen;
|
||||
const bottomBlock = uiPlayerStore.bottomBlock;
|
||||
|
|
@ -68,7 +62,7 @@ function Player(props: IProps) {
|
|||
const [isAttached, setAttached] = React.useState(false);
|
||||
|
||||
React.useEffect(() => {
|
||||
props.updateLastPlayedSession(props.sessionId);
|
||||
updateLastPlayedSession(sessionId);
|
||||
const parentElement = findDOMNode(screenWrapper.current) as HTMLDivElement | null; //TODO: good architecture
|
||||
if (parentElement && !isAttached) {
|
||||
playerContext.player.attach(parentElement);
|
||||
|
|
@ -166,17 +160,4 @@ function Player(props: IProps) {
|
|||
);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
(state: any) => ({
|
||||
nextId: state.getIn(['sessions', 'nextId']),
|
||||
sessionId: state.getIn(['sessions', 'current']).sessionId,
|
||||
userDevice: state.getIn(['sessions', 'current']).userDevice,
|
||||
videoURL: state.getIn(['sessions', 'current']).videoURL,
|
||||
platform: state.getIn(['sessions', 'current']).platform,
|
||||
screenWidth: state.getIn(['sessions', 'current']).screenWidth,
|
||||
screenHeight: state.getIn(['sessions', 'current']).screenHeight,
|
||||
}),
|
||||
{
|
||||
updateLastPlayedSession,
|
||||
}
|
||||
)(observer(Player));
|
||||
export default observer(Player);
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import {
|
|||
withSiteId,
|
||||
} from 'App/routes';
|
||||
import { BackLink, Link } from 'UI';
|
||||
import { toggleFavorite, setSessionPath } from 'Duck/sessions';
|
||||
import cn from 'classnames';
|
||||
import SessionMetaList from 'Shared/SessionItem/SessionMetaList';
|
||||
import UserCard from './EventsBlock/UserCard';
|
||||
|
|
@ -20,24 +19,23 @@ import { IFRAME } from 'App/constants/storageKeys';
|
|||
|
||||
const SESSIONS_ROUTE = sessionsRoute();
|
||||
|
||||
// TODO props
|
||||
function PlayerBlockHeader(props: any) {
|
||||
const [hideBack, setHideBack] = React.useState(false);
|
||||
const { player, store } = React.useContext(PlayerContext);
|
||||
const { uxtestingStore, customFieldStore, projectsStore } = useStore()
|
||||
const { uxtestingStore, customFieldStore, projectsStore, sessionStore } = useStore()
|
||||
const session = sessionStore.current;
|
||||
const sessionPath = sessionStore.sessionPath;
|
||||
const siteId = projectsStore.siteId!;
|
||||
const playerState = store?.get?.() || { width: 0, height: 0, showEvents: false }
|
||||
const { width = 0, height = 0, showEvents = false } = playerState
|
||||
|
||||
const {
|
||||
session,
|
||||
fullscreen,
|
||||
metaList,
|
||||
closedLive = false,
|
||||
setActiveTab,
|
||||
activeTab,
|
||||
history,
|
||||
sessionPath,
|
||||
} = props;
|
||||
|
||||
React.useEffect(() => {
|
||||
|
|
@ -130,19 +128,12 @@ function PlayerBlockHeader(props: any) {
|
|||
|
||||
const PlayerHeaderCont = connect(
|
||||
(state: any) => {
|
||||
const session = state.getIn(['sessions', 'current']);
|
||||
|
||||
return {
|
||||
session,
|
||||
sessionPath: state.getIn(['sessions', 'sessionPath']),
|
||||
funnelRef: state.getIn(['funnels', 'navRef']),
|
||||
metaList: state.getIn(['customFields', 'list']).map((i: any) => i.key),
|
||||
};
|
||||
},
|
||||
{
|
||||
toggleFavorite,
|
||||
setSessionPath,
|
||||
}
|
||||
)(observer(PlayerBlockHeader));
|
||||
|
||||
export default withRouter(PlayerHeaderCont);
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import { VList, VListHandle } from 'virtua';
|
|||
import { PlayerContext } from 'App/components/Session/playerContext';
|
||||
import { RootStore } from 'App/duck';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { filterOutNote, setEventFilter } from 'Duck/sessions';
|
||||
import { Icon } from 'UI';
|
||||
|
||||
import EventGroupWrapper from './EventGroupWrapper';
|
||||
|
|
@ -18,19 +17,19 @@ import EventSearch from './EventSearch/EventSearch';
|
|||
import styles from './eventsBlock.module.css';
|
||||
|
||||
interface IProps {
|
||||
setEventFilter: (filter: { query: string }) => void;
|
||||
filteredEvents: InjectedEvent[];
|
||||
setActiveTab: (tab?: string) => void;
|
||||
query: string;
|
||||
events: Session['events'];
|
||||
notesWithEvents: Session['notesWithEvents'];
|
||||
filterOutNote: (id: string) => void;
|
||||
eventsIndex: number[];
|
||||
uxtVideo: string;
|
||||
}
|
||||
|
||||
function EventsBlock(props: IProps) {
|
||||
const { notesStore, uxtestingStore, uiPlayerStore } = useStore();
|
||||
const { notesStore, uxtestingStore, uiPlayerStore, sessionStore } = useStore();
|
||||
const session = sessionStore.current;
|
||||
const notesWithEvents = session.notesWithEvents;
|
||||
const uxtVideo = session.uxtVideo;
|
||||
const filteredEvents = sessionStore.filteredEvents;
|
||||
const query = sessionStore.eventsQuery;
|
||||
const eventsIndex = sessionStore.eventsIndex;
|
||||
const setEventFilter = sessionStore.setEventQuery;
|
||||
const filterOutNote = sessionStore.filterOutNote;
|
||||
const [mouseOver, setMouseOver] = React.useState(false);
|
||||
const scroller = React.useRef<VListHandle>(null);
|
||||
const zoomEnabled = uiPlayerStore.timelineZoom.enabled;
|
||||
|
|
@ -47,12 +46,7 @@ function EventsBlock(props: IProps) {
|
|||
} = store.get();
|
||||
|
||||
const {
|
||||
filteredEvents,
|
||||
eventsIndex,
|
||||
filterOutNote,
|
||||
query,
|
||||
setActiveTab,
|
||||
notesWithEvents = [],
|
||||
} = props;
|
||||
const notes = notesStore.sessionNotes;
|
||||
|
||||
|
|
@ -129,7 +123,7 @@ function EventsBlock(props: IProps) {
|
|||
const write = ({
|
||||
target: { value },
|
||||
}: React.ChangeEvent<HTMLInputElement>) => {
|
||||
props.setEventFilter({ query: value });
|
||||
setEventFilter({ query: value });
|
||||
|
||||
setTimeout(() => {
|
||||
if (!scroller.current) return;
|
||||
|
|
@ -139,7 +133,7 @@ function EventsBlock(props: IProps) {
|
|||
};
|
||||
|
||||
const clearSearch = () => {
|
||||
props.setEventFilter({ query: '' });
|
||||
setEventFilter({ query: '' });
|
||||
|
||||
setTimeout(() => {
|
||||
if (!scroller.current) return;
|
||||
|
|
@ -163,7 +157,7 @@ function EventsBlock(props: IProps) {
|
|||
|
||||
const onEventClick = (_: React.MouseEvent, event: { time: number }) => {
|
||||
player.jump(event.time);
|
||||
props.setEventFilter({ query: '' });
|
||||
setEventFilter({ query: '' });
|
||||
};
|
||||
const onMouseOver = () => setMouseOver(true);
|
||||
const onMouseLeave = () => setMouseOver(false);
|
||||
|
|
@ -213,7 +207,7 @@ function EventsBlock(props: IProps) {
|
|||
muted
|
||||
autoPlay
|
||||
controls
|
||||
src={props.uxtVideo}
|
||||
src={uxtVideo}
|
||||
width={240}
|
||||
/>
|
||||
<div
|
||||
|
|
@ -265,18 +259,4 @@ function EventsBlock(props: IProps) {
|
|||
);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
(state: RootStore) => ({
|
||||
session: state.getIn(['sessions', 'current']),
|
||||
notesWithEvents: state.getIn(['sessions', 'current']).notesWithEvents,
|
||||
events: state.getIn(['sessions', 'current']).events,
|
||||
uxtVideo: state.getIn(['sessions', 'current']).uxtVideo,
|
||||
filteredEvents: state.getIn(['sessions', 'filteredEvents']),
|
||||
query: state.getIn(['sessions', 'eventsQuery']),
|
||||
eventsIndex: state.getIn(['sessions', 'eventsIndex']),
|
||||
}),
|
||||
{
|
||||
setEventFilter,
|
||||
filterOutNote,
|
||||
}
|
||||
)(observer(EventsBlock));
|
||||
export default observer(EventsBlock);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
import DraggableMarkers from 'Components/Session_/Player/Controls/components/ZoomDragLayer';
|
||||
import React, { useEffect, useMemo, useContext, useState, useRef } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import stl from './timeline.module.css';
|
||||
import { setTimelinePointer, setTimelineHoverTime } from 'Duck/sessions';
|
||||
import CustomDragLayer, { OnDragCallback } from './components/CustomDragLayer';
|
||||
import { debounce } from 'App/utils';
|
||||
import TooltipContainer from './components/TooltipContainer';
|
||||
|
|
@ -10,18 +8,12 @@ import { PlayerContext } from 'App/components/Session/playerContext';
|
|||
import { observer } from 'mobx-react-lite';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { DateTime, Duration } from 'luxon';
|
||||
import Issue from 'Types/session/issue';
|
||||
import { WebEventsList, MobEventsList } from './EventsList';
|
||||
import NotesList from './NotesList';
|
||||
import SkipIntervalsList from './SkipIntervalsList';
|
||||
import TimelineTracker from 'Components/Session_/Player/Controls/TimelineTracker';
|
||||
|
||||
interface IProps {
|
||||
issues: Issue[];
|
||||
setTimelineHoverTime: (t: number) => void;
|
||||
startedAt: number;
|
||||
tooltipVisible: boolean;
|
||||
timezone?: string;
|
||||
isMobile?: boolean;
|
||||
}
|
||||
|
||||
|
|
@ -29,10 +21,14 @@ function Timeline(props: IProps) {
|
|||
const { player, store } = useContext(PlayerContext);
|
||||
const [wasPlaying, setWasPlaying] = useState(false);
|
||||
const [maxWidth, setMaxWidth] = useState(0);
|
||||
const { settingsStore, uiPlayerStore } = useStore();
|
||||
const { settingsStore, uiPlayerStore, sessionStore } = useStore();
|
||||
const startedAt = sessionStore.current.startedAt ?? 0;
|
||||
const tooltipVisible = sessionStore.timeLineTooltip.isVisible;
|
||||
const setTimelineHoverTime = sessionStore.setTimelineTooltip;
|
||||
const timezone = sessionStore.current.timezone;
|
||||
const issues = sessionStore.current.issues;
|
||||
const timelineZoomEnabled = uiPlayerStore.timelineZoom.enabled;
|
||||
const { playing, skipToIssue, ready, endTime, devtoolsLoading, domLoading } = store.get();
|
||||
const { issues, timezone } = props;
|
||||
|
||||
const progressRef = useRef<HTMLDivElement>(null);
|
||||
const timelineRef = useRef<HTMLDivElement>(null);
|
||||
|
|
@ -51,7 +47,7 @@ function Timeline(props: IProps) {
|
|||
}, []);
|
||||
|
||||
const debouncedJump = useMemo(() => debounce(player.jump, 500), []);
|
||||
const debouncedTooltipChange = useMemo(() => debounce(props.setTimelineHoverTime, 50), []);
|
||||
const debouncedTooltipChange = useMemo(() => debounce(setTimelineHoverTime, 50), []);
|
||||
|
||||
const onDragEnd = () => {
|
||||
if (wasPlaying) {
|
||||
|
|
@ -78,17 +74,17 @@ function Timeline(props: IProps) {
|
|||
// @ts-ignore black magic
|
||||
!progressRef.current.contains(e.target)
|
||||
) {
|
||||
return props.tooltipVisible && hideTimeTooltip();
|
||||
return tooltipVisible && hideTimeTooltip();
|
||||
}
|
||||
|
||||
const time = getTime(e);
|
||||
if (!time) return;
|
||||
const tz = settingsStore.sessionSettings.timezone.value;
|
||||
const timeStr = DateTime.fromMillis(props.startedAt + time)
|
||||
const timeStr = DateTime.fromMillis(startedAt + time)
|
||||
.setZone(tz)
|
||||
.toFormat(`hh:mm:ss a`);
|
||||
const userTimeStr = timezone
|
||||
? DateTime.fromMillis(props.startedAt + time)
|
||||
? DateTime.fromMillis(startedAt + time)
|
||||
.setZone(timezone)
|
||||
.toFormat(`hh:mm:ss a`)
|
||||
: undefined;
|
||||
|
|
@ -177,12 +173,4 @@ function Timeline(props: IProps) {
|
|||
);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
(state: any) => ({
|
||||
issues: state.getIn(['sessions', 'current']).issues || [],
|
||||
startedAt: state.getIn(['sessions', 'current']).startedAt || 0,
|
||||
timezone: state.getIn(['sessions', 'current']).timezone,
|
||||
tooltipVisible: state.getIn(['sessions', 'timeLineTooltip', 'isVisible']),
|
||||
}),
|
||||
{ setTimelinePointer, setTimelineHoverTime }
|
||||
)(observer(Timeline));
|
||||
export default observer(Timeline);
|
||||
|
|
|
|||
|
|
@ -12,16 +12,13 @@ import {
|
|||
iTag,
|
||||
tagProps,
|
||||
} from 'App/services/NotesService';
|
||||
import { addNote, updateNote } from 'Duck/sessions';
|
||||
import { Button, Checkbox, Icon } from 'UI';
|
||||
|
||||
import Select from 'Shared/Select';
|
||||
|
||||
interface Props {
|
||||
time: number;
|
||||
addNote: (note: Note) => void;
|
||||
updateNote: (note: Note) => void;
|
||||
sessionId: string;
|
||||
isEdit?: boolean;
|
||||
editNote?: WriteNote;
|
||||
hideModal: () => void;
|
||||
|
|
@ -29,13 +26,13 @@ interface Props {
|
|||
|
||||
function CreateNote({
|
||||
time,
|
||||
sessionId,
|
||||
isEdit,
|
||||
editNote,
|
||||
updateNote,
|
||||
hideModal,
|
||||
}: Props) {
|
||||
const { notesStore, integrationsStore } = useStore();
|
||||
const { notesStore, integrationsStore, sessionStore } = useStore();
|
||||
const sessionId = sessionStore.current.sessionId;
|
||||
const updateNote = sessionStore.updateNote;
|
||||
const slackChannels = integrationsStore.slack.list;
|
||||
const fetchSlack = integrationsStore.slack.fetchIntegrations;
|
||||
const teamsChannels = integrationsStore.msteams.list;
|
||||
|
|
@ -323,10 +320,4 @@ function CreateNote({
|
|||
);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
(state: any) => {
|
||||
const sessionId = state.getIn(['sessions', 'current']).sessionId;
|
||||
return { sessionId };
|
||||
},
|
||||
{ addNote, updateNote,}
|
||||
)(observer(CreateNote));
|
||||
export default observer(CreateNote);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { setAutoplayValues } from 'Duck/sessions';
|
||||
import { withSiteId, session as sessionRoute } from 'App/routes';
|
||||
import AutoplayToggle from 'Shared/AutoplayToggle/AutoplayToggle';
|
||||
import { withRouter, RouteComponentProps } from 'react-router-dom';
|
||||
|
|
@ -12,24 +11,21 @@ import { useStore } from 'App/mstore';
|
|||
const PER_PAGE = 10;
|
||||
|
||||
interface Props extends RouteComponentProps {
|
||||
previousId: string;
|
||||
nextId: string;
|
||||
defaultList: any;
|
||||
currentPage: number;
|
||||
total: number;
|
||||
setAutoplayValues: () => void;
|
||||
latestRequestTime: any;
|
||||
sessionIds: any;
|
||||
}
|
||||
|
||||
function QueueControls(props: Props) {
|
||||
const { projectsStore } = useStore();
|
||||
const { projectsStore, sessionStore, searchStore } = useStore();
|
||||
const previousId = sessionStore.previousId;
|
||||
const nextId = sessionStore.nextId;
|
||||
const total = sessionStore.total;
|
||||
const sessionIds = sessionStore.sessionIds ?? [];
|
||||
const setAutoplayValues = sessionStore.setAutoplayValues;
|
||||
const {
|
||||
previousId,
|
||||
nextId,
|
||||
currentPage,
|
||||
total,
|
||||
sessionIds,
|
||||
latestRequestTime,
|
||||
match: {
|
||||
// @ts-ignore
|
||||
|
|
@ -37,19 +33,15 @@ function QueueControls(props: Props) {
|
|||
}
|
||||
} = props;
|
||||
|
||||
const { searchStore } = useStore();
|
||||
|
||||
const disabled = sessionIds.length === 0;
|
||||
|
||||
useEffect(() => {
|
||||
if (latestRequestTime) {
|
||||
props.setAutoplayValues();
|
||||
setAutoplayValues();
|
||||
const totalPages = Math.ceil(total / PER_PAGE);
|
||||
const index = sessionIds.indexOf(sessionId);
|
||||
|
||||
// check for the last page and load the next
|
||||
if (currentPage !== totalPages && index === sessionIds.length - 1) {
|
||||
searchStore.fetchAutoplaySessions(currentPage + 1).then(props.setAutoplayValues);
|
||||
searchStore.fetchAutoplaySessions(currentPage + 1).then(setAutoplayValues);
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
|
@ -107,12 +99,7 @@ function QueueControls(props: Props) {
|
|||
|
||||
export default connect(
|
||||
(state: any) => ({
|
||||
previousId: state.getIn(['sessions', 'previousId']),
|
||||
nextId: state.getIn(['sessions', 'nextId']),
|
||||
currentPage: state.getIn(['search', 'currentPage']) || 1,
|
||||
total: state.getIn(['sessions', 'total']) || 0,
|
||||
sessionIds: state.getIn(['sessions', 'sessionIds']) || [],
|
||||
latestRequestTime: state.getIn(['search', 'latestRequestTime'])
|
||||
}),
|
||||
{ setAutoplayValues }
|
||||
)(withRouter(QueueControls));
|
||||
|
|
|
|||
|
|
@ -3,20 +3,21 @@ import { BookmarkCheck, Bookmark as BookmarkIcn, Vault } from 'lucide-react';
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
import { toggleFavorite } from 'Duck/sessions';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
|
||||
interface Props {
|
||||
toggleFavorite: (sessionId: string) => Promise<void>;
|
||||
favorite: boolean;
|
||||
sessionId: any;
|
||||
isEnterprise: boolean;
|
||||
noMargin?: boolean;
|
||||
}
|
||||
|
||||
function Bookmark(props: Props) {
|
||||
const { sessionId, favorite, isEnterprise, noMargin } = props;
|
||||
const { sessionStore } = useStore();
|
||||
const favorite = sessionStore.current.favorite;
|
||||
const onToggleFavorite = sessionStore.toggleFavorite;
|
||||
const { sessionId, isEnterprise } = props;
|
||||
const [isFavorite, setIsFavorite] = useState(favorite);
|
||||
|
||||
const ADDED_MESSAGE = isEnterprise
|
||||
? 'Session added to vault'
|
||||
: 'Session added to your bookmarks';
|
||||
|
|
@ -33,7 +34,7 @@ function Bookmark(props: Props) {
|
|||
}, [favorite]);
|
||||
|
||||
const toggleFavorite = async () => {
|
||||
props.toggleFavorite(sessionId).then(() => {
|
||||
onToggleFavorite(sessionId).then(() => {
|
||||
toast.success(isFavorite ? REMOVED_MESSAGE : ADDED_MESSAGE);
|
||||
setIsFavorite(!isFavorite);
|
||||
});
|
||||
|
|
@ -65,8 +66,6 @@ function Bookmark(props: Props) {
|
|||
|
||||
export default connect(
|
||||
(state: any) => ({
|
||||
isEnterprise: state.getIn(['user', 'account', 'edition']) === 'ee',
|
||||
favorite: state.getIn(['sessions', 'current']).favorite,
|
||||
}),
|
||||
{ toggleFavorite }
|
||||
)(Bookmark);
|
||||
isEnterprise: state.getIn(['user', 'account', 'edition']) === 'ee',
|
||||
}),
|
||||
)(observer(Bookmark));
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ export default class SessionStore {
|
|||
visitedEvents: Location[] = [];
|
||||
insights: any[] = [];
|
||||
host = '';
|
||||
sessionPath = {};
|
||||
sessionPath: Record<string, any> = {};
|
||||
lastPlayedSessionId: string = '';
|
||||
timeLineTooltip = {
|
||||
time: 0,
|
||||
|
|
@ -421,16 +421,6 @@ export default class SessionStore {
|
|||
});
|
||||
}
|
||||
|
||||
// Add Note
|
||||
addNote(note: Note) {
|
||||
this.current.notesWithEvents.push(note);
|
||||
this.current.notesWithEvents.sort((a, b) => {
|
||||
const aTs = a.time || a.timestamp;
|
||||
const bTs = b.time || b.timestamp;
|
||||
return aTs - bTs;
|
||||
});
|
||||
}
|
||||
|
||||
// Update Note
|
||||
updateNote(note: Note) {
|
||||
const noteIndex = this.current.notesWithEvents.findIndex((item) => {
|
||||
|
|
@ -450,7 +440,6 @@ export default class SessionStore {
|
|||
this.sessionPath = path;
|
||||
}
|
||||
|
||||
// Update Last Played Session
|
||||
updateLastPlayedSession(sessionId: string) {
|
||||
const sIndex = this.list.findIndex((s) => s.sessionId === sessionId);
|
||||
if (sIndex !== -1) {
|
||||
|
|
|
|||
|
|
@ -174,6 +174,7 @@ export default class Session {
|
|||
duration: Duration;
|
||||
durationMs: ISession['durationMs'];
|
||||
events: ISession['events'];
|
||||
uxtVideo?: any;
|
||||
stackEvents: ISession['stackEvents'];
|
||||
metadata: ISession['metadata'];
|
||||
favorite: ISession['favorite'];
|
||||
|
|
@ -228,6 +229,9 @@ export default class Session {
|
|||
fileKey: ISession['fileKey'];
|
||||
durationSeconds: number;
|
||||
liveOnly: boolean;
|
||||
videoURL: string[]
|
||||
screenWidth?: number
|
||||
screenHeight?: number
|
||||
|
||||
constructor(plainSession?: ISession) {
|
||||
const sessionData = plainSession || (emptyValues as unknown as ISession);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue