no longer set resolution, everything from event loop
This commit is contained in:
parent
b04ae8a8d4
commit
64896cfb3a
@ -2,6 +2,7 @@ export const setAccount = value => ({ type: 'SET_ACCOUNT', value });
|
|||||||
export const setActiveConstruct = value => ({ type: 'SET_ACTIVE_CONSTRUCT', value });
|
export const setActiveConstruct = value => ({ type: 'SET_ACTIVE_CONSTRUCT', value });
|
||||||
|
|
||||||
export const setAnimating = value => ({ type: 'SET_ANIMATING', value });
|
export const setAnimating = value => ({ type: 'SET_ANIMATING', value });
|
||||||
|
export const setAnimFocus = value => ({ type: 'SET_ANIM_FOCUS', value });
|
||||||
export const setAnimSource = value => ({ type: 'SET_ANIM_SOURCE', value });
|
export const setAnimSource = value => ({ type: 'SET_ANIM_SOURCE', value });
|
||||||
export const setAnimTarget = value => ({ type: 'SET_ANIM_TARGET', value });
|
export const setAnimTarget = value => ({ type: 'SET_ANIM_TARGET', value });
|
||||||
export const setAnimText = value => ({ type: 'SET_ANIM_TEXT', value });
|
export const setAnimText = value => ({ type: 'SET_ANIM_TEXT', value });
|
||||||
|
|||||||
@ -86,94 +86,116 @@ function getSequence(resolution) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const SOURCE_DURATION_MS = 1000;
|
|
||||||
const TARGET_DELAY_MS = 500;
|
|
||||||
const TARGET_DURATION_MS = 1500;
|
|
||||||
const POST_SKILL_DELAY_MS = 2000;
|
|
||||||
const POST_SKILL_DURATION_MS = 1000;
|
|
||||||
const SOURCE_AND_TARGET_TOTAL_DURATION = TARGET_DELAY_MS + TARGET_DURATION_MS + POST_SKILL_DURATION_MS;
|
|
||||||
|
|
||||||
function getTime(stages) {
|
function getTime(stages) {
|
||||||
if (stages.includes('START_SKILL') && stages.includes('END_SKILL')) {
|
|
||||||
return TIMES.SOURCE_AND_TARGET_TOTAL_DURATION;
|
|
||||||
}
|
|
||||||
|
|
||||||
let time = 0;
|
let time = 0;
|
||||||
|
if (stages.includes('START_SKILL') && stages.includes('END_SKILL')) {
|
||||||
|
time += TIMES.SOURCE_AND_TARGET_TOTAL_DURATION;
|
||||||
|
} else {
|
||||||
if (stages.includes('START_SKILL')) time += TIMES.SOURCE_DURATION_MS;
|
if (stages.includes('START_SKILL')) time += TIMES.SOURCE_DURATION_MS;
|
||||||
if (stages.includes('END_SKILL')) time += TIMES.TARGET_DURATION_MS;
|
if (stages.includes('END_SKILL')) time += TIMES.TARGET_DURATION_MS;
|
||||||
|
}
|
||||||
if (stages.includes('POST_SKILL')) time += TIMES.POST_SKILL_DURATION_MS;
|
if (stages.includes('POST_SKILL')) time += TIMES.POST_SKILL_DURATION_MS;
|
||||||
|
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getText(resolution, sequence) {
|
function getFocusTargets(resolution, game) {
|
||||||
if (!resolution) return { text: null, constructId: null };
|
if (!resolution) return [];
|
||||||
if (!sequence.includes('POST_SKILL')) return { text: null, constructId: null };
|
if (!resolution.event) return [];
|
||||||
|
const [type] = resolution.event;
|
||||||
|
const source = resolution.source.id;
|
||||||
|
const target = resolution.target.id;
|
||||||
|
|
||||||
function generateText() {
|
if (type === 'AoeSkill') {
|
||||||
|
const targetTeam = game.players.find(t => t.constructs.find(c => c.id === target));
|
||||||
|
const targetTeamIds = targetTeam.constructs.map(c => c.id);
|
||||||
|
if (source !== target) return targetTeamIds.push(source);
|
||||||
|
return targetTeamIds;
|
||||||
|
}
|
||||||
|
if (source !== target) return [source, target];
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getText(resolution, sequence) {
|
||||||
|
const nullText = { text: null, constructId: null, life: null };
|
||||||
|
if (!resolution) return nullText;
|
||||||
|
if (!sequence.includes('POST_SKILL')) return nullText;
|
||||||
|
|
||||||
|
function generatePostSkill() {
|
||||||
const [type, event] = resolution.event;
|
const [type, event] = resolution.event;
|
||||||
if (type === 'Ko') {
|
if (type === 'Ko') {
|
||||||
return 'KO!';
|
return { text: 'KO!', css: 'ko' };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === 'Disable') {
|
if (type === 'Disable') {
|
||||||
const { disable } = event;
|
const { disable } = event;
|
||||||
return `${disable}`;
|
return { text: `${disable}`, css: '' };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === 'Immunity') {
|
if (type === 'Immunity') {
|
||||||
return 'IMMUNE';
|
return { text: 'IMMUNE', css: '' };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === 'Damage') {
|
if (type === 'Damage') {
|
||||||
const { mitigation, colour } = event;
|
const { mitigation, colour } = event;
|
||||||
let { amount } = event;
|
let { amount } = event;
|
||||||
if (colour === 'Green') amount *= -1;
|
let css = '';
|
||||||
|
if (colour === 'Green') {
|
||||||
|
css = 'green-damage';
|
||||||
|
amount *= -1;
|
||||||
|
}
|
||||||
|
if (colour === 'Red') css = 'red-damage';
|
||||||
|
if (colour === 'Blue') css = 'blue-damage';
|
||||||
|
|
||||||
const mitigationText = mitigation
|
const mitigationText = mitigation
|
||||||
? `(${mitigation})`
|
? `(${mitigation})`
|
||||||
: '';
|
: '';
|
||||||
return `${amount} ${mitigationText}`;
|
return { text: `${amount} ${mitigationText}`, css };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === 'Healing') {
|
if (type === 'Healing') {
|
||||||
const { amount, overhealing } = event;
|
const { amount, overhealing } = event;
|
||||||
return `${amount} (${overhealing} OH)`;
|
return { text: `${amount} (${overhealing} OH)`, css: 'green-damage' };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === 'Inversion') {
|
if (type === 'Inversion') {
|
||||||
return 'INVERT';
|
return { text: 'INVERT', css: '' };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === 'Reflection') {
|
if (type === 'Reflection') {
|
||||||
return 'REFLECT';
|
return { text: 'REFLECT', css: '' };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === 'Effect') {
|
if (type === 'Effect') {
|
||||||
const { effect, duration } = event;
|
const { effect, duration, construct_effects: effects } = event;
|
||||||
return `+ ${effect} ${duration}T`;
|
return { text: `+ ${effect} ${duration}T`, css: '', effects };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === 'Recharge') {
|
if (type === 'Recharge') {
|
||||||
const { red, blue } = event;
|
const { red, blue } = event;
|
||||||
return [`+${red}R ${blue}B`, ''];
|
return { text: [`+${red}R ${blue}B`, ''], css: '' };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === 'Removal') {
|
if (type === 'Removal') {
|
||||||
const { effect } = event;
|
const { effect, construct_effects: effects } = event;
|
||||||
return `-${effect}`;
|
return { text: `-${effect}`, css: '', effects };
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { green, red, blue } = resolution.target;
|
||||||
|
const { text, css, effects } = generatePostSkill();
|
||||||
return {
|
return {
|
||||||
text: generateText(),
|
css,
|
||||||
|
text,
|
||||||
|
effects,
|
||||||
|
life: { green, red, blue },
|
||||||
constructId: resolution.target.id,
|
constructId: resolution.target.id,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
getFocusTargets,
|
||||||
getObjects,
|
getObjects,
|
||||||
getTime,
|
getTime,
|
||||||
getSequence,
|
getSequence,
|
||||||
|
|||||||
@ -3,7 +3,7 @@ const { Component } = require('preact');
|
|||||||
const preact = require('preact');
|
const preact = require('preact');
|
||||||
const range = require('lodash/range');
|
const range = require('lodash/range');
|
||||||
|
|
||||||
const { STATS, eventClasses } = require('../utils');
|
const { STATS } = require('../utils');
|
||||||
const { ConstructAvatar, ConstructText } = require('./construct');
|
const { ConstructAvatar, ConstructText } = require('./construct');
|
||||||
const { ConstructAnimation } = require('./animations');
|
const { ConstructAnimation } = require('./animations');
|
||||||
const shapes = require('./shapes');
|
const shapes = require('./shapes');
|
||||||
@ -21,8 +21,9 @@ const addState = connect(
|
|||||||
game,
|
game,
|
||||||
account,
|
account,
|
||||||
activeSkill,
|
activeSkill,
|
||||||
|
animFocus,
|
||||||
resolution,
|
resolution,
|
||||||
|
animating,
|
||||||
animText,
|
animText,
|
||||||
} = state;
|
} = state;
|
||||||
|
|
||||||
@ -41,13 +42,31 @@ const addState = connect(
|
|||||||
game,
|
game,
|
||||||
account,
|
account,
|
||||||
resolution,
|
resolution,
|
||||||
|
animating,
|
||||||
|
animFocus,
|
||||||
animText,
|
animText,
|
||||||
activeSkill,
|
activeSkill,
|
||||||
selectSkillTarget,
|
selectSkillTarget,
|
||||||
};
|
};
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const eventClasses = (animating, animFocus, construct, postSkill) => {
|
||||||
|
if (!animating) return '';
|
||||||
|
if (!postSkill) {
|
||||||
|
if (animFocus.includes(construct.id)) return '';
|
||||||
|
return 'unfocus';
|
||||||
|
}
|
||||||
|
if (postSkill.constructId !== construct.id) {
|
||||||
|
if (animFocus.includes(construct.id)) return '';
|
||||||
|
return 'unfocus';
|
||||||
|
}
|
||||||
|
if (postSkill.effects) construct.effects = postSkill.effects;
|
||||||
|
construct.green_life.value = postSkill.life.green;
|
||||||
|
construct.red_life.value = postSkill.life.red;
|
||||||
|
construct.blue_life.value = postSkill.life.blue;
|
||||||
|
return postSkill.css;
|
||||||
|
};
|
||||||
|
|
||||||
class GameConstruct extends Component {
|
class GameConstruct extends Component {
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -58,21 +77,17 @@ class GameConstruct extends Component {
|
|||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
i,
|
i,
|
||||||
game,
|
animating,
|
||||||
account,
|
|
||||||
construct,
|
construct,
|
||||||
player,
|
player,
|
||||||
activeSkill,
|
activeSkill,
|
||||||
selectSkillTarget,
|
selectSkillTarget,
|
||||||
|
animFocus,
|
||||||
// todo remove dep
|
|
||||||
resolution,
|
|
||||||
|
|
||||||
animText,
|
animText,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const ko = construct.green_life.value === 0 ? 'ko' : '';
|
const ko = construct.green_life.value === 0 ? 'ko' : '';
|
||||||
const classes = eventClasses(game, account, resolution, construct, animText);
|
const classes = eventClasses(animating, animFocus, construct, animText);
|
||||||
|
|
||||||
const stats = ['RedLife', 'GreenLife', 'BlueLife'].map((s, j) => (
|
const stats = ['RedLife', 'GreenLife', 'BlueLife'].map((s, j) => (
|
||||||
<div key={j} alt={STATS[s].stat}>
|
<div key={j} alt={STATS[s].stat}>
|
||||||
@ -83,7 +98,7 @@ class GameConstruct extends Component {
|
|||||||
));
|
));
|
||||||
|
|
||||||
const skills = range(0, 3)
|
const skills = range(0, 3)
|
||||||
.map(j => <SkillBtn key={j} construct={construct} i={j} j={i} />);
|
.map(j => <SkillBtn key={j} construct={construct} i={j} j={i} animating={animating} />);
|
||||||
|
|
||||||
let crypSkills = <div> </div>;
|
let crypSkills = <div> </div>;
|
||||||
if (player) crypSkills = (<div class="skills"> {skills} </div>);
|
if (player) crypSkills = (<div class="skills"> {skills} </div>);
|
||||||
|
|||||||
@ -1,16 +1,14 @@
|
|||||||
const SOURCE_DURATION_MS = 1000;
|
const SOURCE_DURATION_MS = 1000;
|
||||||
const TARGET_DELAY_MS = 500;
|
const TARGET_DELAY_MS = 500;
|
||||||
const TARGET_DURATION_MS = 1500;
|
const TARGET_DURATION_MS = 1500;
|
||||||
const POST_SKILL_DELAY_MS = 2000;
|
|
||||||
const POST_SKILL_DURATION_MS = 1000;
|
const POST_SKILL_DURATION_MS = 1000;
|
||||||
const SOURCE_AND_TARGET_TOTAL_DURATION = TARGET_DELAY_MS + TARGET_DURATION_MS + POST_SKILL_DURATION_MS;
|
const SOURCE_AND_TARGET_TOTAL_DURATION = TARGET_DELAY_MS + TARGET_DURATION_MS;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
TIMES: {
|
TIMES: {
|
||||||
SOURCE_DURATION_MS,
|
SOURCE_DURATION_MS,
|
||||||
TARGET_DELAY_MS,
|
TARGET_DELAY_MS,
|
||||||
TARGET_DURATION_MS,
|
TARGET_DURATION_MS,
|
||||||
POST_SKILL_DELAY_MS,
|
|
||||||
POST_SKILL_DURATION_MS,
|
POST_SKILL_DURATION_MS,
|
||||||
SOURCE_AND_TARGET_TOTAL_DURATION,
|
SOURCE_AND_TARGET_TOTAL_DURATION,
|
||||||
},
|
},
|
||||||
@ -20,7 +18,7 @@ module.exports = {
|
|||||||
RED: '#a52a2a',
|
RED: '#a52a2a',
|
||||||
BLUE: '#3498db',
|
BLUE: '#3498db',
|
||||||
WHITE: '#f5f5f5', // whitesmoke
|
WHITE: '#f5f5f5', // whitesmoke
|
||||||
PURPLE: '#9355b5' // 6lack - that far cover
|
PURPLE: '#9355b5', // 6lack - that far cover
|
||||||
},
|
},
|
||||||
|
|
||||||
INFO: {
|
INFO: {
|
||||||
|
|||||||
@ -55,8 +55,6 @@ function registerEvents(store) {
|
|||||||
return eachSeries(newRes, (r, cb) => {
|
return eachSeries(newRes, (r, cb) => {
|
||||||
if (['Disable', 'TargetKo'].includes(r.event[0])) return cb();
|
if (['Disable', 'TargetKo'].includes(r.event[0])) return cb();
|
||||||
|
|
||||||
store.dispatch(actions.setResolution(r));
|
|
||||||
|
|
||||||
// convert server enum into anims keywords
|
// convert server enum into anims keywords
|
||||||
// todo make serersideonly
|
// todo make serersideonly
|
||||||
const sequence = animations.getSequence(r);
|
const sequence = animations.getSequence(r);
|
||||||
@ -64,13 +62,15 @@ function registerEvents(store) {
|
|||||||
const anims = animations.getObjects(r, sequence, game, account);
|
const anims = animations.getObjects(r, sequence, game, account);
|
||||||
const text = animations.getText(r, sequence);
|
const text = animations.getText(r, sequence);
|
||||||
|
|
||||||
|
store.dispatch(actions.setAnimFocus(animations.getFocusTargets(r)));
|
||||||
|
|
||||||
if (sequence.includes('START_SKILL')) store.dispatch(actions.setAnimSource(anims.animSource));
|
if (sequence.includes('START_SKILL')) store.dispatch(actions.setAnimSource(anims.animSource));
|
||||||
if (sequence.includes('END_SKILL')) store.dispatch(actions.setAnimTarget(anims.animTarget));
|
if (sequence.includes('END_SKILL')) store.dispatch(actions.setAnimTarget(anims.animTarget));
|
||||||
if (sequence.includes('POST_SKILL')) {
|
if (sequence.includes('POST_SKILL')) {
|
||||||
// timeout to prevent text classes from being added too soon
|
// timeout to prevent text classes from being added too soon
|
||||||
setTimeout(
|
setTimeout(
|
||||||
() => store.dispatch(actions.setAnimText(text)),
|
() => store.dispatch(actions.setAnimText(text)),
|
||||||
timeout - 1000,
|
timeout - TIMES.POST_SKILL_DURATION_MS
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,9 +78,10 @@ function registerEvents(store) {
|
|||||||
store.dispatch(actions.setAnimSource(null));
|
store.dispatch(actions.setAnimSource(null));
|
||||||
store.dispatch(actions.setAnimTarget(null));
|
store.dispatch(actions.setAnimTarget(null));
|
||||||
store.dispatch(actions.setAnimText(null));
|
store.dispatch(actions.setAnimText(null));
|
||||||
return cb();
|
// We currently need another small timeout so that everything can properly dismount / unload
|
||||||
|
// Otherwise 3 x Attack on same target will only render the first time
|
||||||
|
return setTimeout(cb, 75);
|
||||||
}, timeout);
|
}, timeout);
|
||||||
|
|
||||||
}, err => {
|
}, err => {
|
||||||
if (err) return console.error(err);
|
if (err) return console.error(err);
|
||||||
// clear animation state
|
// clear animation state
|
||||||
|
|||||||
@ -18,6 +18,7 @@ module.exports = {
|
|||||||
|
|
||||||
animating: createReducer(false, 'SET_ANIMATING'),
|
animating: createReducer(false, 'SET_ANIMATING'),
|
||||||
animSource: createReducer(null, 'SET_ANIM_SOURCE'),
|
animSource: createReducer(null, 'SET_ANIM_SOURCE'),
|
||||||
|
animFocus: createReducer(null, 'SET_ANIM_FOCUS'),
|
||||||
animTarget: createReducer(null, 'SET_ANIM_TARGET'),
|
animTarget: createReducer(null, 'SET_ANIM_TARGET'),
|
||||||
animText: createReducer(null, 'SET_ANIM_TEXT'),
|
animText: createReducer(null, 'SET_ANIM_TEXT'),
|
||||||
|
|
||||||
|
|||||||
@ -85,89 +85,6 @@ const STATS = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function eventClasses(game, account, resolution, construct, postSkill) {
|
|
||||||
if (!resolution) return '';
|
|
||||||
const source = construct.id === resolution.source.id;
|
|
||||||
const target = construct.id === resolution.target.id;
|
|
||||||
// not involved at all. blur them
|
|
||||||
const [type, event] = resolution.event;
|
|
||||||
|
|
||||||
if (type === 'AoeSkill') {
|
|
||||||
const playerTeam = game.players.find(t => t.id === account.id);
|
|
||||||
const playerTeamIds = playerTeam.constructs.map(c => c.id);
|
|
||||||
const otherTeam = game.players.find(t => t.id !== account.id);
|
|
||||||
const otherTeamIds = otherTeam.constructs.map(c => c.id);
|
|
||||||
const targetIsPlayer = playerTeamIds.includes(resolution.target.id);
|
|
||||||
|
|
||||||
const targetTeam = targetIsPlayer ? playerTeamIds : otherTeamIds;
|
|
||||||
|
|
||||||
if (targetTeam.includes(construct.id)) return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(source || target)) return 'unfocus';
|
|
||||||
|
|
||||||
if (type === 'Ko') {
|
|
||||||
if (target) return 'ko';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === 'Damage') {
|
|
||||||
const { colour } = event;
|
|
||||||
if (target) {
|
|
||||||
construct.green_life.value = resolution.target.green;
|
|
||||||
if (colour === 'Red') {
|
|
||||||
construct.red_life.value = resolution.target.red;
|
|
||||||
return 'red-damage';
|
|
||||||
}
|
|
||||||
if (colour === 'Blue') {
|
|
||||||
construct.blue_life.value = resolution.target.blue;
|
|
||||||
return 'blue-damage';
|
|
||||||
}
|
|
||||||
if (colour === 'Green') {
|
|
||||||
construct.green_life.value = resolution.target.green;
|
|
||||||
return 'green-damage';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === 'Healing') {
|
|
||||||
if (target && postSkill) {
|
|
||||||
construct.green_life.value = resolution.target.green;
|
|
||||||
return 'green-damage';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === 'Effect') {
|
|
||||||
const { construct_effects: constructEffects } = event;
|
|
||||||
if (target && postSkill) construct.effects = constructEffects;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === 'Removal') {
|
|
||||||
const { construct_effects: constructEffects } = event;
|
|
||||||
if (target && postSkill) construct.effects = constructEffects;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === 'Recharge') {
|
|
||||||
const { red, blue } = event;
|
|
||||||
if (target && postSkill) {
|
|
||||||
if (red > 0 && blue > 0) {
|
|
||||||
construct.red_life.value = resolution.target.red;
|
|
||||||
construct.blue_life.value = resolution.target.blue;
|
|
||||||
return 'purple-damage';
|
|
||||||
}
|
|
||||||
if (red > 0) {
|
|
||||||
construct.red_life.value = resolution.target.red;
|
|
||||||
return 'red-damage';
|
|
||||||
}
|
|
||||||
if (blue > 0) {
|
|
||||||
construct.blue_life.value = resolution.target.blue;
|
|
||||||
return 'blue-damage';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
const COLOURS = [
|
const COLOURS = [
|
||||||
'#a52a2a',
|
'#a52a2a',
|
||||||
'#1FF01F',
|
'#1FF01F',
|
||||||
@ -225,7 +142,6 @@ function randomPoints(numPoints, radius, dimensions) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const removeTier = skill => {
|
const removeTier = skill => {
|
||||||
|
|
||||||
if (skill.includes('SiphonTick')) return 'SiphonTick';
|
if (skill.includes('SiphonTick')) return 'SiphonTick';
|
||||||
if (skill.includes('TriageTick')) return 'TriageTick';
|
if (skill.includes('TriageTick')) return 'TriageTick';
|
||||||
if (skill.includes('DecayTick')) return 'DecayTick';
|
if (skill.includes('DecayTick')) return 'DecayTick';
|
||||||
@ -314,7 +230,6 @@ function convertItem(v) {
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
stringSort,
|
stringSort,
|
||||||
numSort,
|
numSort,
|
||||||
eventClasses,
|
|
||||||
postData,
|
postData,
|
||||||
convertItem,
|
convertItem,
|
||||||
errorToast,
|
errorToast,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user