Grabbed dndbeyond's source code
``` ~/go/bin/sourcemapper -output ddb -jsurl https://media.dndbeyond.com/character-app/static/js/main.90aa78c5.js ```
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
import { call } from 'redux-saga/effects';
|
||||
import * as ApiAdapterUtils from '../apiAdapter/utils';
|
||||
/**
|
||||
*
|
||||
* @param apiMakeRequest
|
||||
* @param requestParams
|
||||
*/
|
||||
export function* getApiRequestData(apiMakeRequest, requestParams, apiAdapterConfig) {
|
||||
const response = yield call(sendApiRequest, apiMakeRequest, requestParams, apiAdapterConfig);
|
||||
return ApiAdapterUtils.getResponseData(response);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param apiMakeRequest
|
||||
* @param requestParams
|
||||
*/
|
||||
export function* sendApiRequest(apiMakeRequest, requestParams, apiAdapterConfig) {
|
||||
const response = yield call(apiMakeRequest, requestParams, apiAdapterConfig);
|
||||
return response;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
import { call, put, select } from 'redux-saga/effects';
|
||||
import { serviceDataActions } from '../../actions/serviceData';
|
||||
import { ApiHacks } from '../../api';
|
||||
import * as ApiAdapterUtils from '../../apiAdapter/utils';
|
||||
import { AccessTypeEnum } from '../../engine/Access';
|
||||
import { ClassAccessors } from '../../engine/Class';
|
||||
import { ClassFeatureAccessors } from '../../engine/ClassFeature';
|
||||
import { DefinitionPoolSimulators } from '../../engine/DefinitionPool';
|
||||
import { RaceAccessors } from '../../engine/Race';
|
||||
import { RacialTraitAccessors } from '../../engine/RacialTrait';
|
||||
import * as rulesEngineSelectors from '../../selectors/composite/engine';
|
||||
import { TypeScriptUtils } from '../../utils';
|
||||
/**
|
||||
*
|
||||
* same as handleLoadDefinitions but using the temporary characterService game-data requests
|
||||
*
|
||||
* @param definitionType
|
||||
* @param definitionIds
|
||||
*/
|
||||
export function* hack__handleLoadDefinitions(definitionType, definitionIds) {
|
||||
try {
|
||||
// make the requests from the definition ids
|
||||
const serviceResponse = yield call(ApiHacks.hack__characterServiceMakeGetIdsDefinitionTypeRequest(definitionType), {
|
||||
ids: definitionIds,
|
||||
});
|
||||
let responseData = ApiAdapterUtils.getResponseData(serviceResponse);
|
||||
if (responseData !== null) {
|
||||
// compile all the definition and accessType responses
|
||||
yield put(serviceDataActions.definitionPoolAdd(responseData.definitionData, responseData.accessTypes));
|
||||
}
|
||||
}
|
||||
catch (error) { }
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export function* hack__simulateOwnedDefinitionData() {
|
||||
const race = yield select(rulesEngineSelectors.getRace);
|
||||
if (race) {
|
||||
yield call(hack__simulateOwnedRacialTraitDefinitionData, race);
|
||||
}
|
||||
yield call(hack__simulateOwnedClassFeatureDefinitionData);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function* hack__simulateOwnedRacialTraitDefinitionData(race) {
|
||||
const racialTraitDefinitions = RaceAccessors.getDefinitionRacialTraits(race)
|
||||
.map((contract) => {
|
||||
var _a;
|
||||
return (_a = RacialTraitAccessors.getDefinition(contract)) !== null && _a !== void 0 ? _a : null;
|
||||
})
|
||||
.filter(TypeScriptUtils.isNotNullOrUndefined);
|
||||
const racialTraitAccessTypeLookup = DefinitionPoolSimulators.simulateAccessTypeLookup(racialTraitDefinitions, AccessTypeEnum.OWNED);
|
||||
if (racialTraitDefinitions.length) {
|
||||
yield put(serviceDataActions.definitionPoolAdd(racialTraitDefinitions, racialTraitAccessTypeLookup));
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export function* hack__simulateOwnedClassFeatureDefinitionData() {
|
||||
const classes = yield select(rulesEngineSelectors.getClasses);
|
||||
const classFeatureDefinitions = [];
|
||||
classes.forEach((charClass) => {
|
||||
ClassAccessors.getDefinitionClassFeatures(charClass).forEach((featureContract) => {
|
||||
const definition = ClassFeatureAccessors.getDefinition(featureContract);
|
||||
if (definition !== null) {
|
||||
classFeatureDefinitions.push(definition);
|
||||
}
|
||||
});
|
||||
});
|
||||
const classFeatureAccessTypeLookup = DefinitionPoolSimulators.simulateAccessTypeLookup(classFeatureDefinitions, AccessTypeEnum.OWNED);
|
||||
if (classFeatureDefinitions.length) {
|
||||
yield put(serviceDataActions.definitionPoolAdd(classFeatureDefinitions, classFeatureAccessTypeLookup));
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,6 @@
|
||||
import * as hacks from './hacks';
|
||||
import * as handlers from './handlers';
|
||||
import saga from './saga';
|
||||
export const characterSagaHacks = hacks;
|
||||
export const characterSagaHandlers = handlers;
|
||||
export const characterSaga = saga;
|
||||
@@ -0,0 +1,482 @@
|
||||
import { uniqueId } from 'lodash';
|
||||
import { call, put, select, takeEvery } from 'redux-saga/effects';
|
||||
import * as characterSelectors from "../../selectors/character";
|
||||
import * as types from '../../actions/character/actionTypes';
|
||||
import { syncTransactionActions } from '../../actions/syncTransaction';
|
||||
import * as apiShared from '../../api/requests';
|
||||
import { OverrideApiException } from '../../apiAdapter';
|
||||
import { SpellAccessors } from '../../engine/Spell';
|
||||
import { CharacterLoadingStatusEnum } from '../../reducers/constants';
|
||||
import * as characterEnvSelectors from '../../selectors/characterEnv';
|
||||
import * as syncTransactionSelectors from '../../selectors/syncTransaction';
|
||||
import * as sagaHandlers from './handlers';
|
||||
const SYNC_ACTION_LOOKUP = {
|
||||
//ACTION
|
||||
[types.CUSTOM_ACTION_CREATE]: true,
|
||||
//BACKGROUND
|
||||
[types.BACKGROUND_CHOOSE]: true,
|
||||
[types.BACKGROUND_CHOICE_SET_REQUEST]: true,
|
||||
[types.BACKGROUND_HAS_CUSTOM_SET_REQUEST]: true,
|
||||
[types.BACKGROUND_CUSTOM_SET_REQUEST]: true,
|
||||
//CHARACTER
|
||||
[types.XP_SET_REQUEST]: true,
|
||||
[types.RANDOM_NAME_REQUEST]: true,
|
||||
[types.RESTORE_LIFE]: true,
|
||||
[types.PORTRAIT_UPLOAD]: true,
|
||||
[types.CUSTOM_PROFICIENCY_CREATE]: true,
|
||||
[types.SHORT_REST]: true,
|
||||
[types.LONG_REST]: true,
|
||||
[types.STARTING_EQUIPMENT_ADD_REQUEST]: true,
|
||||
[types.STARTING_GOLD_ADD_REQUEST]: true,
|
||||
//CLASS
|
||||
[types.CLASS_ADD_REQUEST]: true,
|
||||
[types.CLASS_REMOVE_REQUEST]: true,
|
||||
[types.CLASS_LEVEL_SET_REQUEST]: true,
|
||||
//CLASS_FEATURE
|
||||
[types.CLASS_FEATURE_CHOICE_SET_REQUEST]: true,
|
||||
//CONDITION
|
||||
[types.CONDITION_ADD]: true,
|
||||
[types.CONDITION_SET]: true,
|
||||
[types.CONDITION_REMOVE]: true,
|
||||
//CONFIGURATION
|
||||
[types.ABILITY_SCORE_TYPE_SET_REQUEST]: true,
|
||||
//CORE
|
||||
[types.ACTIVE_SOURCE_CATEGORIES_SET]: true,
|
||||
[types.ACTIVE_SOURCES_SET]: true,
|
||||
[types.PREFERENCE_CHOOSE]: true,
|
||||
[types.SEND_SOCIAL_IMAGE_DATA]: true,
|
||||
//CREATURE
|
||||
[types.CREATURE_CREATE]: true,
|
||||
//FEAT
|
||||
[types.FEAT_CHOICE_SET_REQUEST]: true,
|
||||
[types.ADHOC_FEAT_CREATE]: true,
|
||||
[types.ADHOC_FEAT_REMOVE]: true,
|
||||
[types.SET_ENTITY_FEAT]: true,
|
||||
//ITEM
|
||||
[types.ITEM_CREATE]: true,
|
||||
[types.CUSTOM_ITEM_CREATE]: true,
|
||||
[types.ITEM_DESTROY]: true,
|
||||
[types.CUSTOM_ITEM_DESTROY]: true,
|
||||
//CURRENCY
|
||||
[types.CURRENCY_TRANSACTION_SET]: true,
|
||||
//OPTIONAL_FEATURES
|
||||
[types.OPTIONAL_CLASS_FEATURE_CREATE]: true,
|
||||
[types.OPTIONAL_CLASS_FEATURE_SET_REQUEST]: true,
|
||||
[types.OPTIONAL_CLASS_FEATURE_DESTROY]: true,
|
||||
[types.OPTIONAL_ORIGIN_CREATE]: true,
|
||||
[types.OPTIONAL_ORIGIN_SET_REQUEST]: true,
|
||||
[types.OPTIONAL_ORIGIN_DESTROY]: true,
|
||||
//RACE
|
||||
[types.RACE_CHOOSE]: true,
|
||||
//RACIAL_TRAIT
|
||||
[types.RACIAL_TRAIT_CHOICE_SET_REQUEST]: true,
|
||||
//SPELL
|
||||
[types.SPELL_CREATE]: true,
|
||||
[types.SPELL_REMOVE]: true,
|
||||
};
|
||||
/**
|
||||
*
|
||||
* @param action
|
||||
*/
|
||||
function isSyncAction(action) {
|
||||
return !!SYNC_ACTION_LOOKUP[action.type];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param meta
|
||||
* //TODO find a better solution for checking props on meta
|
||||
*/
|
||||
function isCommonCommitAction(meta) {
|
||||
return meta.commit !== undefined;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param meta
|
||||
* //TODO find a better solution for checking props on meta
|
||||
*/
|
||||
function isPostAction(meta) {
|
||||
return meta.postAction !== undefined;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export default function* saga() {
|
||||
yield takeEvery(Object.keys(types).map((key) => types[key]), filter);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param action
|
||||
*/
|
||||
function* filter(action) {
|
||||
var _a;
|
||||
const characterLoadingStatus = yield select(characterEnvSelectors.getLoadingStatus);
|
||||
//TODO: CanEdit
|
||||
// const isReadonly: ReturnType<typeof characterEnvSelectors.getIsReadonly> = yield select(
|
||||
// characterEnvSelectors.getIsReadonly,
|
||||
// );
|
||||
const canEdit = yield select(characterSelectors.getCanEdit);
|
||||
if (!canEdit && characterLoadingStatus === CharacterLoadingStatusEnum.LOADED) {
|
||||
return;
|
||||
}
|
||||
let transactionInitiatorId = null;
|
||||
if (action.meta) {
|
||||
transactionInitiatorId = yield call(executeSyncTransactionActivate, action);
|
||||
try {
|
||||
yield call(executeApi, action);
|
||||
yield call(executeHandler, action);
|
||||
yield call(executePostAction, action);
|
||||
yield call(executeSyncTransactionDeactivate, action, transactionInitiatorId);
|
||||
}
|
||||
catch (error) {
|
||||
if (error instanceof OverrideApiException) {
|
||||
yield call(executeSyncTransactionDeactivate, action, transactionInitiatorId);
|
||||
if ((_a = action.meta) === null || _a === void 0 ? void 0 : _a.reject) {
|
||||
action.meta.reject();
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param action
|
||||
*/
|
||||
function* executePostAction(action) {
|
||||
if (isPostAction(action.meta)) {
|
||||
for (let i = 0; i < action.meta.postAction.type.length; i++) {
|
||||
yield put({
|
||||
type: action.meta.postAction.type[i],
|
||||
payload: action.payload,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param action
|
||||
*/
|
||||
function* executeSyncTransactionActivate(action) {
|
||||
const isSyncTransactionActive = yield select(syncTransactionSelectors.getActive);
|
||||
let transactionInitiatorId = null;
|
||||
if (isSyncAction(action) && !isSyncTransactionActive) {
|
||||
transactionInitiatorId = uniqueId();
|
||||
yield put(syncTransactionActions.activate(transactionInitiatorId));
|
||||
}
|
||||
return transactionInitiatorId;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param action
|
||||
* @param transactionInitiatorId
|
||||
*/
|
||||
function* executeSyncTransactionDeactivate(action, transactionInitiatorId) {
|
||||
if (isSyncAction(action)) {
|
||||
let syncTransactionInitiator = yield select(syncTransactionSelectors.getInitiator);
|
||||
if (syncTransactionInitiator === transactionInitiatorId) {
|
||||
yield put(syncTransactionActions.deactivate());
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param action
|
||||
*/
|
||||
function* executeApi(action) {
|
||||
let apiLookup = {
|
||||
// ACTION
|
||||
[types.ACTION_USE_SET]: apiShared.putCharacterActionLimitedUse,
|
||||
[types.CUSTOM_ACTION_REMOVE]: apiShared.deleteCharacterCustomAction,
|
||||
[types.CUSTOM_ACTION_SET]: apiShared.putCharacterCustomAction,
|
||||
//CHARACTER
|
||||
[types.XP_SET]: apiShared.putCharacterProgression,
|
||||
[types.NAME_SET]: apiShared.putCharacterDescriptionName,
|
||||
[types.NOTE_SET]: apiShared.putCharacterDescriptionNotes,
|
||||
[types.TRAIT_SET]: apiShared.putCharacterDescriptionTraits,
|
||||
[types.BASE_HIT_POINTS_SET]: apiShared.putCharacterLifeHpBase,
|
||||
[types.BONUS_HIT_POINTS_SET]: apiShared.putCharacterLifeHpBonus,
|
||||
[types.OVERRIDE_HIT_POINTS_SET]: apiShared.putCharacterLifeHpOverride,
|
||||
[types.HAIR_SET]: apiShared.putCharacterDescriptionHair,
|
||||
[types.SKIN_SET]: apiShared.putCharacterDescriptionSkin,
|
||||
[types.EYES_SET]: apiShared.putCharacterDescriptionEyes,
|
||||
[types.HEIGHT_SET]: apiShared.putCharacterDescriptionHeight,
|
||||
[types.WEIGHT_SET]: apiShared.putCharacterDescriptionWeight,
|
||||
[types.AGE_SET]: apiShared.putCharacterDescriptionAge,
|
||||
[types.GENDER_SET]: apiShared.putCharacterDescriptionGender,
|
||||
[types.ALIGNMENT_SET]: apiShared.putCharacterDescriptionAlignment,
|
||||
[types.LIFESTYLE_SET]: apiShared.putCharacterDescriptionLifestyle,
|
||||
[types.FAITH_SET]: apiShared.putCharacterDescriptionFaith,
|
||||
[types.PORTRAIT_SET]: apiShared.putCharacterDecorationPortrait,
|
||||
[types.HIT_POINTS_SET]: apiShared.putCharacterLifeHpDamageTaken,
|
||||
[types.INSPIRATION_SET]: apiShared.putCharacterInspiration,
|
||||
[types.CURRENCIES_SET]: apiShared.putCharacterInventoryCurrency,
|
||||
[types.CURRENCY_COPPER_SET]: apiShared.putCharacterInventoryCurrencyCopper,
|
||||
[types.ITEM_CURRENCY_COPPER_SET]: apiShared.putCharacterInventoryCurrencyCopper,
|
||||
[types.CURRENCY_ELECTRUM_SET]: apiShared.putCharacterInventoryCurrencyElectrum,
|
||||
[types.ITEM_CURRENCY_ELECTRUM_SET]: apiShared.putCharacterInventoryCurrencyElectrum,
|
||||
[types.CURRENCY_GOLD_SET]: apiShared.putCharacterInventoryCurrencyGold,
|
||||
[types.ITEM_CURRENCY_GOLD_SET]: apiShared.putCharacterInventoryCurrencyGold,
|
||||
[types.CURRENCY_PLATINUM_SET]: apiShared.putCharacterInventoryCurrencyPlatinum,
|
||||
[types.ITEM_CURRENCY_PLATINUM_SET]: apiShared.putCharacterInventoryCurrencyPlatinum,
|
||||
[types.CURRENCY_SILVER_SET]: apiShared.putCharacterInventoryCurrencySilver,
|
||||
[types.ITEM_CURRENCY_SILVER_SET]: apiShared.putCharacterInventoryCurrencySilver,
|
||||
[types.DEATHSAVES_SET]: apiShared.putCharacterLifeDeathSaves,
|
||||
[types.MOVEMENT_ADD]: apiShared.postCharacterCustomMovement,
|
||||
[types.MOVEMENT_SET]: apiShared.putCharacterCustomMovement,
|
||||
[types.MOVEMENT_REMOVE]: apiShared.deleteCharacterCustomMovement,
|
||||
[types.SENSE_ADD]: apiShared.postCharacterCustomSense,
|
||||
[types.SENSE_SET]: apiShared.putCharacterCustomSense,
|
||||
[types.SENSE_REMOVE]: apiShared.deleteCharacterCustomSense,
|
||||
[types.CUSTOM_PROFICIENCY_REMOVE]: apiShared.deleteCharacterCustomProficiency,
|
||||
[types.CUSTOM_PROFICIENCY_SET]: apiShared.putCharacterCustomProficiency,
|
||||
[types.CUSTOM_DEFENSE_ADJUSTMENT_ADD]: apiShared.postCharacterCustomDefenseAdjustment,
|
||||
[types.CUSTOM_DEFENSE_ADJUSTMENT_SET]: apiShared.putCharacterCustomDefenseAdjustment,
|
||||
[types.CUSTOM_DEFENSE_ADJUSTMENT_REMOVE]: apiShared.deleteCharacterCustomDefenseAdjustment,
|
||||
//CORE
|
||||
[types.ACTIVE_SOURCE_CATEGORIES_SET]: apiShared.putCharacterSourceCategories,
|
||||
[types.ACTIVE_SOURCES_SET]: apiShared.putCharacterSources,
|
||||
[types.BACKDROP_SET]: apiShared.putCharacterDecorationBackdrop,
|
||||
[types.FRAME_SET]: apiShared.putCharacterDecorationFrame,
|
||||
[types.THEME_SET]: apiShared.putCharacterDecorationThemeColor,
|
||||
//CREATURE
|
||||
[types.CREATURE_REMOVE]: apiShared.deleteCharacterCreature,
|
||||
[types.CREATURE_DATA_SET]: apiShared.putCharacterCreature,
|
||||
[types.CREATURE_HIT_POINTS_SET]: apiShared.putCharacterCreatureHp,
|
||||
[types.CREATURE_ACTIVE_SET]: apiShared.putCharacterCreatureStatus,
|
||||
//ITEM
|
||||
//TODO v5.1: remove this v5 guy when mobile moves up to Custom Items
|
||||
[types.CUSTOM_ITEM_REMOVE]: apiShared.deleteCharacterCustomItemV5,
|
||||
[types.ITEM_REMOVE]: apiShared.deleteCharacterInventoryItem,
|
||||
//SPELL
|
||||
[types.SPELL_REMOVE]: apiShared.deleteCharacterSpell,
|
||||
[types.SPELL_USE_SET]: apiShared.putCharacterActionLimitedUse,
|
||||
[types.SPELL_LEVEL_SPELL_SLOTS_SET]: apiShared.putCharacterSpellSlots,
|
||||
[types.SPELL_LEVEL_PACT_MAGIC_SLOTS_SET]: apiShared.putCharacterSpellPactMagic,
|
||||
//VALUE
|
||||
[types.VALUE_SET]: apiShared.putCharacterCustomValue,
|
||||
[types.VALUE_REMOVE]: apiShared.deleteCharacterCustomValue,
|
||||
[types.ENTITY_VALUES_REMOVE]: apiShared.deleteCharacterCustomEntityValues,
|
||||
//PREMADE INFO
|
||||
[types.PREMADE_INFO_ADD]: apiShared.addPremadeInfo,
|
||||
[types.PREMADE_INFO_UPDATE]: apiShared.setPremadeInfo,
|
||||
[types.PREMADE_INFO_DELETE]: apiShared.deletePremadeInfo,
|
||||
};
|
||||
let apiPayload = action.payload;
|
||||
//transforming payloads where api payload is different from action payload
|
||||
switch (action.type) {
|
||||
//ACTION
|
||||
case types.ACTION_USE_SET: {
|
||||
const payload = {
|
||||
id: action.payload.id,
|
||||
entityTypeId: action.payload.entityTypeId,
|
||||
uses: action.payload.uses,
|
||||
};
|
||||
apiPayload = payload;
|
||||
break;
|
||||
}
|
||||
case types.CUSTOM_ACTION_SET: {
|
||||
const payload = Object.assign({ id: action.payload.id }, action.payload.properties);
|
||||
apiPayload = payload;
|
||||
break;
|
||||
}
|
||||
//CHARACTER
|
||||
case types.NOTE_SET: {
|
||||
const payload = {
|
||||
[action.payload.noteType]: action.payload.content,
|
||||
};
|
||||
apiPayload = payload;
|
||||
break;
|
||||
}
|
||||
case types.TRAIT_SET: {
|
||||
const payload = {
|
||||
[action.payload.traitType]: action.payload.content,
|
||||
};
|
||||
apiPayload = payload;
|
||||
break;
|
||||
}
|
||||
case types.DEATHSAVES_SET: {
|
||||
const payload = {
|
||||
failCount: action.payload.fails,
|
||||
successCount: action.payload.successes,
|
||||
};
|
||||
apiPayload = payload;
|
||||
break;
|
||||
}
|
||||
case types.CUSTOM_PROFICIENCY_SET: {
|
||||
const payload = Object.assign({ id: action.payload.id }, action.payload.properties);
|
||||
apiPayload = payload;
|
||||
break;
|
||||
}
|
||||
//CORE
|
||||
case types.BACKDROP_SET: {
|
||||
const { backdropAvatarId, largeBackdropAvatarId, smallBackdropAvatarId, thumbnailBackdropAvatarId } = action.payload.backdrop;
|
||||
const payload = {
|
||||
backdropAvatarId,
|
||||
largeBackdropAvatarId,
|
||||
smallBackdropAvatarId,
|
||||
thumbnailBackdropAvatarId,
|
||||
};
|
||||
apiPayload = payload;
|
||||
break;
|
||||
}
|
||||
case types.FRAME_SET: {
|
||||
const { frameAvatarId } = action.payload.frame;
|
||||
const payload = {
|
||||
frameAvatarId,
|
||||
};
|
||||
apiPayload = payload;
|
||||
break;
|
||||
}
|
||||
case types.THEME_SET: {
|
||||
const { themeColor } = action.payload;
|
||||
const payload = {
|
||||
themeColorId: themeColor ? themeColor.themeColorId : themeColor,
|
||||
};
|
||||
apiPayload = payload;
|
||||
break;
|
||||
}
|
||||
//CREATURE
|
||||
case types.CREATURE_DATA_SET: {
|
||||
const payload = Object.assign({ id: action.payload.id }, action.payload.properties);
|
||||
apiPayload = payload;
|
||||
break;
|
||||
}
|
||||
//ITEM
|
||||
case types.ITEM_CHARGES_SET: {
|
||||
const payload = {
|
||||
id: action.payload.id,
|
||||
charges: action.payload.uses,
|
||||
};
|
||||
apiPayload = payload;
|
||||
break;
|
||||
}
|
||||
//SPELL
|
||||
case types.SPELL_REMOVE: {
|
||||
const { spell, characterClassId } = action.payload;
|
||||
const payload = {
|
||||
spellId: SpellAccessors.getId(spell),
|
||||
characterClassId,
|
||||
entityTypeId: SpellAccessors.getMappingEntityTypeId(spell),
|
||||
id: SpellAccessors.getMappingId(spell),
|
||||
};
|
||||
apiPayload = payload;
|
||||
break;
|
||||
}
|
||||
case types.SPELL_USE_SET: {
|
||||
const { id, entityTypeId, uses } = action.payload;
|
||||
const payload = {
|
||||
id,
|
||||
entityTypeId,
|
||||
uses,
|
||||
};
|
||||
apiPayload = payload;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// not implemented
|
||||
}
|
||||
let apiRequest = apiLookup[action.type] ? apiLookup[action.type] : null;
|
||||
if (isCommonCommitAction(action.meta) && apiRequest !== null) {
|
||||
yield put({
|
||||
type: action.meta.commit.type,
|
||||
payload: action.payload,
|
||||
meta: {},
|
||||
});
|
||||
if (action.meta.accept) {
|
||||
action.meta.accept();
|
||||
}
|
||||
}
|
||||
if (apiRequest !== null) {
|
||||
yield call(apiRequest, apiPayload);
|
||||
}
|
||||
}
|
||||
function* executeHandler(action) {
|
||||
let handlerLookup = {
|
||||
//ACTION
|
||||
[types.ACTION_CUSTOMIZATIONS_DELETE]: sagaHandlers.handleActionCustomizationsDelete,
|
||||
[types.CUSTOM_ACTION_CREATE]: sagaHandlers.handleCustomActionCreate,
|
||||
//BACKGROUND
|
||||
[types.BACKGROUND_CHOOSE]: sagaHandlers.handleBackgroundSetRequest,
|
||||
[types.BACKGROUND_CHOICE_SET_REQUEST]: sagaHandlers.handleBackgroundChoiceSetRequest,
|
||||
[types.BACKGROUND_HAS_CUSTOM_SET_REQUEST]: sagaHandlers.handleBackgroundHasCustomSetRequest,
|
||||
[types.BACKGROUND_CUSTOM_SET_REQUEST]: sagaHandlers.handleBackgroundCustomSetRequest,
|
||||
//CAMPAIGN_SETTING
|
||||
[types.CAMPAIGN_SETTING_SET_REQUEST]: sagaHandlers.handleCampaignSettingSetRequest,
|
||||
//CHARACTER
|
||||
[types.CHARACTER_LOAD]: sagaHandlers.handleCharacterLoad,
|
||||
[types.XP_SET_REQUEST]: sagaHandlers.handleXpSetRequest,
|
||||
[types.RANDOM_NAME_REQUEST]: sagaHandlers.handleRandomNameRequest,
|
||||
[types.RESTORE_LIFE]: sagaHandlers.handleRestoreLife,
|
||||
[types.PORTRAIT_UPLOAD]: sagaHandlers.handlePortraitUpload,
|
||||
[types.CUSTOM_PROFICIENCY_CREATE]: sagaHandlers.handleCustomProficiencyCreate,
|
||||
[types.SHORT_REST]: sagaHandlers.handleShortRest,
|
||||
[types.LONG_REST]: sagaHandlers.handleLongRest,
|
||||
[types.ABILITY_SCORE_SET]: sagaHandlers.handleAbilityScoreSet,
|
||||
[types.STARTING_EQUIPMENT_ADD_REQUEST]: sagaHandlers.handleStartingEquipmentAdd,
|
||||
[types.STARTING_GOLD_ADD_REQUEST]: sagaHandlers.handleStartingGoldAdd,
|
||||
[types.LOAD_LAZY_CHARACTER_DATA]: sagaHandlers.handleLoadCharacterLazyData,
|
||||
//CLASS
|
||||
[types.CLASS_ADD_REQUEST]: sagaHandlers.handleClassAddRequest,
|
||||
[types.CLASS_REMOVE_REQUEST]: sagaHandlers.handleClassRemoveRequest,
|
||||
[types.CLASS_LEVEL_SET_REQUEST]: sagaHandlers.handleClassLevelSetRequest,
|
||||
//CLASS_FEATURE
|
||||
[types.CLASS_FEATURE_CHOICE_SET_REQUEST]: sagaHandlers.handleClassFeatureChoiceSetRequest,
|
||||
//CONDITION
|
||||
[types.CONDITION_SET]: sagaHandlers.handleConditionSet,
|
||||
[types.CONDITION_ADD]: sagaHandlers.handleConditionAdd,
|
||||
[types.CONDITION_REMOVE]: sagaHandlers.handleConditionRemove,
|
||||
//CONFIGURATION
|
||||
[types.ABILITY_SCORE_TYPE_SET_REQUEST]: sagaHandlers.handleSetAbilityScoreTypeRequest,
|
||||
[types.SHOW_HELP_TEXT_SET_REQUEST]: sagaHandlers.handleShowHelpTextSetRequest,
|
||||
[types.STARTING_EQUIPMENT_TYPE_SET]: sagaHandlers.handleStartingEquipmentTypeSet,
|
||||
//CORE
|
||||
[types.PREFERENCE_CHOOSE]: sagaHandlers.handlePreferenceChoose,
|
||||
[types.SEND_SOCIAL_IMAGE_DATA]: sagaHandlers.handleSendSocialImageData,
|
||||
//CREATURE
|
||||
[types.CREATURE_CREATE]: sagaHandlers.handleCreatureCreate,
|
||||
[types.CREATURE_CUSTOMIZATIONS_DELETE]: sagaHandlers.handleCreatureCustomizationsDelete,
|
||||
//FEAT
|
||||
[types.FEAT_CHOICE_SET_REQUEST]: sagaHandlers.handleFeatChoiceSetRequest,
|
||||
[types.ADHOC_FEAT_CREATE]: sagaHandlers.handleAdhocFeatCreate,
|
||||
[types.ADHOC_FEAT_REMOVE]: sagaHandlers.handleAdhocFeatRemove,
|
||||
[types.SET_ENTITY_FEAT]: sagaHandlers.handleSetEntityFeat,
|
||||
//ITEM
|
||||
[types.ITEM_CREATE]: sagaHandlers.handleItemCreate,
|
||||
[types.CUSTOM_ITEM_CREATE]: sagaHandlers.handleCustomItemCreate,
|
||||
[types.CUSTOM_ITEM_SET]: sagaHandlers.handleCustomItemSet,
|
||||
[types.ITEM_CUSTOMIZATIONS_DELETE]: sagaHandlers.handleItemCustomizationsDelete,
|
||||
[types.ITEM_EQUIPPED_SET]: sagaHandlers.handleItemEquippedSet,
|
||||
[types.ITEM_ATTUNE_SET]: sagaHandlers.handleItemAttuneSet,
|
||||
[types.ITEM_QUANTITY_SET]: sagaHandlers.handleItemQuantitySet,
|
||||
[types.ITEM_DESTROY]: sagaHandlers.handleItemDestroy,
|
||||
[types.CUSTOM_ITEM_DESTROY]: sagaHandlers.handleCustomItemDestroy,
|
||||
[types.ITEM_CHARGES_SET]: sagaHandlers.handleItemChargesSet,
|
||||
[types.ITEM_MOVE_SET]: sagaHandlers.handleItemMove,
|
||||
//CURRENCY
|
||||
[types.CURRENCY_TRANSACTION_SET]: sagaHandlers.handleCurrencyTransactionSet,
|
||||
//OPTIONAL_FEATURES
|
||||
[types.OPTIONAL_CLASS_FEATURE_CREATE]: sagaHandlers.handleOptionalClassFeatureCreate,
|
||||
[types.OPTIONAL_CLASS_FEATURE_SET_REQUEST]: sagaHandlers.handleOptionalClassFeatureSetRequest,
|
||||
[types.OPTIONAL_CLASS_FEATURE_DESTROY]: sagaHandlers.handleOptionalClassFeatureDestroy,
|
||||
[types.OPTIONAL_ORIGIN_CREATE]: sagaHandlers.handleOptionalOriginCreate,
|
||||
[types.OPTIONAL_ORIGIN_SET_REQUEST]: sagaHandlers.handleOptionalOriginSetRequest,
|
||||
[types.OPTIONAL_ORIGIN_DESTROY]: sagaHandlers.handleOptionalOriginDestroy,
|
||||
//RACE
|
||||
[types.RACE_CHOOSE]: sagaHandlers.handleRaceChoose,
|
||||
//RACIAL_TRAIT
|
||||
[types.RACIAL_TRAIT_CHOICE_SET_REQUEST]: sagaHandlers.handleRacialTraitChoiceSetRequest,
|
||||
//SPELL
|
||||
[types.SPELL_CREATE]: sagaHandlers.handleSpellCreate,
|
||||
[types.SPELL_REMOVE]: sagaHandlers.handleSpellRemove,
|
||||
[types.SPELL_CUSTOMIZATIONS_DELETE]: sagaHandlers.handleSpellCustomizationsDelete,
|
||||
[types.SPELL_PREPARED_SET]: sagaHandlers.handleSpellPrepareSet,
|
||||
//PREMADE INFO
|
||||
[types.PREMADE_INFO_GET]: sagaHandlers.handlePremadeInfoGet,
|
||||
};
|
||||
let handler = handlerLookup[action.type] ? handlerLookup[action.type] : null;
|
||||
if (handler !== null) {
|
||||
yield call(handler, action);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,347 @@
|
||||
import { call, put, select } from 'redux-saga/effects';
|
||||
import { characterActions, serviceDataActions } from '../../actions';
|
||||
import { ApiRequests } from '../../api';
|
||||
import * as apiShared from '../../api/requests';
|
||||
import { CampaignAccessors, PartyInventorySharingStateEnum } from '../../engine/Campaign';
|
||||
import { CreatureAccessors } from '../../engine/Creature';
|
||||
import { DefinitionAccessors, DefinitionTypeEnum, DefinitionUtils } from '../../engine/Definition';
|
||||
import { DefinitionPoolUtils } from '../../engine/DefinitionPool';
|
||||
import { FeatureFlagEnum, FeatureFlagInfoUtils } from '../../engine/FeatureFlagInfo';
|
||||
import { HelperUtils } from '../../engine/Helper';
|
||||
import { InfusionAccessors, InfusionTypeEnum } from '../../engine/Infusion';
|
||||
import { InfusionChoiceAccessors } from '../../engine/InfusionChoice';
|
||||
import { ItemAccessors, ItemUtils } from '../../engine/Item';
|
||||
import { KnownInfusionAccessors } from '../../engine/KnownInfusion';
|
||||
import { ValueAccessors } from '../../engine/Value';
|
||||
import { VehicleAccessors, VehicleSimulators } from '../../engine/Vehicle';
|
||||
import { VehicleComponentAccessors } from '../../engine/VehicleComponent';
|
||||
import { initialCoinState } from '../../reducers/character';
|
||||
import * as SagaHelpers from '../../sagas/SagaHelpers';
|
||||
import { characterSelectors, featureFlagInfoSelectors, rulesEngineSelectors, serviceDataSelectors, } from '../../selectors';
|
||||
import { TypeScriptUtils } from '../../utils';
|
||||
import { callCommitAction } from '../../utils/ReduxActionUtils';
|
||||
import { apiCreatureCreate, apiItemsCreate, handleLoadDefinitions } from '../character/handlers';
|
||||
/**
|
||||
*
|
||||
* @param action
|
||||
*/
|
||||
export function* handleKnownInfusionCreate(action) {
|
||||
const newKnownInfusionMapping = yield call(SagaHelpers.getApiRequestData, apiShared.postCharacterKnownInfusion, action.payload);
|
||||
yield put(callCommitAction(serviceDataActions.knownInfusionMappingAdd, newKnownInfusionMapping));
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param action
|
||||
*/
|
||||
export function* handleKnownInfusionDestroy(action) {
|
||||
const choiceKey = action.payload.choiceKey;
|
||||
const knownInfusionLookup = yield select(rulesEngineSelectors.getKnownInfusionLookupByChoiceKey);
|
||||
const knownInfusion = HelperUtils.lookupDataOrFallback(knownInfusionLookup, choiceKey);
|
||||
if (knownInfusion) {
|
||||
const infusionChoiceInfusionLookup = yield select(rulesEngineSelectors.getInfusionChoiceInfusionLookup);
|
||||
const infusion = HelperUtils.lookupDataOrFallback(infusionChoiceInfusionLookup, choiceKey);
|
||||
if (infusion) {
|
||||
const infusionId = InfusionAccessors.getId(infusion);
|
||||
if (infusionId !== null) {
|
||||
yield call(handleInfusionDestroy, serviceDataActions.infusionMappingDestroy(infusionId, InfusionAccessors.getInventoryMappingId(infusion)));
|
||||
}
|
||||
}
|
||||
}
|
||||
const responseData = yield call(SagaHelpers.getApiRequestData, apiShared.deleteCharacterKnownInfusion, action.payload);
|
||||
yield put(callCommitAction(serviceDataActions.knownInfusionMappingRemove, action.payload.choiceKey));
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param action
|
||||
*/
|
||||
export function* handleInfusionCreate(action) {
|
||||
const infusionId = action.payload.infusionId;
|
||||
const choiceKey = action.payload.choiceKey;
|
||||
const choiceLookup = yield select(rulesEngineSelectors.getInfusionChoiceLookup);
|
||||
if (choiceKey === null) {
|
||||
return;
|
||||
}
|
||||
const infusionChoice = HelperUtils.lookupDataOrFallback(choiceLookup, choiceKey);
|
||||
if (infusionChoice === null) {
|
||||
return;
|
||||
}
|
||||
const knownInfusion = InfusionChoiceAccessors.getKnownInfusion(infusionChoice);
|
||||
if (knownInfusion === null) {
|
||||
return;
|
||||
}
|
||||
const simulatedInfusion = KnownInfusionAccessors.getSimulatedInfusion(knownInfusion);
|
||||
if (simulatedInfusion === null) {
|
||||
return;
|
||||
}
|
||||
let infusionInventoryMappingId = action.payload.inventoryMappingId;
|
||||
let itemId = null;
|
||||
let itemEntityTypeId = null;
|
||||
let containerEntityId = null;
|
||||
let containerEntityTypeId = null;
|
||||
if (action.payload.itemId && action.payload.itemTypeId) {
|
||||
itemId = action.payload.itemId;
|
||||
itemEntityTypeId = action.payload.itemTypeId;
|
||||
}
|
||||
if (action.payload.containerEntityId && action.payload.containerEntityTypeId) {
|
||||
containerEntityId = action.payload.containerEntityId;
|
||||
containerEntityTypeId = action.payload.containerEntityTypeId;
|
||||
}
|
||||
if (itemId !== null && itemEntityTypeId !== null) {
|
||||
const addedItems = yield call(apiItemsCreate, {
|
||||
equipment: [
|
||||
{
|
||||
containerEntityId,
|
||||
containerEntityTypeId,
|
||||
entityId: itemId,
|
||||
entityTypeId: itemEntityTypeId,
|
||||
quantity: 1,
|
||||
},
|
||||
],
|
||||
});
|
||||
infusionInventoryMappingId = addedItems[0].id;
|
||||
}
|
||||
let creatureMappingId = null;
|
||||
if (InfusionAccessors.getType(simulatedInfusion) === InfusionTypeEnum.CREATURE) {
|
||||
const creatureData = InfusionAccessors.getCreatureData(simulatedInfusion);
|
||||
if (creatureData && creatureData.length) {
|
||||
// Hardcoded to first entry until we adjust data to allow for more than 1 monster
|
||||
const apiPayload = {
|
||||
groupId: creatureData[0].creatureGroupId,
|
||||
monsterId: creatureData[0].monsterId,
|
||||
names: [null],
|
||||
};
|
||||
const addedCreatures = yield call(apiCreatureCreate, apiPayload);
|
||||
creatureMappingId = CreatureAccessors.getMappingId(addedCreatures[0]);
|
||||
}
|
||||
}
|
||||
if (infusionInventoryMappingId === null) {
|
||||
return;
|
||||
}
|
||||
const payload = {
|
||||
infusionId,
|
||||
inventoryMappingId: infusionInventoryMappingId,
|
||||
creatureMappingId,
|
||||
modifierGroupId: action.payload.modifierGroupId,
|
||||
choiceKey,
|
||||
};
|
||||
const infusionResponseData = yield call(SagaHelpers.getApiRequestData, apiShared.postCharacterInfusion, payload);
|
||||
yield put(callCommitAction(serviceDataActions.infusionMappingAdd, infusionResponseData));
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param action
|
||||
*/
|
||||
export function* handleInfusionsDestroy(action) {
|
||||
const { ids } = action.payload;
|
||||
const inventoryLookup = yield select(rulesEngineSelectors.getInventoryLookup);
|
||||
for (let i = 0; i < ids.length; i++) {
|
||||
const foundItem = HelperUtils.lookupDataOrFallback(inventoryLookup, ids[i]);
|
||||
if (foundItem) {
|
||||
const infusion = ItemAccessors.getInfusion(foundItem);
|
||||
if (infusion) {
|
||||
const infusionId = InfusionAccessors.getId(infusion);
|
||||
if (infusionId !== null) {
|
||||
yield put(serviceDataActions.infusionMappingDestroy(infusionId, ids[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param action
|
||||
*/
|
||||
export function* handleInfusionDestroy(action) {
|
||||
const inventoryInfusionLookup = yield select(rulesEngineSelectors.getInventoryInfusionLookup);
|
||||
// If this handler gets anymore complicated, come back and rethink these saga flows
|
||||
const foundInfusion = HelperUtils.lookupDataOrFallback(inventoryInfusionLookup, action.payload.inventoryMappingId);
|
||||
if (foundInfusion) {
|
||||
const infusionType = InfusionAccessors.getType(foundInfusion);
|
||||
const creatureMappingId = InfusionAccessors.getCreatureMappingId(foundInfusion);
|
||||
if (infusionType === InfusionTypeEnum.CREATURE && creatureMappingId !== null) {
|
||||
yield put(characterActions.creatureRemove(creatureMappingId));
|
||||
}
|
||||
const inventoryMappingId = InfusionAccessors.getInventoryMappingId(foundInfusion);
|
||||
//if infused item is a REPLICATE type remove the item from inventory
|
||||
//otherwise leave the item but un-attune and reset charges
|
||||
if (infusionType === InfusionTypeEnum.REPLICATE && inventoryMappingId !== null) {
|
||||
yield put(characterActions.itemRemove(inventoryMappingId, true));
|
||||
// Mapping was removed on the backend due to being an item
|
||||
// Only call commit action to mirror backend
|
||||
yield put(callCommitAction(serviceDataActions.infusionMappingRemove, action.payload.infusionId, action.payload.inventoryMappingId));
|
||||
}
|
||||
else {
|
||||
const inventoryLookup = yield select(rulesEngineSelectors.getInventoryLookup);
|
||||
const foundItem = HelperUtils.lookupDataOrFallback(inventoryLookup, action.payload.inventoryMappingId);
|
||||
if (foundItem) {
|
||||
if (ItemAccessors.isAttuned(foundItem)) {
|
||||
yield put(characterActions.itemAttuneSet(inventoryMappingId, false));
|
||||
}
|
||||
const limitedUse = ItemAccessors.getLimitedUse(foundItem);
|
||||
if (limitedUse !== null) {
|
||||
// TODO IMS Infusions come back here and switch this out
|
||||
yield put(characterActions.itemChargesSet(ItemAccessors.getMappingId(foundItem), 0));
|
||||
}
|
||||
}
|
||||
yield put(serviceDataActions.infusionMappingRemove(action.payload.infusionId, action.payload.inventoryMappingId));
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param action
|
||||
*/
|
||||
export function* handleVehicleCreate(action) {
|
||||
const data = yield call(SagaHelpers.getApiRequestData, apiShared.postCharacterVehicle, action.payload);
|
||||
let newVehicleMapping = data;
|
||||
yield put(callCommitAction(serviceDataActions.vehicleMappingAdd, newVehicleMapping));
|
||||
let definitionPool = yield select(serviceDataSelectors.getDefinitionPool);
|
||||
let ruleData = yield select(rulesEngineSelectors.getRuleData);
|
||||
let definitionKey = VehicleAccessors.getDefinitionKey(newVehicleMapping);
|
||||
if (definitionKey === null) {
|
||||
return;
|
||||
}
|
||||
let vehicleDefinition = DefinitionPoolUtils.getVehicleDefinition(definitionKey, definitionPool);
|
||||
if (vehicleDefinition === null) {
|
||||
return;
|
||||
}
|
||||
let simulatedVehicle = VehicleSimulators.simulateVehicle(vehicleDefinition, definitionPool, ruleData);
|
||||
if (simulatedVehicle === null) {
|
||||
return;
|
||||
}
|
||||
let vehicleComponents = VehicleAccessors.getDefinitionComponents(simulatedVehicle);
|
||||
let componentIds = vehicleComponents
|
||||
.map((component) => DefinitionUtils.getDefinitionKeyId(DefinitionAccessors.getDefinitionKey(component)))
|
||||
.filter(TypeScriptUtils.isNotNullOrUndefined);
|
||||
const componentsData = yield call(SagaHelpers.getApiRequestData, apiShared.postCharacterVehicleComponent, {
|
||||
vehicleMappingId: VehicleAccessors.getMappingId(newVehicleMapping),
|
||||
componentIds,
|
||||
});
|
||||
const componentMappings = componentsData;
|
||||
for (let i = 0; i < componentMappings.length; i++) {
|
||||
let componentMapping = componentMappings[i];
|
||||
yield put(callCommitAction(serviceDataActions.vehicleComponentMappingAdd, componentMapping));
|
||||
}
|
||||
if (action.meta.accept) {
|
||||
action.meta.accept();
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param action
|
||||
*/
|
||||
export function* handleVehicleRemove(action) {
|
||||
const vehicles = yield select(rulesEngineSelectors.getVehicles);
|
||||
const responseData = yield call(SagaHelpers.getApiRequestData, apiShared.deleteCharacterVehicle, action.payload);
|
||||
let vehicle = vehicles.find((vehicle) => VehicleAccessors.getMappingId(vehicle) === action.payload.id);
|
||||
if (vehicle) {
|
||||
let vehicleComponents = VehicleAccessors.getAllComponentsData(vehicle);
|
||||
yield put(callCommitAction(serviceDataActions.vehicleMappingRemove, action.payload.id));
|
||||
for (let i = 0; i < vehicleComponents.length; i++) {
|
||||
yield put(callCommitAction(serviceDataActions.vehicleComponentMappingRemove, VehicleComponentAccessors.getMappingId(vehicleComponents[i])));
|
||||
}
|
||||
}
|
||||
}
|
||||
export function* handlePartyInventoryRequest(action) {
|
||||
var _a, _b, _c, _d, _e, _f;
|
||||
const featureFlagInfo = yield select(featureFlagInfoSelectors.getFeatureFlagInfo);
|
||||
const partyFlag = FeatureFlagInfoUtils.getFeatureFlagInfoValue(FeatureFlagEnum.RELEASE_GATE_IMS, featureFlagInfo);
|
||||
// Party Inventory
|
||||
if (partyFlag) {
|
||||
const campaignInfo = yield select(characterSelectors.getCampaign);
|
||||
if (campaignInfo) {
|
||||
const data = yield call(SagaHelpers.getApiRequestData, apiShared.getPartyInventory, { campaignId: CampaignAccessors.getId(campaignInfo) });
|
||||
// This sets the data in the serviceData.partyInfo state
|
||||
yield put(serviceDataActions.partyCampaignInfoSet(Object.assign(Object.assign({}, campaignInfo), { sharingState: (_a = data === null || data === void 0 ? void 0 : data.sharingState) !== null && _a !== void 0 ? _a : PartyInventorySharingStateEnum.OFF, partyInventory: (_b = data === null || data === void 0 ? void 0 : data.partyItems) !== null && _b !== void 0 ? _b : [], spells: (_c = data === null || data === void 0 ? void 0 : data.spells) !== null && _c !== void 0 ? _c : null, modifiers: (_d = data === null || data === void 0 ? void 0 : data.modifiers) !== null && _d !== void 0 ? _d : null, coin: (_e = data === null || data === void 0 ? void 0 : data.currency) !== null && _e !== void 0 ? _e : initialCoinState })));
|
||||
yield call(handleUpdatePartyInventoryValues, data);
|
||||
// Party infusions set into serviceData
|
||||
if ((_f = data.partyInfusions) === null || _f === void 0 ? void 0 : _f.length) {
|
||||
let infusionDefinitionIds = new Set();
|
||||
for (let i = 0; i < data.partyInfusions.length; i++) {
|
||||
const mapping = data.partyInfusions[i];
|
||||
yield put(callCommitAction(serviceDataActions.infusionMappingAdd, mapping));
|
||||
const definitionKey = InfusionAccessors.getDefinitionKey(mapping);
|
||||
if (definitionKey !== null) {
|
||||
infusionDefinitionIds.add(DefinitionUtils.getDefinitionKeyId(definitionKey));
|
||||
}
|
||||
}
|
||||
if (infusionDefinitionIds.size > 0) {
|
||||
yield call(handleLoadDefinitions, DefinitionTypeEnum.INFUSION, Array.from(infusionDefinitionIds));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function* handleUpdatePartyInventoryValues(data) {
|
||||
if (data === null || data === void 0 ? void 0 : data.partyValues) {
|
||||
for (let i = 0; i < data.partyValues.length; i++) {
|
||||
const valueContract = data.partyValues[i];
|
||||
yield put(callCommitAction(characterActions.valueSet, ValueAccessors.getTypeId(valueContract), ValueAccessors.getValue(valueContract), ValueAccessors.getNotes(valueContract), ValueAccessors.getValueId(valueContract), ValueAccessors.getValueTypeId(valueContract), ValueAccessors.getContextId(valueContract), ValueAccessors.getContextTypeId(valueContract)));
|
||||
}
|
||||
const characterValueLookupByEntity = yield select(characterSelectors.getCharacterValueLookupByEntity);
|
||||
const characterValueLookup = yield select(characterSelectors.getCharacterValueLookup);
|
||||
const partyItemValuesContracts = ItemUtils.getInventoryValuesMappings(characterValueLookupByEntity, data.partyItems);
|
||||
const currentPartyItemValueKeys = partyItemValuesContracts.map((value) => ValueAccessors.getUniqueKey(value));
|
||||
const newPartyItemValueKeys = data.partyValues.map((value) => ValueAccessors.getUniqueKey(value));
|
||||
for (let i = 0; i < currentPartyItemValueKeys.length; i++) {
|
||||
const valueContractKey = currentPartyItemValueKeys[i];
|
||||
const valueContract = HelperUtils.lookupDataOrFallback(characterValueLookup, valueContractKey);
|
||||
if (valueContract && !newPartyItemValueKeys.includes(currentPartyItemValueKeys[i])) {
|
||||
yield put(callCommitAction(characterActions.valueRemove, valueContract.typeId, valueContract.valueId, valueContract.valueTypeId, valueContract.contextId, valueContract.contextTypeId));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
export function* handlePartyCurrencyCopperSet(action) {
|
||||
const data = yield call(SagaHelpers.getApiRequestData, ApiRequests.putCharacterInventoryCurrencyCopper, action.payload);
|
||||
if (data) {
|
||||
yield call(handlePartyCoinUpdate, data, action.payload.destinationEntityId);
|
||||
if (action.meta.accept) {
|
||||
action.meta.accept();
|
||||
}
|
||||
}
|
||||
}
|
||||
export function* handlePartyCurrencySilverSet(action) {
|
||||
const data = yield call(SagaHelpers.getApiRequestData, ApiRequests.putCharacterInventoryCurrencySilver, action.payload);
|
||||
if (data) {
|
||||
yield call(handlePartyCoinUpdate, data, action.payload.destinationEntityId);
|
||||
if (action.meta.accept) {
|
||||
action.meta.accept();
|
||||
}
|
||||
}
|
||||
}
|
||||
export function* handlePartyCurrencyElectrumSet(action) {
|
||||
const data = yield call(SagaHelpers.getApiRequestData, ApiRequests.putCharacterInventoryCurrencyElectrum, action.payload);
|
||||
if (data) {
|
||||
yield call(handlePartyCoinUpdate, data, action.payload.destinationEntityId);
|
||||
if (action.meta.accept) {
|
||||
action.meta.accept();
|
||||
}
|
||||
}
|
||||
}
|
||||
export function* handlePartyCurrencyPlatinumSet(action) {
|
||||
const data = yield call(SagaHelpers.getApiRequestData, ApiRequests.putCharacterInventoryCurrencyPlatinum, action.payload);
|
||||
if (data) {
|
||||
yield call(handlePartyCoinUpdate, data, action.payload.destinationEntityId);
|
||||
if (action.meta.accept) {
|
||||
action.meta.accept();
|
||||
}
|
||||
}
|
||||
}
|
||||
export function* handlePartyCurrencyGoldSet(action) {
|
||||
const data = yield call(SagaHelpers.getApiRequestData, ApiRequests.putCharacterInventoryCurrencyGold, action.payload);
|
||||
if (data) {
|
||||
yield call(handlePartyCoinUpdate, data, action.payload.destinationEntityId);
|
||||
if (action.meta.accept) {
|
||||
action.meta.accept();
|
||||
}
|
||||
}
|
||||
}
|
||||
function* handlePartyCoinUpdate(data, destinationEntityId) {
|
||||
if (destinationEntityId) {
|
||||
yield put(callCommitAction(serviceDataActions.partyItemCurrencySet, data, destinationEntityId));
|
||||
}
|
||||
else {
|
||||
yield put(callCommitAction(serviceDataActions.partyCurrenciesSet, data));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import * as handlers from './handlers';
|
||||
import saga from './saga';
|
||||
export const serviceDataSagaHandlers = handlers;
|
||||
export const serviceDataSaga = saga;
|
||||
@@ -0,0 +1,240 @@
|
||||
var __rest = (this && this.__rest) || function (s, e) {
|
||||
var t = {};
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||
t[p] = s[p];
|
||||
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
||||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
import { uniqueId } from 'lodash';
|
||||
import { call, put, select, takeEvery } from 'redux-saga/effects';
|
||||
import * as characterSelectors from "../../selectors/character";
|
||||
import * as types from '../../actions/serviceData/actionTypes';
|
||||
import { syncTransactionActions } from '../../actions/syncTransaction';
|
||||
import * as apiShared from '../../api/requests';
|
||||
import { OverrideApiException } from '../../apiAdapter';
|
||||
import { CharacterLoadingStatusEnum } from '../../reducers/constants';
|
||||
import * as characterEnvSelectors from '../../selectors/characterEnv';
|
||||
import * as syncTransactionSelectors from '../../selectors/syncTransaction';
|
||||
import { characterSagaHandlers } from '../character';
|
||||
import * as sagaHandlers from './handlers';
|
||||
const SYNC_ACTION_LOOKUP = {
|
||||
//KNOWN_INFUSION
|
||||
[types.KNOWN_INFUSION_MAPPING_CREATE]: true,
|
||||
[types.KNOWN_INFUSION_MAPPING_DESTROY]: true,
|
||||
//INFUSION
|
||||
[types.INFUSION_MAPPING_CREATE]: true,
|
||||
[types.INFUSION_MAPPING_DESTROY]: true,
|
||||
//VEHICLE
|
||||
[types.VEHICLE_MAPPING_CREATE]: true,
|
||||
};
|
||||
/**
|
||||
*
|
||||
* @param action
|
||||
*/
|
||||
function isSyncAction(action) {
|
||||
return !!SYNC_ACTION_LOOKUP[action.type];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param meta
|
||||
* //TODO find a better solution for checking props on meta
|
||||
*/
|
||||
function isCommonCommitAction(meta) {
|
||||
return meta.commit !== undefined;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param meta
|
||||
* //TODO find a better solution for checking props on meta
|
||||
*/
|
||||
function isPostAction(meta) {
|
||||
return meta.postAction !== undefined;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export default function* saga() {
|
||||
yield takeEvery(Object.keys(types).map((key) => types[key]), filter);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param action
|
||||
*/
|
||||
function* filter(action) {
|
||||
var _a;
|
||||
const characterLoadingStatus = yield select(characterEnvSelectors.getLoadingStatus);
|
||||
const canEdit = yield select(characterSelectors.getCanEdit);
|
||||
if (!canEdit && characterLoadingStatus === CharacterLoadingStatusEnum.LOADED) {
|
||||
return;
|
||||
}
|
||||
let transactionInitiatorId = null;
|
||||
if (action.meta) {
|
||||
transactionInitiatorId = yield call(executeSyncTransactionActivate, action);
|
||||
try {
|
||||
yield call(executeApi, action);
|
||||
yield call(executeHandler, action);
|
||||
yield call(executePostAction, action);
|
||||
yield call(executeSyncTransactionDeactivate, action, transactionInitiatorId);
|
||||
}
|
||||
catch (error) {
|
||||
if (error instanceof OverrideApiException) {
|
||||
yield call(executeSyncTransactionDeactivate, action, transactionInitiatorId);
|
||||
if ((_a = action.meta) === null || _a === void 0 ? void 0 : _a.reject) {
|
||||
action.meta.reject();
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param action
|
||||
*/
|
||||
function* executePostAction(action) {
|
||||
if (isPostAction(action.meta)) {
|
||||
for (let i = 0; i < action.meta.postAction.type.length; i++) {
|
||||
yield put({
|
||||
type: action.meta.postAction.type[i],
|
||||
payload: action.payload,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param action
|
||||
*/
|
||||
function* executeSyncTransactionActivate(action) {
|
||||
const isSyncTransactionActive = yield select(syncTransactionSelectors.getActive);
|
||||
let transactionInitiatorId = null;
|
||||
if (isSyncAction(action) && !isSyncTransactionActive) {
|
||||
transactionInitiatorId = uniqueId();
|
||||
yield put(syncTransactionActions.activate(transactionInitiatorId));
|
||||
}
|
||||
return transactionInitiatorId;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param action
|
||||
* @param transactionInitiatorId
|
||||
*/
|
||||
function* executeSyncTransactionDeactivate(action, transactionInitiatorId) {
|
||||
if (isSyncAction(action)) {
|
||||
let syncTransactionInitiator = yield select(syncTransactionSelectors.getInitiator);
|
||||
if (syncTransactionInitiator === transactionInitiatorId) {
|
||||
yield put(syncTransactionActions.deactivate());
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param action
|
||||
*/
|
||||
function* executeApi(action) {
|
||||
let apiLookup = {
|
||||
//KNOWN_INFUSION
|
||||
[types.KNOWN_INFUSION_MAPPING_SET]: apiShared.putCharacterKnownInfusion,
|
||||
[types.KNOWN_INFUSION_MAPPING_REMOVE]: apiShared.deleteCharacterKnownInfusion,
|
||||
//INFUSION
|
||||
[types.INFUSION_MAPPING_REMOVE]: apiShared.deleteCharacterInfusion,
|
||||
//VEHICLE_COMPONENT
|
||||
[types.VEHICLE_COMPONENT_MAPPING_HIT_POINTS_SET]: apiShared.putCharacterVehicleComponentHp,
|
||||
//VEHICLE
|
||||
[types.VEHICLE_MAPPING_DATA_SET]: apiShared.putCharacterVehicle,
|
||||
[types.VEHICLE_MAPPING_CONDITION_REMOVE]: apiShared.deleteCharacterVehicleCondition,
|
||||
[types.VEHICLE_MAPPING_CONDITION_ADD]: apiShared.postCharacterVehicleCondition,
|
||||
[types.VEHICLE_MAPPING_CONDITION_SET]: apiShared.putCharacterVehicleCondition,
|
||||
[types.VEHICLE_MAPPING_REMAINING_FUEL_SET]: apiShared.putCharacterVehicleFuel,
|
||||
//PARTY_ITEM
|
||||
[types.PARTY_ITEM_REMOVE]: apiShared.deleteCharacterInventoryItem,
|
||||
};
|
||||
let apiPayload = action.payload;
|
||||
//transforming payloads where api payload is different from action payload
|
||||
switch (action.type) {
|
||||
//KNOWN_INFUSION
|
||||
case types.KNOWN_INFUSION_MAPPING_SET: {
|
||||
const _a = action.payload, { definitionKey } = _a, knownInfusionSetPayload = __rest(_a, ["definitionKey"]);
|
||||
const payload = knownInfusionSetPayload;
|
||||
apiPayload = payload;
|
||||
break;
|
||||
}
|
||||
//VEHICLE
|
||||
case types.VEHICLE_MAPPING_DATA_SET: {
|
||||
const payload = Object.assign({ id: action.payload.id }, action.payload.properties);
|
||||
apiPayload = payload;
|
||||
break;
|
||||
}
|
||||
case types.VEHICLE_MAPPING_REMAINING_FUEL_SET: {
|
||||
const payload = {
|
||||
id: action.payload.vehicleMappingId,
|
||||
remainingFuel: action.payload.remainingFuel,
|
||||
};
|
||||
apiPayload = payload;
|
||||
break;
|
||||
}
|
||||
case types.VEHICLE_MAPPING_CONDITION_SET: {
|
||||
const payload = Object.assign({ vehicleMappingId: action.payload.vehicleMappingId }, action.payload.mappingContract);
|
||||
apiPayload = payload;
|
||||
break;
|
||||
}
|
||||
case types.VEHICLE_MAPPING_CONDITION_ADD: {
|
||||
const payload = Object.assign({ vehicleMappingId: action.payload.vehicleMappingId }, action.payload.mappingContract);
|
||||
apiPayload = payload;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// not implemented
|
||||
}
|
||||
let apiRequest = apiLookup[action.type] ? apiLookup[action.type] : null;
|
||||
if (isCommonCommitAction(action.meta)) {
|
||||
yield put({
|
||||
type: action.meta.commit.type,
|
||||
payload: action.payload,
|
||||
meta: {},
|
||||
});
|
||||
if (apiRequest !== null && action.meta.accept) {
|
||||
action.meta.accept();
|
||||
}
|
||||
}
|
||||
if (apiRequest !== null) {
|
||||
yield call(apiRequest, apiPayload);
|
||||
}
|
||||
}
|
||||
function* executeHandler(action) {
|
||||
let handlerLookup = {
|
||||
//KNOWN_INFUSION
|
||||
[types.KNOWN_INFUSION_MAPPING_CREATE]: sagaHandlers.handleKnownInfusionCreate,
|
||||
[types.KNOWN_INFUSION_MAPPING_DESTROY]: sagaHandlers.handleKnownInfusionDestroy,
|
||||
//INFUSION
|
||||
[types.INFUSION_MAPPING_CREATE]: sagaHandlers.handleInfusionCreate,
|
||||
[types.INFUSION_MAPPING_DESTROY]: sagaHandlers.handleInfusionDestroy,
|
||||
[types.INFUSION_MAPPINGS_DESTROY]: sagaHandlers.handleInfusionsDestroy,
|
||||
//VEHICLE
|
||||
[types.VEHICLE_MAPPING_CREATE]: sagaHandlers.handleVehicleCreate,
|
||||
[types.VEHICLE_MAPPING_REMOVE]: sagaHandlers.handleVehicleRemove,
|
||||
//PARTY INVENTORY
|
||||
[types.PARTY_INVENTORY_REQUEST]: sagaHandlers.handlePartyInventoryRequest,
|
||||
[types.PARTY_CURRENCY_TRANSACTION_SET]: characterSagaHandlers.handleCurrencyTransactionSet,
|
||||
[types.PARTY_CURRENCY_COPPER_SET]: sagaHandlers.handlePartyCurrencyCopperSet,
|
||||
[types.PARTY_CURRENCY_ELECTRUM_SET]: sagaHandlers.handlePartyCurrencyElectrumSet,
|
||||
[types.PARTY_CURRENCY_GOLD_SET]: sagaHandlers.handlePartyCurrencyGoldSet,
|
||||
[types.PARTY_CURRENCY_PLATINUM_SET]: sagaHandlers.handlePartyCurrencyPlatinumSet,
|
||||
[types.PARTY_CURRENCY_SILVER_SET]: sagaHandlers.handlePartyCurrencySilverSet,
|
||||
[types.PARTY_ITEM_CURRENCY_COPPER_SET]: sagaHandlers.handlePartyCurrencyCopperSet,
|
||||
[types.PARTY_ITEM_CURRENCY_ELECTRUM_SET]: sagaHandlers.handlePartyCurrencyElectrumSet,
|
||||
[types.PARTY_ITEM_CURRENCY_GOLD_SET]: sagaHandlers.handlePartyCurrencyGoldSet,
|
||||
[types.PARTY_ITEM_CURRENCY_PLATINUM_SET]: sagaHandlers.handlePartyCurrencyPlatinumSet,
|
||||
[types.PARTY_ITEM_CURRENCY_SILVER_SET]: sagaHandlers.handlePartyCurrencySilverSet,
|
||||
};
|
||||
let handler = handlerLookup[action.type] ? handlerLookup[action.type] : null;
|
||||
if (handler !== null) {
|
||||
yield call(handler, action);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user