Boost Modal: Support multiple boosts for one channel (#3963)
This commit is contained in:
parent
cd28a97822
commit
62f742c023
@ -212,19 +212,32 @@ export async function fetchMyBoosts() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function applyBoost({
|
export async function applyBoost({
|
||||||
chat,
|
chat,
|
||||||
slots,
|
slots,
|
||||||
} : {
|
} : {
|
||||||
chat: ApiChat;
|
chat: ApiChat;
|
||||||
slots: number[];
|
slots: number[];
|
||||||
}) {
|
}) {
|
||||||
return invokeRequest(new GramJs.premium.ApplyBoost({
|
const result = await invokeRequest(new GramJs.premium.ApplyBoost({
|
||||||
peer: buildInputPeer(chat.id, chat.accessHash),
|
peer: buildInputPeer(chat.id, chat.accessHash),
|
||||||
slots,
|
slots,
|
||||||
}), {
|
}));
|
||||||
shouldReturnTrue: true,
|
|
||||||
});
|
if (!result) return undefined;
|
||||||
|
|
||||||
|
addEntitiesToLocalDb(result.users);
|
||||||
|
addEntitiesToLocalDb(result.chats);
|
||||||
|
|
||||||
|
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||||
|
const chats = result.chats.map((c) => buildApiChatFromPreview(c)).filter(Boolean);
|
||||||
|
const boosts = result.myBoosts.map(buildApiMyBoost);
|
||||||
|
|
||||||
|
return {
|
||||||
|
users,
|
||||||
|
chats,
|
||||||
|
boosts,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchBoostsStatus({
|
export async function fetchBoostsStatus({
|
||||||
|
|||||||
@ -5,11 +5,11 @@ export function getBoostProgressInfo(boostInfo: ApiBoostsStatus, freezeOnLevelUp
|
|||||||
level, boosts, currentLevelBoosts, nextLevelBoosts, hasMyBoost,
|
level, boosts, currentLevelBoosts, nextLevelBoosts, hasMyBoost,
|
||||||
} = boostInfo;
|
} = boostInfo;
|
||||||
|
|
||||||
const currentLevel = level;
|
|
||||||
const hasNextLevel = Boolean(nextLevelBoosts);
|
|
||||||
|
|
||||||
const isJustUpgraded = freezeOnLevelUp && boosts === currentLevelBoosts && hasMyBoost;
|
const isJustUpgraded = freezeOnLevelUp && boosts === currentLevelBoosts && hasMyBoost;
|
||||||
|
|
||||||
|
const currentLevel = isJustUpgraded ? level - 1 : level;
|
||||||
|
const hasNextLevel = Boolean(nextLevelBoosts);
|
||||||
|
|
||||||
const levelProgress = (!nextLevelBoosts || isJustUpgraded) ? 1
|
const levelProgress = (!nextLevelBoosts || isJustUpgraded) ? 1
|
||||||
: (boosts - currentLevelBoosts) / (nextLevelBoosts - currentLevelBoosts);
|
: (boosts - currentLevelBoosts) / (nextLevelBoosts - currentLevelBoosts);
|
||||||
const remainingBoosts = nextLevelBoosts ? nextLevelBoosts - boosts : 0;
|
const remainingBoosts = nextLevelBoosts ? nextLevelBoosts - boosts : 0;
|
||||||
|
|||||||
@ -33,6 +33,7 @@ type LoadedParams = {
|
|||||||
progress: number;
|
progress: number;
|
||||||
descriptionText: string;
|
descriptionText: string;
|
||||||
isBoosted?: boolean;
|
isBoosted?: boolean;
|
||||||
|
canBoostMore?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type BoostInfo = ({
|
type BoostInfo = ({
|
||||||
@ -100,6 +101,7 @@ const BoostModal = ({
|
|||||||
value,
|
value,
|
||||||
progress,
|
progress,
|
||||||
descriptionText,
|
descriptionText,
|
||||||
|
canBoostMore,
|
||||||
}: BoostInfo = useMemo(() => {
|
}: BoostInfo = useMemo(() => {
|
||||||
if (!info?.boostStatus || !chat) {
|
if (!info?.boostStatus || !chat) {
|
||||||
return {
|
return {
|
||||||
@ -112,7 +114,8 @@ const BoostModal = ({
|
|||||||
level, currentLevelBoosts, hasMyBoost,
|
level, currentLevelBoosts, hasMyBoost,
|
||||||
} = info.boostStatus;
|
} = info.boostStatus;
|
||||||
|
|
||||||
const firstBoost = info?.myBoosts && getFirstAvailableBoost(info.myBoosts);
|
const firstBoost = info?.myBoosts && getFirstAvailableBoost(info.myBoosts, chat.id);
|
||||||
|
const areBoostsInDifferentChannels = info?.myBoosts && !areAllBoostsInChannel(info.myBoosts, chat.id);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
boosts,
|
boosts,
|
||||||
@ -163,10 +166,11 @@ const BoostModal = ({
|
|||||||
descriptionText: description,
|
descriptionText: description,
|
||||||
boost: firstBoost,
|
boost: firstBoost,
|
||||||
isBoosted: hasBoost,
|
isBoosted: hasBoost,
|
||||||
|
canBoostMore: areBoostsInDifferentChannels,
|
||||||
};
|
};
|
||||||
}, [chat, chatTitle, info, lang]);
|
}, [chat, chatTitle, info, lang]);
|
||||||
|
|
||||||
const isBoostDisabled = !boost && isCurrentUserPremium;
|
const isBoostDisabled = !info?.myBoosts?.length && isCurrentUserPremium;
|
||||||
const isReplacingBoost = boost?.chatId && boost.chatId !== info?.chatId;
|
const isReplacingBoost = boost?.chatId && boost.chatId !== info?.chatId;
|
||||||
|
|
||||||
const handleApplyBoost = useLastCallback(() => {
|
const handleApplyBoost = useLastCallback(() => {
|
||||||
@ -187,10 +191,11 @@ const BoostModal = ({
|
|||||||
openPremiumDialog();
|
openPremiumDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
closeBoostModal();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isBoosted) {
|
if (!canBoostMore) {
|
||||||
closeBoostModal();
|
closeBoostModal();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -231,10 +236,10 @@ const BoostModal = ({
|
|||||||
</div>
|
</div>
|
||||||
<div className="dialog-buttons">
|
<div className="dialog-buttons">
|
||||||
<Button isText className="confirm-dialog-button" disabled={isBoostDisabled} onClick={handleButtonClick}>
|
<Button isText className="confirm-dialog-button" disabled={isBoostDisabled} onClick={handleButtonClick}>
|
||||||
{!isBoosted ? (
|
{canBoostMore ? (
|
||||||
<>
|
<>
|
||||||
<Icon name="boost" />
|
<Icon name="boost" />
|
||||||
{lang('ChannelBoost.BoostChannel')}
|
{lang(isBoosted && canBoostMore ? 'BoostingBoostAgain' : 'ChannelBoost.BoostChannel')}
|
||||||
</>
|
</>
|
||||||
) : lang('OK')}
|
) : lang('OK')}
|
||||||
</Button>
|
</Button>
|
||||||
@ -316,14 +321,20 @@ const BoostModal = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
function getFirstAvailableBoost(myBoosts: ApiMyBoost[]) {
|
function getFirstAvailableBoost(myBoosts: ApiMyBoost[], chatId?: string) {
|
||||||
return myBoosts.find((boost) => !boost.chatId) || myBoosts.sort((a, b) => a.date - b.date)[0];
|
return myBoosts.find((boost) => !boost.chatId)
|
||||||
|
|| myBoosts.filter((b) => chatId && b.chatId !== chatId)
|
||||||
|
.sort((a, b) => a.date - b.date)[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
function areAllBoostsInChannel(myBoosts: ApiMyBoost[], chatId: string) {
|
||||||
|
return myBoosts.every((boost) => boost.chatId === chatId);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default memo(withGlobal<OwnProps>(
|
export default memo(withGlobal<OwnProps>(
|
||||||
(global, { info }): StateProps => {
|
(global, { info }): StateProps => {
|
||||||
const chat = info && selectChat(global, info?.chatId);
|
const chat = info && selectChat(global, info?.chatId);
|
||||||
const firstBoost = info?.myBoosts && getFirstAvailableBoost(info.myBoosts);
|
const firstBoost = info?.myBoosts && getFirstAvailableBoost(info.myBoosts, info.chatId);
|
||||||
const boostedChat = firstBoost?.chatId ? selectChat(global, firstBoost?.chatId) : undefined;
|
const boostedChat = firstBoost?.chatId ? selectChat(global, firstBoost?.chatId) : undefined;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -611,6 +611,20 @@ addActionHandler('applyBoost', async (global, actions, payload): Promise<void> =
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
global = getGlobal();
|
||||||
|
let tabState = selectTabState(global, tabId);
|
||||||
|
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||||
|
global = addChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||||
|
if (tabState.boostModal) {
|
||||||
|
global = updateTabState(global, {
|
||||||
|
boostModal: {
|
||||||
|
...tabState.boostModal,
|
||||||
|
myBoosts: result.boosts,
|
||||||
|
},
|
||||||
|
}, tabId);
|
||||||
|
}
|
||||||
|
setGlobal(global);
|
||||||
|
|
||||||
const newStatusResult = await callApi('fetchBoostsStatus', {
|
const newStatusResult = await callApi('fetchBoostsStatus', {
|
||||||
chat,
|
chat,
|
||||||
});
|
});
|
||||||
@ -620,7 +634,7 @@ addActionHandler('applyBoost', async (global, actions, payload): Promise<void> =
|
|||||||
}
|
}
|
||||||
|
|
||||||
global = getGlobal();
|
global = getGlobal();
|
||||||
const tabState = selectTabState(global, tabId);
|
tabState = selectTabState(global, tabId);
|
||||||
if (!tabState.boostModal?.boostStatus) return;
|
if (!tabState.boostModal?.boostStatus) return;
|
||||||
global = updateTabState(global, {
|
global = updateTabState(global, {
|
||||||
boostModal: {
|
boostModal: {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user