[Log] IF-LGSP-LOG-100, 추가 시나리오 반영 (RandomUnit.jsx, RollingUnit.jsx)
This commit is contained in:
@@ -1113,9 +1113,9 @@ export const sendLogTopContents = (params) => (dispatch, getState) => {
|
||||
const { entryMenu, nowMenu } = getState().common.menu;
|
||||
const newParams = {
|
||||
...params,
|
||||
entryMenu: entryMenu,
|
||||
entryMenu: params?.entryMenu ?? entryMenu,
|
||||
outDt: formatGMTString(new Date()),
|
||||
nowMenu: nowMenu,
|
||||
nowMenu: params?.nowMenu ?? nowMenu,
|
||||
};
|
||||
|
||||
dispatch(postLog(newParams));
|
||||
|
||||
@@ -4,47 +4,32 @@ import React, {
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
} from "react";
|
||||
|
||||
import classNames from 'classnames';
|
||||
import {
|
||||
useDispatch,
|
||||
useSelector,
|
||||
} from 'react-redux';
|
||||
import classNames from "classnames";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
|
||||
import SpotlightContainerDecorator
|
||||
from '@enact/spotlight/SpotlightContainerDecorator';
|
||||
import Spottable from '@enact/spotlight/Spottable';
|
||||
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||
import Spottable from "@enact/spotlight/Spottable";
|
||||
|
||||
import btnPlay from '../../../../assets/images/btn/btn-play-thumb-nor.png';
|
||||
import defaultLogoImg
|
||||
from '../../../../assets/images/ic-tab-partners-default@3x.png';
|
||||
import emptyHorImage
|
||||
from '../../../../assets/images/img-home-banner-empty-hor.png';
|
||||
import emptyVerImage
|
||||
from '../../../../assets/images/img-home-banner-empty-ver.png';
|
||||
import defaultImageItem
|
||||
from '../../../../assets/images/img-thumb-empty-product@3x.png';
|
||||
import liveShow from '../../../../assets/images/tag-liveshow.png';
|
||||
import { sendLogTopContents } from '../../../actions/logActions';
|
||||
import btnPlay from "../../../../assets/images/btn/btn-play-thumb-nor.png";
|
||||
import defaultLogoImg from "../../../../assets/images/ic-tab-partners-default@3x.png";
|
||||
import emptyHorImage from "../../../../assets/images/img-home-banner-empty-hor.png";
|
||||
import emptyVerImage from "../../../../assets/images/img-home-banner-empty-ver.png";
|
||||
import defaultImageItem from "../../../../assets/images/img-thumb-empty-product@3x.png";
|
||||
import liveShow from "../../../../assets/images/tag-liveshow.png";
|
||||
import { sendLogTopContents } from "../../../actions/logActions";
|
||||
//import { sendBroadCast } from "../../../actions/commonActions";
|
||||
import { pushPanel } from '../../../actions/panelActions';
|
||||
import { pushPanel } from "../../../actions/panelActions";
|
||||
import {
|
||||
finishVideoPreview,
|
||||
startVideoPlayer,
|
||||
} from '../../../actions/playActions';
|
||||
import CustomImage from '../../../components/CustomImage/CustomImage';
|
||||
import usePriceInfo from '../../../hooks/usePriceInfo';
|
||||
import {
|
||||
LOG_MENU,
|
||||
LOG_TP_NO,
|
||||
panel_names,
|
||||
} from '../../../utils/Config';
|
||||
import {
|
||||
$L,
|
||||
formatGMTString,
|
||||
} from '../../../utils/helperMethods';
|
||||
import css from './RandomUnit.module.less';
|
||||
} from "../../../actions/playActions";
|
||||
import CustomImage from "../../../components/CustomImage/CustomImage";
|
||||
import usePriceInfo from "../../../hooks/usePriceInfo";
|
||||
import { LOG_MENU, LOG_TP_NO, panel_names } from "../../../utils/Config";
|
||||
import { $L, formatGMTString } from "../../../utils/helperMethods";
|
||||
import css from "./RandomUnit.module.less";
|
||||
|
||||
const SpottableComponent = Spottable("div");
|
||||
|
||||
@@ -70,24 +55,50 @@ export default function RandomUnit({
|
||||
(state) => state.home?.bannerData?.shptmTmplCd
|
||||
);
|
||||
const nowMenu = useSelector((state) => state.common.menu.nowMenu);
|
||||
const entryMenu = useSelector((state) => state.common.menu.entryMenu);
|
||||
|
||||
const homeCategory = useSelector(
|
||||
(state) => state.home.menuData?.data?.homeCategory
|
||||
);
|
||||
const countryCode = useSelector((state) => state.common.httpHeader.cntry_cd);
|
||||
|
||||
// 정상적으로 로딩되면 빈객체로 넘어가고 , 에러가 나면 객체안에 타입이 담겨옵니다.
|
||||
const broadcast = useSelector((state) => state.common.broadcast);
|
||||
|
||||
const [randomData, setRandomData] = useState("");
|
||||
const [priceInfos, setpriceInfos] = useState("");
|
||||
const [isFocused, setIsFocused] = useState(false);
|
||||
const [videoError, setVideoError] = useState(false);
|
||||
const [liveIndicies, setLiveIndicies] = useState([]);
|
||||
|
||||
const timerRef = useRef();
|
||||
const bannerDataRef = useRef(bannerData);
|
||||
const randomDataRef = useRef(bannerDetailInfos[randomNumber]);
|
||||
|
||||
const [videoError, setVideoError] = useState(false);
|
||||
const topContentsLogInfo = useMemo(() => {
|
||||
if (curationId && curtNm) {
|
||||
const currentRandomData = randomDataRef.current;
|
||||
return {
|
||||
banrNo: `${currentRandomData?.banrDpOrd}`,
|
||||
banrTpNm: currentRandomData?.vtctpYn
|
||||
? currentRandomData.vtctpYn === "Y"
|
||||
? "Vertical"
|
||||
: "Horizontal"
|
||||
: "",
|
||||
contId: curationId,
|
||||
contNm: curtNm,
|
||||
contTpNm: currentRandomData?.shptmBanrTpNm ?? "",
|
||||
dspyTpNm: bannerDataRef.current?.shptmDspyTpNm ?? "",
|
||||
expsOrd: bannerDataRef.current?.banrLctnNo ?? "",
|
||||
linkTpCd: "", // pyh todo, get linkTpCd
|
||||
patncNm: currentRandomData?.patncNm ?? "",
|
||||
patnrId: currentRandomData?.patnrId ?? "",
|
||||
tmplCd: shptmTmplCd,
|
||||
};
|
||||
}
|
||||
|
||||
const [liveIndicies, setLiveIndicies] = useState([]);
|
||||
|
||||
// 정상적으로 로딩되면 빈객체로 넘어가고 , 에러가 나면 객체안에 타입이 담겨옵니다.
|
||||
const broadcast = useSelector((state) => state.common.broadcast);
|
||||
return {};
|
||||
}, [curationId, curtNm, shptmTmplCd]);
|
||||
|
||||
// 1. 비디오(live) 에러 감지
|
||||
// 2. 라이브 영상이 2개 이상이면, 그 다음 영상으로 전환
|
||||
@@ -116,16 +127,18 @@ export default function RandomUnit({
|
||||
|
||||
// 포커스 인
|
||||
const onFocus = useCallback(() => {
|
||||
setIsFocused(true);
|
||||
|
||||
if (handleItemFocus) {
|
||||
handleItemFocus();
|
||||
}
|
||||
setIsFocused(true);
|
||||
}, [handleItemFocus]);
|
||||
|
||||
// 포커스 아웃
|
||||
const onBlur = useCallback(() => {
|
||||
setIsFocused(false);
|
||||
clearTimeout(timerRef.current);
|
||||
|
||||
if (isFocused) {
|
||||
dispatch(finishVideoPreview());
|
||||
}
|
||||
@@ -159,41 +172,47 @@ export default function RandomUnit({
|
||||
}, [homeCategory, randomData.shptmLnkTpCd]);
|
||||
|
||||
// 이미지 배너 클릭
|
||||
const imageBannerClick = () => {
|
||||
let panelName = "";
|
||||
const imageBannerClick = useCallback(() => {
|
||||
let linkInfo = {};
|
||||
const linkType = randomData.shptmLnkTpCd;
|
||||
|
||||
if (randomData.shptmLnkTpCd === "DSP00501") {
|
||||
return dispatch(
|
||||
pushPanel({
|
||||
switch (linkType) {
|
||||
case "DSP00501":
|
||||
linkInfo = {
|
||||
name: panel_names.FEATURED_BRANDS_PANEL,
|
||||
panelInfo: { patnrId: randomData.patnrId },
|
||||
})
|
||||
);
|
||||
} else if (randomData.shptmLnkTpCd === "DSP00502") {
|
||||
panelName = panel_names.TRENDING_NOW_PANEL;
|
||||
} else if (randomData.shptmLnkTpCd === "DSP00503") {
|
||||
return dispatch(
|
||||
pushPanel({
|
||||
};
|
||||
break;
|
||||
|
||||
case "DSP00502":
|
||||
linkInfo = {
|
||||
name: panel_names.TRENDING_NOW_PANEL,
|
||||
panelInfo: {},
|
||||
};
|
||||
break;
|
||||
|
||||
case "DSP00503":
|
||||
linkInfo = {
|
||||
name: panel_names.HOT_PICKS_PANEL,
|
||||
panelInfo: {
|
||||
patnrId: randomData.patnrId,
|
||||
curationId: randomData.lnkCurationId,
|
||||
},
|
||||
})
|
||||
);
|
||||
} else if (randomData.shptmLnkTpCd === "DSP00504") {
|
||||
return dispatch(
|
||||
pushPanel({
|
||||
};
|
||||
break;
|
||||
|
||||
case "DSP00504":
|
||||
linkInfo = {
|
||||
name: panel_names.ON_SALE_PANEL,
|
||||
panelInfo: {
|
||||
lgCatCd: randomData.lgCatCd,
|
||||
},
|
||||
})
|
||||
);
|
||||
} else if (randomData.shptmLnkTpCd === "DSP00505") {
|
||||
if (Object.keys(categoryData).length > 0) {
|
||||
return dispatch(
|
||||
pushPanel({
|
||||
};
|
||||
break;
|
||||
|
||||
case "DSP00505":
|
||||
if (Object.keys(categoryData).length > 0) {
|
||||
linkInfo = {
|
||||
name: panel_names.CATEGORY_PANEL,
|
||||
panelInfo: {
|
||||
lgCatCd: randomData.lgCatCd,
|
||||
@@ -204,33 +223,33 @@ export default function RandomUnit({
|
||||
tab: 0,
|
||||
focusedContainerId: null,
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
} else if (randomData.shptmLnkTpCd === "DSP00506") {
|
||||
return dispatch(
|
||||
pushPanel({
|
||||
};
|
||||
}
|
||||
break;
|
||||
|
||||
case "DSP00506":
|
||||
linkInfo = {
|
||||
name: panel_names.DETAIL_PANEL,
|
||||
panelInfo: {
|
||||
patnrId: randomData.patnrId,
|
||||
prdtId: randomData.prdtId,
|
||||
curationId: randomData.lnkCurationId,
|
||||
},
|
||||
})
|
||||
);
|
||||
} else if (randomData.shptmLnkTpCd === "DSP00507") {
|
||||
return dispatch(
|
||||
startVideoPlayer({
|
||||
};
|
||||
break;
|
||||
|
||||
case "DSP00507":
|
||||
linkInfo = {
|
||||
patnrId: randomData.patnrId,
|
||||
showId: randomData.showId,
|
||||
shptmBanrTpNm: "VOD",
|
||||
lgCatCd: randomData.lgCatCd,
|
||||
modal: false,
|
||||
})
|
||||
);
|
||||
} else if (randomData.shptmLnkTpCd === "DSP00508") {
|
||||
return dispatch(
|
||||
pushPanel({
|
||||
};
|
||||
break;
|
||||
|
||||
case "DSP00508":
|
||||
linkInfo = {
|
||||
name: panel_names.DETAIL_PANEL,
|
||||
panelInfo: {
|
||||
patnrId: randomData.patnrId,
|
||||
@@ -238,31 +257,47 @@ export default function RandomUnit({
|
||||
prdtId: randomData.prdtId,
|
||||
type: "theme",
|
||||
},
|
||||
})
|
||||
);
|
||||
} else if (randomData.shptmLnkTpCd === "DSP00509") {
|
||||
return dispatch(
|
||||
pushPanel({
|
||||
};
|
||||
break;
|
||||
|
||||
case "DSP00509":
|
||||
linkInfo = {
|
||||
name: panel_names.THEME_CURATION_PANEL,
|
||||
panelInfo: {
|
||||
curationId: randomData.lnkCurationId,
|
||||
},
|
||||
})
|
||||
);
|
||||
} else {
|
||||
panelName = panel_names.HOME_PANEL;
|
||||
};
|
||||
break;
|
||||
|
||||
default:
|
||||
linkInfo = {
|
||||
name: panel_names.HOME_PANEL,
|
||||
panelInfo: {},
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
let action = linkType === "DSP00507" ? startVideoPlayer : pushPanel;
|
||||
|
||||
dispatch(action(linkInfo));
|
||||
dispatch(
|
||||
pushPanel({
|
||||
name: panelName,
|
||||
panelInfo: {
|
||||
patnrId: randomData.patnrId,
|
||||
prdtId: randomData.prdtId,
|
||||
},
|
||||
sendLogTopContents({
|
||||
...topContentsLogInfo,
|
||||
inDt: formatGMTString(new Date()) ?? "",
|
||||
logTpNo: LOG_TP_NO.TOP_CONTENTS.CLICK,
|
||||
})
|
||||
);
|
||||
};
|
||||
}, [
|
||||
categoryData,
|
||||
dispatch,
|
||||
randomData?.lgCatCd,
|
||||
randomData?.lnkCurationId,
|
||||
randomData?.patnrId,
|
||||
randomData?.prdtId,
|
||||
randomData?.showId,
|
||||
randomData?.shptmLnkTpCd,
|
||||
topContentsLogInfo,
|
||||
]);
|
||||
|
||||
// 투데이즈딜 클릭
|
||||
const todayDealClick = useCallback(() => {
|
||||
@@ -275,7 +310,15 @@ export default function RandomUnit({
|
||||
},
|
||||
})
|
||||
);
|
||||
}, [dispatch, randomData?.patnrId, randomData?.prdtId]);
|
||||
|
||||
dispatch(
|
||||
sendLogTopContents({
|
||||
...topContentsLogInfo,
|
||||
inDt: formatGMTString(new Date()) ?? "",
|
||||
logTpNo: LOG_TP_NO.TOP_CONTENTS.CLICK,
|
||||
})
|
||||
);
|
||||
}, [dispatch, randomData?.patnrId, randomData?.prdtId, topContentsLogInfo]);
|
||||
|
||||
// 비디오 클릭
|
||||
const videoClick = useCallback(() => {
|
||||
@@ -292,7 +335,15 @@ export default function RandomUnit({
|
||||
modalClassName: css.videoModal,
|
||||
})
|
||||
);
|
||||
}, [randomData, spotlightId]);
|
||||
|
||||
dispatch(
|
||||
sendLogTopContents({
|
||||
...topContentsLogInfo,
|
||||
inDt: formatGMTString(new Date()) ?? "",
|
||||
logTpNo: LOG_TP_NO.TOP_CONTENTS.CLICK,
|
||||
})
|
||||
);
|
||||
}, [randomData, spotlightId, topContentsLogInfo]);
|
||||
|
||||
// 투데이즈 딜 가격 정보
|
||||
const { originalPrice, discountedPrice, discountRate, offerInfo } =
|
||||
@@ -300,35 +351,21 @@ export default function RandomUnit({
|
||||
|
||||
// 로그
|
||||
useEffect(() => {
|
||||
if (
|
||||
bannerDataRef.current &&
|
||||
randomDataRef.current &&
|
||||
nowMenu &&
|
||||
nowMenu === LOG_MENU.HOME_TOP
|
||||
) {
|
||||
let _nowMenu = nowMenu;
|
||||
let _entryMenu = entryMenu;
|
||||
|
||||
if (nowMenu === LOG_MENU.HOME_TOP) {
|
||||
const params = {
|
||||
banrNo: `${randomDataRef.current?.banrDpOrd}`,
|
||||
banrTpNm: randomDataRef.current?.vtctpYn
|
||||
? randomDataRef.current.vtctpYn === "Y"
|
||||
? "Vertical"
|
||||
: "Horizontal"
|
||||
: "",
|
||||
contId: curationId ?? "",
|
||||
contNm: curtNm ?? "",
|
||||
contTpNm: randomDataRef.current?.shptmBanrTpNm ?? "",
|
||||
dspyTpNm: bannerDataRef.current?.shptmDspyTpNm ?? "",
|
||||
expsOrd: bannerDataRef.current?.banrLctnNo ?? "",
|
||||
inDt: formatGMTString(new Date()),
|
||||
linkTpCd: "",
|
||||
...topContentsLogInfo,
|
||||
entryMenu: _entryMenu,
|
||||
inDt: formatGMTString(new Date()) ?? "",
|
||||
logTpNo: LOG_TP_NO.TOP_CONTENTS.VIEW,
|
||||
patncNm: randomDataRef.current?.patncNm ?? "",
|
||||
patnrId: randomDataRef.current?.patnrId ?? "",
|
||||
tmplCd: shptmTmplCd,
|
||||
nowMenu: _nowMenu,
|
||||
};
|
||||
|
||||
return () => dispatch(sendLogTopContents(params));
|
||||
}
|
||||
}, [curationId, curtNm, nowMenu, shptmTmplCd]);
|
||||
}, [dispatch, entryMenu, nowMenu, topContentsLogInfo]);
|
||||
|
||||
useEffect(() => {
|
||||
if (bannerData) {
|
||||
|
||||
@@ -77,6 +77,7 @@ export default function RollingUnit({
|
||||
(state) => state.home?.bannerData?.shptmTmplCd
|
||||
);
|
||||
const nowMenu = useSelector((state) => state.common.menu.nowMenu);
|
||||
const entryMenu = useSelector((state) => state.common.menu.entryMenu);
|
||||
|
||||
const homeCategory = useSelector(
|
||||
(state) => state.home.menuData?.data?.homeCategory
|
||||
@@ -100,6 +101,31 @@ export default function RollingUnit({
|
||||
const bannerDataRef = useRef(bannerData);
|
||||
const rollingDataRef = useRef(rollingData);
|
||||
|
||||
const topContentsLogInfo = useMemo(() => {
|
||||
if (curationId && curtNm) {
|
||||
const currentRollingData = rollingDataRef.current[startIndex];
|
||||
return {
|
||||
banrNo: `${currentRollingData?.banrDpOrd}`,
|
||||
banrTpNm: currentRollingData?.vtctpYn
|
||||
? currentRollingData.vtctpYn === "Y"
|
||||
? "Vertical"
|
||||
: "Horizontal"
|
||||
: "",
|
||||
contId: curationId,
|
||||
contNm: curtNm,
|
||||
contTpNm: currentRollingData?.shptmBanrTpNm ?? "",
|
||||
dspyTpNm: bannerDataRef.current?.shptmDspyTpNm ?? "",
|
||||
expsOrd: bannerDataRef.current?.banrLctnNo ?? "",
|
||||
linkTpCd: "",
|
||||
patncNm: currentRollingData?.patncNm ?? "",
|
||||
patnrId: currentRollingData?.patnrId ?? "",
|
||||
tmplCd: shptmTmplCd,
|
||||
};
|
||||
}
|
||||
|
||||
return {};
|
||||
}, [curationId, curtNm, shptmTmplCd, startIndex]);
|
||||
|
||||
useEffect(() => {
|
||||
if (savedIndex !== undefined) {
|
||||
setStartIndex(savedIndex);
|
||||
@@ -251,6 +277,13 @@ export default function RollingUnit({
|
||||
|
||||
if (bannerType === "Today's Deals") {
|
||||
handlePushPanel(panel_names.DETAIL_PANEL, createPanelInfo(currentData));
|
||||
dispatch(
|
||||
sendLogTopContents({
|
||||
...topContentsLogInfo,
|
||||
inDt: formatGMTString(new Date()) ?? "",
|
||||
logTpNo: LOG_TP_NO.TOP_CONTENTS.CLICK,
|
||||
})
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -310,6 +343,14 @@ export default function RollingUnit({
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(
|
||||
sendLogTopContents({
|
||||
...topContentsLogInfo,
|
||||
inDt: formatGMTString(new Date()) ?? "",
|
||||
logTpNo: LOG_TP_NO.TOP_CONTENTS.CLICK,
|
||||
})
|
||||
);
|
||||
}, [
|
||||
rollingData,
|
||||
startIndex,
|
||||
@@ -317,6 +358,7 @@ export default function RollingUnit({
|
||||
dispatch,
|
||||
categoryData,
|
||||
handlePushPanel,
|
||||
topContentsLogInfo,
|
||||
]);
|
||||
|
||||
const videoClick = useCallback(() => {
|
||||
@@ -337,7 +379,22 @@ export default function RollingUnit({
|
||||
modalContainerId: null,
|
||||
modalClassName: css.videoModal,
|
||||
});
|
||||
}, [rollingData, startIndex, bannerId, dispatch, handleStartVideoPlayer]);
|
||||
|
||||
dispatch(
|
||||
sendLogTopContents({
|
||||
...topContentsLogInfo,
|
||||
inDt: formatGMTString(new Date()) ?? "",
|
||||
logTpNo: LOG_TP_NO.TOP_CONTENTS.CLICK,
|
||||
})
|
||||
);
|
||||
}, [
|
||||
rollingData,
|
||||
startIndex,
|
||||
bannerId,
|
||||
dispatch,
|
||||
handleStartVideoPlayer,
|
||||
topContentsLogInfo,
|
||||
]);
|
||||
|
||||
// 10초 롤링
|
||||
useEffect(() => {
|
||||
@@ -358,32 +415,16 @@ export default function RollingUnit({
|
||||
}, [rollingDataLength, rollingFocus, animate]);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
bannerDataRef.current &&
|
||||
rollingDataRef.current &&
|
||||
nowMenu &&
|
||||
nowMenu === LOG_MENU.HOME_TOP
|
||||
) {
|
||||
const currentRollingData = rollingDataRef.current[startIndex];
|
||||
let _nowMenu = nowMenu;
|
||||
let _entryMenu = entryMenu;
|
||||
|
||||
if (nowMenu === LOG_MENU.HOME_TOP) {
|
||||
const params = {
|
||||
banrNo: `${currentRollingData?.banrDpOrd}`,
|
||||
banrTpNm: currentRollingData?.vtctpYn
|
||||
? currentRollingData.vtctpYn === "Y"
|
||||
? "Vertical"
|
||||
: "Horizontal"
|
||||
: "",
|
||||
contId: curationId ?? "",
|
||||
contNm: curtNm ?? "",
|
||||
contTpNm: currentRollingData?.shptmBanrTpNm ?? "",
|
||||
dspyTpNm: bannerDataRef.current?.shptmDspyTpNm ?? "",
|
||||
expsOrd: bannerDataRef.current?.banrLctnNo ?? "",
|
||||
inDt: formatGMTString(new Date()),
|
||||
linkTpCd: "",
|
||||
...topContentsLogInfo,
|
||||
entryMenu: _entryMenu,
|
||||
inDt: formatGMTString(new Date()) ?? "",
|
||||
logTpNo: LOG_TP_NO.TOP_CONTENTS.VIEW,
|
||||
patncNm: currentRollingData?.patncNm ?? "",
|
||||
patnrId: currentRollingData?.patnrId ?? "",
|
||||
tmplCd: shptmTmplCd,
|
||||
nowMenu: _nowMenu,
|
||||
};
|
||||
|
||||
return () => {
|
||||
@@ -393,7 +434,7 @@ export default function RollingUnit({
|
||||
}
|
||||
};
|
||||
}
|
||||
}, [curationId, curtNm, nowMenu, shptmTmplCd, startIndex]);
|
||||
}, [dispatch, entryMenu, nowMenu, startIndex, topContentsLogInfo]);
|
||||
|
||||
useEffect(() => {
|
||||
if (nowMenu !== LOG_MENU.HOME_TOP) {
|
||||
|
||||
Reference in New Issue
Block a user