docs: add more inline documentation

This commit is contained in:
Lukas Obermann
2023-10-03 15:40:31 +02:00
parent 01c0fe2e6b
commit 5119b3ce44
19 changed files with 228 additions and 0 deletions
+3
View File
@@ -23,6 +23,9 @@ get()
})
.catch(() => {})
/**
* The complate database content.
*/
export type Database = {
raw: Awaited<ReturnType<typeof getAllValidData>>
cache: Awaited<ReturnType<typeof getCache>>
+3
View File
@@ -11,6 +11,9 @@ const debug = Debug("main:main")
let mainWindow: BrowserWindow | undefined = undefined
/**
* Creates the main window with the loaded database and returns its instance.
*/
export const createMainWindow = async (database: Database) => {
if (mainWindow === undefined) {
debug("Create Window ...")
+13
View File
@@ -3,6 +3,9 @@ import { Theme } from "../shared/settings/GlobalSettings.ts"
import { getGlobalSettings } from "../shared/settings/main.ts"
import { assertExhaustive } from "../shared/utils/typeSafety.ts"
/**
* Sets the native theme for the application.
*/
export const setNativeTheme = (theme: Theme | undefined) => {
switch (theme) {
case Theme.Dark:
@@ -22,6 +25,9 @@ export const setNativeTheme = (theme: Theme | undefined) => {
const DARK = "#111111"
const LIGHT = "#f0f0f0"
/**
* Returns the background color for each window based on the theme.
*/
export const getWindowBackgroundColor = (theme: Theme | undefined) => {
switch (theme) {
case Theme.Dark:
@@ -35,6 +41,9 @@ export const getWindowBackgroundColor = (theme: Theme | undefined) => {
}
}
/**
* Sets the background color for all windows based on the theme.
*/
export const setBackgroundColorForAllWindows = (theme: Theme | undefined) => {
const color = getWindowBackgroundColor(theme)
@@ -43,6 +52,10 @@ export const setBackgroundColorForAllWindows = (theme: Theme | undefined) => {
})
}
/**
* Attaches a listener to native theme changes that updates all windows on each
* change.
*/
export const handleNativeThemeChanges = () => {
nativeTheme.on("updated", () => {
setBackgroundColorForAllWindows(getGlobalSettings().theme)
+4
View File
@@ -15,6 +15,10 @@ const debug = Debug("main:settings")
let settingsWindow: BrowserWindow | undefined = undefined
/**
* Creates the settings window with the loaded database and a handler that gets
* called then the locale is changed and returns its instance.
*/
export const createSettingsWindow = async (
database: Database,
onLocaleChanged: (newLocale: string | undefined) => void,
+8
View File
@@ -147,6 +147,10 @@ const prepareUpdaterWindowForAvailableUpdate = (
})
}
/**
* Checks for updates on startup and returns a `Promise` that resolves to `true`
* if an update is available.
*/
export const checkForUpdatesOnStartup = async (database: Database) => {
debug("checking for updates ...")
@@ -172,6 +176,10 @@ export const checkForUpdatesOnStartup = async (database: Database) => {
}
}
/**
* Checks for updates when the user manually requests to and returns a `Promise`
* that resolves to `true` if an update is available.
*/
export const checkForUpdatesOnRequest = async (database: Database) => {
debug("checking for updates ...")
const updaterWindow = await createUpdaterWindow(database)
+3
View File
@@ -2,4 +2,7 @@ import { PreloadAPI } from "../main_window_preload/index.ts"
type EnhancedWindow = Window & typeof globalThis & { optolith: PreloadAPI }
/**
* The external API for the main window.
*/
export const ExternalAPI = (window as EnhancedWindow).optolith
+4
View File
@@ -7,6 +7,10 @@ import {
import { selectPublications } from "../slices/databaseSlice.ts"
import { useAppSelector } from "./redux.ts"
/**
* Returns a function that checks if a given entry is available based on the
* enabled publications.
*/
export const useIsEntryAvailable = () => {
const publications = useAppSelector(selectPublications)
const includeAllPublications = useAppSelector(selectIncludeAllPublications) === true
+3
View File
@@ -1,5 +1,8 @@
import { useState } from "react"
/**
* Custom hook that provides state functions tailored for modals.
*/
export const useModalState = () => {
const [isOpen, setIsOpen] = useState(false)
+3
View File
@@ -11,6 +11,9 @@ import {
import { selectCustomProfessionName, selectSex } from "../slices/characterSlice.ts"
import { useAppSelector } from "./redux.ts"
/**
* Returns the full name of the current profession.
*/
export const useProfessionName = (): FullProfessionNameParts | undefined => {
const translateMap = useTranslateMap()
const sex = useAppSelector(selectSex)
+9
View File
@@ -1,5 +1,14 @@
import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux"
import { AppDispatch, RootState } from "../store.ts"
/**
* A pre-typed hook to access the redux `dispatch` function.
*/
export const useAppDispatch: () => AppDispatch = useDispatch
/**
* A pre-typed hook to access the redux store's state. This hook takes a
* selector function as an argument. The selector is called with the store
* state.
*/
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector
+3
View File
@@ -2,6 +2,9 @@ import { createAction } from "@reduxjs/toolkit"
import type { Database } from "../database/index.ts"
import { GlobalSettings } from "../shared/settings/GlobalSettings.ts"
/**
* Action to initialize the main window with required values.
*/
export const init = createAction<{
database: Database
globalSettings: GlobalSettings
@@ -29,6 +29,10 @@ import {
selectZibiljaRituals,
} from "../slices/characterSlice.ts"
/**
* Adventure Points can either be spent from the main pool of adventure points
* or from the pool bound to a specific entry.
*/
export type SpentAdventurePoints = {
general: number
bound: number
@@ -47,16 +51,28 @@ const sumRatedMaps = (
{ general: 0, bound: 0 },
)
/**
* Returns the adventure points spent on attributes.
*/
export const selectAdventurePointsSpentOnAttributes = createSelector(selectAttributes, sumRatedMaps)
/**
* Returns the adventure points spent on skills.
*/
export const selectAdventurePointsSpentOnSkills = createSelector(selectSkills, sumRatedMaps)
/**
* Returns the adventure points spent on combat techniques.
*/
export const selectAdventurePointsSpentOnCombatTechniques = createSelector(
selectCloseCombatTechniques,
selectRangedCombatTechniques,
sumRatedMaps,
)
/**
* Returns the adventure points spent on spells.
*/
export const selectAdventurePointsSpentOnSpells = createSelector(
selectSpells,
selectRituals,
@@ -72,47 +88,74 @@ export const selectAdventurePointsSpentOnSpells = createSelector(
sumRatedMaps,
)
/**
* Returns the adventure points spent on liturgical chants.
*/
export const selectAdventurePointsSpentOnLiturgicalChants = createSelector(
selectLiturgicalChants,
selectCeremonies,
sumRatedMaps,
)
/**
* Returns the adventure points spent on cantrips.
*/
export const selectAdventurePointsSpentOnCantrips = createSelector(
selectCantrips,
(cantrips): SpentAdventurePoints => ({ general: cantrips.length, bound: 0 }),
)
/**
* Returns the adventure points spent on blessings.
*/
export const selectAdventurePointsSpentOnBlessings = createSelector(
selectBlessings,
(blessings): SpentAdventurePoints => ({ general: blessings.length, bound: 0 }),
)
/**
* Returns the adventure points spent on advantages.
*/
export const selectAdventurePointsSpentOnAdvantages = createSelector(
selectCurrentCharacter,
(): SpentAdventurePoints => ({ general: 0, bound: 0 }),
)
/**
* Returns the adventure points spent on magical advantages.
*/
export const selectAdventurePointsSpentOnMagicalAdvantages = createSelector(
selectCurrentCharacter,
(): SpentAdventurePoints => ({ general: 0, bound: 0 }),
)
/**
* Returns the adventure points spent on blessed advantages.
*/
export const selectAdventurePointsSpentOnBlessedAdvantages = createSelector(
selectCurrentCharacter,
(): SpentAdventurePoints => ({ general: 0, bound: 0 }),
)
/**
* Returns the adventure points spent on disadvantages.
*/
export const selectAdventurePointsSpentOnDisadvantages = createSelector(
selectCurrentCharacter,
(): SpentAdventurePoints => ({ general: 0, bound: 0 }),
)
/**
* Returns the adventure points spent on magical disadvantages.
*/
export const selectAdventurePointsSpentOnMagicalDisadvantages = createSelector(
selectCurrentCharacter,
(): SpentAdventurePoints => ({ general: 0, bound: 0 }),
)
/**
* Returns the adventure points spent on blessed disadvantages.
*/
export const selectAdventurePointsSpentOnBlessedDisadvantages = createSelector(
selectCurrentCharacter,
(): SpentAdventurePoints => ({ general: 0, bound: 0 }),
@@ -123,11 +166,17 @@ export const selectAdventurePointsSpentOnBlessedDisadvantages = createSelector(
// fmap(getDisAdvantagesSubtypeMax(true))
// )
/**
* Returns the adventure points spent on special abilities.
*/
export const selectAdventurePointsSpentOnSpecialAbilities = createSelector(
selectCurrentCharacter,
(): SpentAdventurePoints => ({ general: 0, bound: 0 }),
)
/**
* Returns the adventure points spent on energies.
*/
export const selectAdventurePointsSpentOnEnergies = createSelector(
selectDerivedCharacteristics,
(derivedCharacteristics): number =>
@@ -143,16 +192,25 @@ export const selectAdventurePointsSpentOnEnergies = createSelector(
derivedCharacteristics.karmaPoints.permanentlyLostBoughtBack * 2,
)
/**
* Returns the adventure points spent on race.
*/
export const selectAdventurePointsSpentOnRace = createSelector(
selectCurrentCharacter,
(): number => 0,
)
/**
* Returns the adventure points spent on profession.
*/
export const selectAdventurePointsSpentOnProfession = createSelector(
selectCurrentCharacter,
(): number | undefined => undefined,
)
/**
* Returns the adventure points spent.
*/
export const selectAdventurePointsSpent = createSelector(
selectAdventurePointsSpentOnAttributes,
selectAdventurePointsSpentOnSkills,
@@ -193,6 +251,9 @@ export const selectAdventurePointsSpent = createSelector(
),
)
/**
* Returns the available adventure points.
*/
export const selectAdventurePointsAvailable = createSelector(
selectTotalAdventurePoints,
selectAdventurePointsSpent,
@@ -2,16 +2,26 @@ import { createSelector } from "@reduxjs/toolkit"
import { selectIsCharacterCreationFinished } from "../slices/characterSlice.ts"
import { selectIsEditAfterCreationEnabled } from "../slices/settingsSlice.ts"
/**
* Returns whether the character is still being created, i.e. the character
* creation has not been finished.
*/
export const selectIsInCharacterCreation = createSelector(
selectIsCharacterCreationFinished,
(isCharacterCreationFinished): boolean => !isCharacterCreationFinished,
)
/**
* Returns whether the more adventure points can be added to the character.
*/
export const selectCanAddAdventurePoints = createSelector(
selectIsCharacterCreationFinished,
(isCharacterCreationFinished): boolean => isCharacterCreationFinished,
)
/**
* Returns whether entries of the character can be removed or lowered in points.
*/
export const selectCanRemove = createSelector(
selectIsCharacterCreationFinished,
selectIsEditAfterCreationEnabled,
@@ -51,6 +51,10 @@ import {
import { selectIsInCharacterCreation } from "./characterSelectors.ts"
import { selectCurrentRace } from "./raceSelectors.ts"
/**
* A combination of a static derived characteristic and its corresponding
* derived values, extended by value bounds.
*/
export type DisplayedDerivedCharacteristic<T extends DCId = DCId> = {
id: T
base: number
@@ -66,6 +70,10 @@ export type DisplayedDerivedCharacteristic<T extends DCId = DCId> = {
static: DerivedCharacteristic
}
/**
* A combination of a static energy and its corresponding derived values,
* extended by value bounds.
*/
export type DisplayedEnergy<T extends EnergyIdentifier = EnergyIdentifier> = {
id: T
base: number
@@ -81,9 +89,15 @@ export type DisplayedEnergy<T extends EnergyIdentifier = EnergyIdentifier> = {
static: DerivedCharacteristic
}
/**
* Checks if a displayed derived characteristic is an energy.
*/
export const isDisplayedEnergy = (dc: DisplayedDerivedCharacteristic): dc is DisplayedEnergy =>
dc.id === DCId.LifePoints || dc.id === DCId.ArcaneEnergy || dc.id === DCId.KarmaPoints
/**
* Returns the static and dynamic values for life points.
*/
export const selectLifePoints = createSelector(
selectCurrentRace,
createPropertySelector(selectAttributes, AttributeIdentifier.Constitution),
@@ -127,6 +141,9 @@ export const selectLifePoints = createSelector(
},
)
/**
* Returns the static and dynamic values for arcane energy.
*/
export const selectArcaneEnergy = createSelector(
createPropertySelector(selectAdvantages, AdvantageIdentifier.Spellcaster),
selectMagicalTraditions,
@@ -201,6 +218,9 @@ export const selectArcaneEnergy = createSelector(
},
)
/**
* Returns the static and dynamic values for karma points.
*/
export const selectKarmaPoints = createSelector(
createPropertySelector(selectAdvantages, AdvantageIdentifier.Blessed),
selectBlessedTraditions,
@@ -268,6 +288,9 @@ export const selectKarmaPoints = createSelector(
const divideAttributeSumByRound = (attributes: (Rated | undefined)[], divisor: number) =>
Math.round(attributes.reduce((acc, attr) => acc + attributeValue(attr), 0) / divisor)
/**
* Returns the static and dynamic values for spirit.
*/
export const selectSpirit = createSelector(
selectCurrentRace,
createPropertySelector(selectAttributes, AttributeIdentifier.Courage),
@@ -303,6 +326,9 @@ export const selectSpirit = createSelector(
},
)
/**
* Returns the static and dynamic values for toughness.
*/
export const selectToughness = createSelector(
selectCurrentRace,
createPropertySelector(selectAttributes, AttributeIdentifier.Constitution),
@@ -336,6 +362,9 @@ export const selectToughness = createSelector(
},
)
/**
* Returns the static and dynamic values for dodge.
*/
export const selectDodge = createSelector(
createPropertySelector(selectAttributes, AttributeIdentifier.Agility),
createPropertySelector(selectActiveOptionalRules, OptionalRuleIdentifier.HigherDefenseStats),
@@ -363,6 +392,9 @@ export const selectDodge = createSelector(
},
)
/**
* Returns the static and dynamic values for initiative.
*/
export const selectInitiative = createSelector(
createPropertySelector(selectAttributes, AttributeIdentifier.Courage),
createPropertySelector(selectAttributes, AttributeIdentifier.Agility),
@@ -396,6 +428,9 @@ export const selectInitiative = createSelector(
},
)
/**
* Returns the static and dynamic values for movement.
*/
export const selectMovement = createSelector(
selectCurrentRace,
createPropertySelector(selectAdvantages, AdvantageIdentifier.Nimble),
@@ -441,6 +476,9 @@ export const selectMovement = createSelector(
},
)
/**
* Returns the static and dynamic values for wound threshold.
*/
export const selectWoundThreshold = createSelector(
createPropertySelector(selectAttributes, AttributeIdentifier.Constitution),
createPropertySelector(selectAdvantages, AdvantageIdentifier.Unyielding),
@@ -474,6 +512,9 @@ export const selectWoundThreshold = createSelector(
},
)
/**
* Returns the static and dynamic values for fate points.
*/
export const selectFatePoints = createSelector(
createPropertySelector(selectAdvantages, AdvantageIdentifier.Luck),
createPropertySelector(selectDisadvantages, DisadvantageIdentifier.BadLuck),
@@ -501,6 +542,9 @@ export const selectFatePoints = createSelector(
},
)
/**
* Returns static and dynamic values for all derived characteristics.
*/
export const selectDerivedCharacteristics = createSelector(
selectLifePoints,
selectArcaneEnergy,
@@ -7,6 +7,9 @@ import {
} from "../slices/characterSlice.ts"
import { selectExperienceLevels } from "../slices/databaseSlice.ts"
/**
* Returns the experience level the character started with.
*/
export const selectStartExperienceLevel = createSelector(
selectExperienceLevels,
selectExperienceLevelStartId,
@@ -14,6 +17,10 @@ export const selectStartExperienceLevel = createSelector(
experienceLevelStartId === undefined ? undefined : experienceLevels[experienceLevelStartId],
)
/**
* Returns the experience level the character has reached with the current
* amount of adventure points.
*/
export const selectCurrentExperienceLevel = createSelector(
selectExperienceLevels,
selectTotalAdventurePoints,
@@ -23,6 +30,9 @@ export const selectCurrentExperienceLevel = createSelector(
: getCurrentExperienceLevel(experienceLevels, totalAdventurePoints),
)
/**
* Returns the maximum number of attribute points that can be spent.
*/
export const selectMaximumTotalAttributePoints = createSelector(
selectStartExperienceLevel,
(experienceLevel): number => experienceLevel?.max_attribute_total ?? 0,
@@ -17,6 +17,10 @@ import { selectEyeColors, selectHairColors, selectSocialStatuses } from "../slic
import { selectCurrentCulture } from "./cultureSelectors.ts"
import { selectCurrentRace, selectCurrentRaceVariant } from "./raceSelectors.ts"
/**
* Returns the social statuses that are available for the character based on
* the culture.
*/
export const selectAvailableSocialStatuses = createSelector(
selectCurrentCulture,
selectSocialStatusDependencies,
@@ -40,6 +44,11 @@ export const selectAvailableSocialStatuses = createSelector(
const ALBINO = 1
const GREEN_HAIR = 3
/**
* Returns a array containing 20 hair color identifiers that mirror the
* probabilities used for randomly rolling a die and that are available for the
* character based on the race.
*/
export const selectAvailableHairColorsIdDice = createSelector(
selectCurrentRace,
selectCurrentRaceVariant,
@@ -66,6 +75,10 @@ export const selectAvailableHairColorsIdDice = createSelector(
},
)
/**
* Returns the hair colors that are available for the character based on the
* race.
*/
export const selectAvailableHairColors = createSelector(
selectAvailableHairColorsIdDice,
selectHairColors,
@@ -73,6 +86,11 @@ export const selectAvailableHairColors = createSelector(
filterNonNullable(unique(hairColorIds).map(id => hairColors[id])),
)
/**
* Returns a array containing 20 eye color identifiers that mirror the
* probabilities used for randomly rolling a die and that are available for the
* character based on the race.
*/
export const selectAvailableEyeColorsIdDice = createSelector(
selectCurrentRace,
selectCurrentRaceVariant,
@@ -96,6 +114,10 @@ export const selectAvailableEyeColorsIdDice = createSelector(
},
)
/**
* Returns the eye colors that are available for the character based on the
* race.
*/
export const selectAvailableEyeColors = createSelector(
selectAvailableEyeColorsIdDice,
selectEyeColors,
@@ -103,6 +125,9 @@ export const selectAvailableEyeColors = createSelector(
filterNonNullable(unique(eyeColorIds).map(id => eyeColors[id])),
)
/**
* Returns the configuration for random height generation.
*/
export const selectRandomHeightCalculation = createSelector(
selectCurrentRace,
selectCurrentRaceVariant,
@@ -113,6 +138,9 @@ export const selectRandomHeightCalculation = createSelector(
: { base: 0, random: [] }),
)
/**
* Returns the configuration for random weight generation.
*/
export const selectRandomWeightCalculation = createSelector(
selectCurrentRace,
(currentRace): Weight => currentRace?.weight ?? { base: 0, random: [] },
@@ -13,6 +13,9 @@ import {
import { selectProfessions } from "../slices/databaseSlice.ts"
import { selectStartExperienceLevel } from "./experienceLevelSelectors.ts"
/**
* Returns different selected parts of a base profession.
*/
export const selectCurrentProfession = createSelector(
selectProfessions,
selectProfessionId,
@@ -27,6 +30,9 @@ export const selectCurrentProfession = createSelector(
},
)
/**
* Returns the current profession variant.
*/
export const selectCurrentProfessionVariant = createSelector(
selectCurrentProfession,
selectProfessionVariantId,
+10
View File
@@ -17,9 +17,19 @@ const sliceReducer = combineReducers({
const reducer = reduceReducers(sliceReducer, globalReducer)
/**
* The Redux store for the main window.
*/
export const store = configureStore({
reducer,
})
/**
* The root state of the Redux store.
*/
export type RootState = ReturnType<typeof sliceReducer>
/**
* A pre-typed version of the dispatch function.
*/
export type AppDispatch = typeof store.dispatch
+3
View File
@@ -20,6 +20,9 @@ type Props = {
initialSettings: GlobalSettings
}
/**
* Root component for the settings window.
*/
export const Root: React.FC<Props> = props => {
const { locales, initialSettings } = props