Improved actor editing units.
This commit is contained in:
		
							parent
							
								
									2293e10af7
								
							
						
					
					
						commit
						855a698eae
					
				|  | @ -66,7 +66,16 @@ | |||
| 			</div> | ||||
| 		</div> | ||||
| 
 | ||||
| 		<span class="name">{{ actor.name }}</span> | ||||
| 		<span class="label"> | ||||
| 			<span class="name ellipsis">{{ actor.name }}</span> | ||||
| 
 | ||||
| 			<img | ||||
| 				v-if="actor.entity" | ||||
| 				v-tooltip="actor.entity.name" | ||||
| 				:src="`/logos/${actor.entity.slug}/favicon_dark.png`" | ||||
| 				class="favicon" | ||||
| 			> | ||||
| 		</span> | ||||
| 	</div> | ||||
| </template> | ||||
| 
 | ||||
|  | @ -119,9 +128,11 @@ const favorited = ref(props.actor.stashes.some((actorStash) => actorStash.id === | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| .name { | ||||
| .label { | ||||
| 	display: flex; | ||||
| 	justify-content: space-between; | ||||
| 	align-items: center; | ||||
| 	flex-shrink: 0; | ||||
| 	padding: .35rem .5rem; | ||||
| 	font-weight: bold; | ||||
| 	font-size: .9rem; | ||||
| 	white-space: nowrap; | ||||
|  | @ -130,6 +141,15 @@ const favorited = ref(props.actor.stashes.some((actorStash) => actorStash.id === | |||
| 	user-select: all; | ||||
| } | ||||
| 
 | ||||
| .name { | ||||
| 	padding: .35rem .25rem .35rem .5rem; | ||||
| } | ||||
| 
 | ||||
| .favicon { | ||||
| 	height: 1rem; | ||||
| 	padding: .35rem .5rem .35rem .25rem; | ||||
| } | ||||
| 
 | ||||
| .avatar-container { | ||||
| 	position: relative; | ||||
| 	flex-grow: 1; | ||||
|  |  | |||
|  | @ -68,7 +68,7 @@ | |||
| 					<div class="item-header"> | ||||
| 						<div class="key">{{ item.label || item.key }}</div> | ||||
| 
 | ||||
| 						<div class="item-actions"> | ||||
| 						<div class="item-actions noselect"> | ||||
| 							<Icon | ||||
| 								v-if="!item.forced" | ||||
| 								icon="pencil5" | ||||
|  | @ -153,32 +153,66 @@ | |||
| 									class="input" | ||||
| 									:disabled="!editing.has(item.key)" | ||||
| 								> | ||||
| 									<option value="imperial">Imperial</option> | ||||
| 									<option value="metric">Metric</option> | ||||
| 									<option value="imperial">Imperial</option> | ||||
| 								</select> | ||||
| 							</div> | ||||
| 
 | ||||
| 							<span class="figure-bust"> | ||||
| 							<span class="figure-height"> | ||||
| 								<div class="value-section"> | ||||
| 									<span class="value-label">Bust</span> | ||||
| 									<span class="value-label">Height</span> | ||||
| 
 | ||||
| 									<select | ||||
| 										v-model="edits[item.key].bust" | ||||
| 										class="select input" | ||||
| 										placeholder="Bust" | ||||
| 										:disabled="!editing.has(item.key)" | ||||
| 									> | ||||
| 										<option | ||||
| 											:key="`${item.key}-bust-unknown`" | ||||
| 											:value="null" | ||||
| 										/> | ||||
| 									<span v-if="sizeUnits === 'metric'"> | ||||
| 										<input | ||||
| 											v-model="edits[item.key].metricHeight" | ||||
| 											type="number" | ||||
| 											class="input" | ||||
| 											:disabled="!editing.has(item.key)" | ||||
| 										> cm | ||||
| 									</span> | ||||
| 
 | ||||
| 										<option | ||||
| 											v-for="bust in bustSizes[figureUnits]" | ||||
| 											:key="`${item.key}-bust-${bust}`" | ||||
| 											:value="Array.isArray(bust) ? bust[0] : bust" | ||||
| 										>{{ Array.isArray(bust) ? bust.join('/') : bust }}</option> | ||||
| 									</select> | ||||
| 									<span v-if="sizeUnits === 'imperial'"> | ||||
| 										<input | ||||
| 											v-model="edits[item.key].imperialHeight[0]" | ||||
| 											type="number" | ||||
| 											class="input" | ||||
| 											:disabled="!editing.has(item.key)" | ||||
| 										> ft | ||||
| 
 | ||||
| 										<input | ||||
| 											v-model="edits[item.key].imperialHeight[1]" | ||||
| 											type="number" | ||||
| 											class="input" | ||||
| 											:disabled="!editing.has(item.key)" | ||||
| 										> in | ||||
| 									</span> | ||||
| 								</div> | ||||
| 							</span> | ||||
| 
 | ||||
| 							<span class="figure-weight"> | ||||
| 								<div class="value-section"> | ||||
| 									<span class="value-label">Weight</span> | ||||
| 
 | ||||
| 									<span v-if="sizeUnits === 'metric'"> | ||||
| 										<input | ||||
| 											v-model="edits[item.key].metricWeight" | ||||
| 											type="number" | ||||
| 											class="input" | ||||
| 											:disabled="!editing.has(item.key)" | ||||
| 										> kg | ||||
| 									</span> | ||||
| 
 | ||||
| 									<span v-if="sizeUnits === 'imperial'"> | ||||
| 										<input | ||||
| 											v-model="edits[item.key].imperialWeight" | ||||
| 											type="number" | ||||
| 											class="input" | ||||
| 											:disabled="!editing.has(item.key)" | ||||
| 										> | ||||
| 
 | ||||
| 										<template v-if="sizeUnits === 'imperial'"> lbs</template> | ||||
| 										<template v-else> kg</template> | ||||
| 									</span> | ||||
| 								</div> | ||||
| 							</span> | ||||
| 						</div> | ||||
|  | @ -210,20 +244,10 @@ | |||
| 							</div> | ||||
| 
 | ||||
| 							<div class="value-section"> | ||||
| 								<span class="value-label">State</span> | ||||
| 								<span class="value-label">Place</span> | ||||
| 
 | ||||
| 								<input | ||||
| 									v-model="edits[item.key].state" | ||||
| 									class="string input" | ||||
| 									:disabled="!editing.has(item.key)" | ||||
| 								> | ||||
| 							</div> | ||||
| 
 | ||||
| 							<div class="value-section"> | ||||
| 								<span class="value-label">City</span> | ||||
| 
 | ||||
| 								<input | ||||
| 									v-model="edits[item.key].city" | ||||
| 									v-model="edits[item.key].place" | ||||
| 									class="string input" | ||||
| 									:disabled="!editing.has(item.key)" | ||||
| 								> | ||||
|  | @ -560,27 +584,53 @@ | |||
| 							<div class="value-section"> | ||||
| 								<span class="value-label">Penis length</span> | ||||
| 
 | ||||
| 								<input | ||||
| 									v-model="edits[item.key].penisLength" | ||||
| 									type="number" | ||||
| 									class="volume input" | ||||
| 									min="1" | ||||
| 									max="20" | ||||
| 									:disabled="!editing.has(item.key)" | ||||
| 								> | ||||
| 								<span v-if="penisUnits === 'metric'"> | ||||
| 									<input | ||||
| 										v-model="edits[item.key].metricLength" | ||||
| 										type="number" | ||||
| 										class="volume input" | ||||
| 										min="1" | ||||
| 										max="30" | ||||
| 										:disabled="!editing.has(item.key)" | ||||
| 									> cm | ||||
| 								</span> | ||||
| 
 | ||||
| 								<span v-if="penisUnits === 'imperial'"> | ||||
| 									<input | ||||
| 										v-model="edits[item.key].imperialLength" | ||||
| 										type="number" | ||||
| 										class="volume input" | ||||
| 										min="1" | ||||
| 										max="30" | ||||
| 										:disabled="!editing.has(item.key)" | ||||
| 									> inch | ||||
| 								</span> | ||||
| 							</div> | ||||
| 
 | ||||
| 							<div class="value-section"> | ||||
| 								<span class="value-label">Penis girth</span> | ||||
| 
 | ||||
| 								<input | ||||
| 									v-model="edits[item.key].penisGirth" | ||||
| 									type="number" | ||||
| 									class="volume input" | ||||
| 									min="1" | ||||
| 									max="20" | ||||
| 									:disabled="!editing.has(item.key)" | ||||
| 								> | ||||
| 								<span v-if="penisUnits === 'metric'"> | ||||
| 									<input | ||||
| 										v-model="edits[item.key].metricGirth" | ||||
| 										type="number" | ||||
| 										class="volume input" | ||||
| 										min="1" | ||||
| 										max="30" | ||||
| 										:disabled="!editing.has(item.key)" | ||||
| 									> cm | ||||
| 								</span> | ||||
| 
 | ||||
| 								<span v-if="penisUnits === 'imperial'"> | ||||
| 									<input | ||||
| 										v-model="edits[item.key].imperialGirth" | ||||
| 										type="number" | ||||
| 										class="volume input" | ||||
| 										min="1" | ||||
| 										max="30" | ||||
| 										:disabled="!editing.has(item.key)" | ||||
| 									> inch | ||||
| 								</span> | ||||
| 							</div> | ||||
| 
 | ||||
| 							<div class="value-section"> | ||||
|  | @ -690,7 +740,7 @@ const user = pageContext.user; | |||
| const countries = pageContext.pageProps.countries; | ||||
| const actor = ref(pageContext.pageProps.actor); | ||||
| 
 | ||||
| console.log(actor.value); | ||||
| // console.log(actor.value); | ||||
| 
 | ||||
| const topCountries = [ | ||||
| 	'AU', | ||||
|  | @ -705,26 +755,6 @@ const topCountries = [ | |||
| 
 | ||||
| const sortedCountries = countries.toSorted((countryA, countryB) => topCountries.indexOf(countryB.alpha2) - topCountries.indexOf(countryA.alpha2)); | ||||
| 
 | ||||
| /* | ||||
| const cupSizes = [ | ||||
| 	'A', 'AA', | ||||
| 	'B', | ||||
| 	'C', | ||||
| 	'D', 'DD', 'DDD', | ||||
| 	'E', | ||||
| 	'F', 'FF', | ||||
| 	'G', 'GG', | ||||
| 	'H', 'HH', | ||||
| 	'J', 'JJ', | ||||
| 	'K', 'KK', | ||||
| 	'L', | ||||
| 	'M', | ||||
| 	'N', | ||||
| 	'O', | ||||
| 	'P', | ||||
| ]; | ||||
| */ | ||||
| 
 | ||||
| const cupSizes = { | ||||
| 	us: ['AA', 'A', 'B', 'C', 'D', ['DD', 'E'], ['DDD', 'F'], 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P'], // United States | ||||
| 	uk: ['AA', 'A', 'B', 'C', 'D', 'DD', 'E', 'F', 'FF', 'G', 'GG', 'H', 'HH', 'J', 'JJ', 'K', 'KK'], // United Kingdom | ||||
|  | @ -778,28 +808,42 @@ const fields = computed(() => [ | |||
| 			: null, | ||||
| 		inline: true, | ||||
| 	}, | ||||
| 	{ | ||||
| 		key: 'ethnicity', | ||||
| 		type: 'string', | ||||
| 		value: actor.value.ethnicity, | ||||
| 		suggestions: [ | ||||
| 			'Asian', | ||||
| 			'Black', | ||||
| 			'Indian', | ||||
| 			'Latina', | ||||
| 			'White', | ||||
| 		], | ||||
| 	}, | ||||
| 	{ | ||||
| 		key: 'origin', | ||||
| 		type: 'place', | ||||
| 		value: { | ||||
| 			...actor.value.origin, | ||||
| 			country: actor.value.origin?.country?.alpha2 || null, | ||||
| 			place: [actor.value.origin?.city, actor.value.origin?.state].filter(Boolean).join(', '), | ||||
| 		}, | ||||
| 	}, | ||||
| 	{ | ||||
| 		key: 'residence', | ||||
| 		type: 'place', | ||||
| 		value: { | ||||
| 			...actor.value.residence, | ||||
| 			country: actor.value.residence?.country?.alpha2 || null, | ||||
| 			place: [actor.value.residence?.city, actor.value.residence?.state].filter(Boolean).join(', '), | ||||
| 		}, | ||||
| 	}, | ||||
| 	{ | ||||
| 		key: 'size', | ||||
| 		type: 'size', | ||||
| 		value: { | ||||
| 			height: actor.value.height?.metric, | ||||
| 			weight: actor.value.weight?.metric, | ||||
| 			metricHeight: actor.value.height?.metric, | ||||
| 			metricWeight: actor.value.weight?.metric, | ||||
| 			imperialHeight: actor.value.height?.imperial || [], | ||||
| 			imperialWeight: actor.value.weight?.imperial, | ||||
| 		}, | ||||
| 	}, | ||||
| 	{ | ||||
|  | @ -900,8 +944,10 @@ const fields = computed(() => [ | |||
| 		key: 'penis', | ||||
| 		type: 'penis', | ||||
| 		value: { | ||||
| 			penisLength: actor.value.penisLength?.imperial, | ||||
| 			penisGirth: actor.value.penisGirth?.imperial, | ||||
| 			metricLength: actor.value.penisLength?.metric, | ||||
| 			metricGirth: actor.value.penisGirth?.metric, | ||||
| 			imperialLength: actor.value.penisLength?.imperial, | ||||
| 			imperialGirth: actor.value.penisGirth?.imperial, | ||||
| 			isCircumcised: actor.value.isCircumcised, | ||||
| 		}, | ||||
| 	}, | ||||
|  | @ -943,27 +989,49 @@ function setAvatar(avatarId) { | |||
| const keyMap = { | ||||
| 	origin: { | ||||
| 		country: 'originCountry', | ||||
| 		state: 'originState', | ||||
| 		city: 'originCity', | ||||
| 		place: 'originPlace', | ||||
| 	}, | ||||
| 	residence: { | ||||
| 		country: 'residenceCountry', | ||||
| 		state: 'residenceState', | ||||
| 		city: 'residenceCity', | ||||
| 		place: 'residencePlace', | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| const groupMap = { | ||||
| 	penisLength: 'penis', | ||||
| 	penisGirth: 'penis', | ||||
| 	height: 'size', | ||||
| 	weight: 'size', | ||||
| }; | ||||
| 
 | ||||
| async function submit() { | ||||
| 	try { | ||||
| 		await post('/revisions/actors', { | ||||
| 			actorId: actor.value.id, | ||||
| 			edits: Object.fromEntries(Array.from(editing.value).flatMap((key) => { | ||||
| 				if (edits.value[key] && typeof edits.value[key] === 'object') { | ||||
| 					return Object.entries(edits.value[key]).map(([valueKey, value]) => [keyMap[key]?.[valueKey] || valueKey, value]); | ||||
| 				} | ||||
| 			edits: { | ||||
| 				...Object.fromEntries(Array.from(editing.value).flatMap((key) => { | ||||
| 					if (edits.value[key] && typeof edits.value[key] === 'object') { | ||||
| 						return Object.entries(edits.value[key]).map(([valueKey, value]) => [keyMap[key]?.[valueKey] || valueKey, value]); | ||||
| 					} | ||||
| 
 | ||||
| 				return [[key, edits.value[key]]]; | ||||
| 			})), | ||||
| 					return [[key, edits.value[key]]]; | ||||
| 				})), | ||||
| 				...Object.fromEntries(Object.entries({ | ||||
| 					height: sizeUnits.value === 'imperial' ? edits.value.size.imperialHeight : edits.value.size.metricHeight, | ||||
| 					weight: sizeUnits.value === 'imperial' ? edits.value.size.imperialWeight : edits.value.size.metricWeight, | ||||
| 					penisLength: penisUnits.value === 'imperial' ? edits.value.penis.imperialLength : edits.value.penis.metricLength, | ||||
| 					penisGirth: penisUnits.value === 'imperial' ? edits.value.penis.imperialGirth : edits.value.penis.metricGirth, | ||||
| 				}).filter(([key]) => editing.value.has(groupMap[key] || key))), | ||||
| 				metricHeight: undefined, | ||||
| 				metricWeight: undefined, | ||||
| 				imperialHeight: undefined, | ||||
| 				imperialWeight: undefined, | ||||
| 				metricLength: undefined, | ||||
| 				metricGirth: undefined, | ||||
| 				imperialLength: undefined, | ||||
| 				imperialGirth: undefined, | ||||
| 			}, | ||||
| 			sizeUnits: sizeUnits.value, | ||||
| 			figureUnits: figureUnits.value, | ||||
| 			penisUnits: penisUnits.value, | ||||
| 			comment: comment.value, | ||||
|  |  | |||
							
								
								
									
										125
									
								
								src/actors.js
								
								
								
								
							
							
						
						
									
										125
									
								
								src/actors.js
								
								
								
								
							|  | @ -59,6 +59,12 @@ export function curateActor(actor, context = {}) { | |||
| 		name: actor.name, | ||||
| 		gender: actor.gender, | ||||
| 		age: actor.age, | ||||
| 		ethnicity: actor.ethnicity, | ||||
| 		entity: actor.entity && { | ||||
| 			id: actor.entity.id, | ||||
| 			slug: actor.entity.slug, | ||||
| 			name: actor.entity.name, | ||||
| 		}, | ||||
| 		...Object.fromEntries(Object.entries(keyMap).map(([key, entryKey]) => [key, actor[entryKey]])), | ||||
| 		ageFromBirth: actor.date_of_birth && differenceInYears(Date.now(), actor.date_of_birth), | ||||
| 		ageThen: context.sceneDate && actor.date_of_birth && differenceInYears(context.sceneDate, actor.date_of_birth), | ||||
|  | @ -166,11 +172,13 @@ export async function fetchActorsById(actorIds, options = {}, reqUser) { | |||
| 				knex.raw('COALESCE(birth_countries.alias, birth_countries.name) as birth_country_name'), | ||||
| 				'residence_countries.alpha2 as residence_country_alpha2', | ||||
| 				knex.raw('COALESCE(residence_countries.alias, residence_countries.name) as residence_country_name'), | ||||
| 				knex.raw('row_to_json(entities) as entity'), | ||||
| 			) | ||||
| 			.leftJoin('actors_meta', 'actors_meta.actor_id', 'actors.id') | ||||
| 			.leftJoin('countries as birth_countries', 'birth_countries.alpha2', 'actors.birth_country_alpha2') | ||||
| 			.leftJoin('countries as residence_countries', 'residence_countries.alpha2', 'actors.residence_country_alpha2') | ||||
| 			.leftJoin('media as avatars', 'avatars.id', 'actors.avatar_media_id') | ||||
| 			.leftJoin('entities', 'entities.id', 'actors.entity_id') | ||||
| 			.whereIn('actors.id', actorIds) | ||||
| 			.modify((builder) => { | ||||
| 				if (options.order) { | ||||
|  | @ -199,8 +207,8 @@ export async function fetchActorsById(actorIds, options = {}, reqUser) { | |||
| 			) | ||||
| 			.whereIn('actor_id', actorIds) | ||||
| 			.leftJoin('media', 'media.id', 'actors_avatars.media_id') | ||||
| 			.groupBy('media.id', 'actors_avatars.actor_id', 'actors_avatars.created_at') | ||||
| 			.orderBy('actors_avatars.created_at', 'desc'), | ||||
| 			.groupBy('media.id', 'actors_avatars.actor_id') | ||||
| 			.orderBy(knex.raw('max(actors_avatars.created_at)'), 'desc'), | ||||
| 		reqUser | ||||
| 			? knex('stashes_actors') | ||||
| 				.leftJoin('stashes', 'stashes.id', 'stashes_actors.stash_id') | ||||
|  | @ -549,34 +557,6 @@ async function fetchMainProfile(actorId, wasCreated = false) { | |||
| 	return fetchMainProfile(actorId, true); | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| async function applyMainProfile(actorId) { | ||||
| 	const [actorEntry, mainProfile] = await Promise.all([ | ||||
| 		knex('actors') | ||||
| 			.where('id', actorId) | ||||
| 			.first(), | ||||
| 		fetchMainProfile(actorId), | ||||
| 	]); | ||||
| 
 | ||||
| 	if (!actorEntry) { | ||||
| 		throw new HttpError('No actor profile found to apply main profile to', 404); | ||||
| 	} | ||||
| 
 | ||||
| 	const preservedKeys = ['id']; | ||||
| 
 | ||||
| 	// we start iterating from the actor entry so we don't include keys that are not yet supported by the actors table
 | ||||
| 	const mergedProfile = Object.fromEntries(Object.entries(actorEntry) | ||||
| 		.filter(([key]) => Object.hasOwn(mainProfile, key)) | ||||
| 		.map(([key, value]) => [key, mainProfile[key] === null || preservedKeys.includes(key) | ||||
| 			? value | ||||
| 			: mainProfile[key]])); | ||||
| 
 | ||||
| 	await knex('actors') | ||||
| 		.where('id', actorId) | ||||
| 		.update(mergedProfile); | ||||
| } | ||||
| */ | ||||
| 
 | ||||
| async function applyActorRevision(revisionIds, reqUser) { | ||||
| 	const revisions = await knex('actors_revisions') | ||||
| 		.whereIn('id', revisionIds) | ||||
|  | @ -600,6 +580,7 @@ async function applyActorRevision(revisionIds, reqUser) { | |||
| 					'residenceCountry', | ||||
| 					'residenceState', | ||||
| 					'residenceCity', | ||||
| 					'ethnicity', | ||||
| 					'height', | ||||
| 					'weight', | ||||
| 					'bust', | ||||
|  | @ -755,6 +736,27 @@ function convertFigure(domain = 'cup', rawValue, units) { | |||
| 	return usValue; | ||||
| } | ||||
| 
 | ||||
| function convertHeight(height, units) { | ||||
| 	if (units === 'metric' || !Array.isArray(height)) { | ||||
| 		return Number(height) || null; | ||||
| 	} | ||||
| 
 | ||||
| 	if (height.length !== 2) { | ||||
| 		return null; | ||||
| 	} | ||||
| 
 | ||||
| 	// 12 inches in a foot
 | ||||
| 	return Math.round(((height[0] * 12) + height[1]) * 2.54); | ||||
| } | ||||
| 
 | ||||
| function convertWeight(weight, units) { | ||||
| 	if (units === 'imperial') { | ||||
| 		return Math.round(unit(weight, 'lbs').toNumeric('kg')); | ||||
| 	} | ||||
| 
 | ||||
| 	return Number(weight) || null; | ||||
| } | ||||
| 
 | ||||
| export async function createActorRevision(actorId, { | ||||
| 	edits, | ||||
| 	comment, | ||||
|  | @ -819,15 +821,9 @@ export async function createActorRevision(actorId, { | |||
| 			return null; | ||||
| 		} | ||||
| 
 | ||||
| 		if (Array.isArray(value)) { | ||||
| 			const valueSet = new Set(value); | ||||
| 			const baseSet = new Set(baseActor[key]); | ||||
| 
 | ||||
| 			if (valueSet.size === baseSet.size && baseActor[key].every((id) => valueSet.has(id))) { | ||||
| 				return null; | ||||
| 			} | ||||
| 
 | ||||
| 			return { key, value: Array.from(valueSet) }; | ||||
| 		if (['originPlace', 'residencePlay'].includes(key)) { | ||||
| 			console.log(key, value); | ||||
| 			throw new Error('must be converted first!'); | ||||
| 		} | ||||
| 
 | ||||
| 		if (['cup', 'bust', 'waist', 'hip'].includes(key)) { | ||||
|  | @ -844,9 +840,49 @@ export async function createActorRevision(actorId, { | |||
| 			}; | ||||
| 		} | ||||
| 
 | ||||
| 		if (['height'].includes(key)) { | ||||
| 			const convertedValue = convertHeight(value, options.sizeUnits); | ||||
| 
 | ||||
| 			if (baseActor[key] === convertedValue) { | ||||
| 				return null; | ||||
| 			} | ||||
| 
 | ||||
| 			const conversionComment = !value || convertedValue === value | ||||
| 				? null | ||||
| 				: `${key} converted from ${value[0]} in ${value[1]} ft to ${convertedValue} cm`; | ||||
| 
 | ||||
| 			return { | ||||
| 				key, | ||||
| 				value: convertedValue, | ||||
| 				comment: conversionComment, | ||||
| 			}; | ||||
| 		} | ||||
| 
 | ||||
| 		if (['weight'].includes(key)) { | ||||
| 			const convertedValue = convertWeight(value, options.sizeUnits); | ||||
| 
 | ||||
| 			if (baseActor[key] === convertedValue) { | ||||
| 				return null; | ||||
| 			} | ||||
| 
 | ||||
| 			const conversionComment = !value || convertedValue === value | ||||
| 				? null | ||||
| 				: `${key} converted from ${value} lbs to ${convertedValue} kg`; | ||||
| 
 | ||||
| 			return { | ||||
| 				key, | ||||
| 				value: convertedValue, | ||||
| 				comment: conversionComment, | ||||
| 			}; | ||||
| 		} | ||||
| 
 | ||||
| 		if (['penisLength', 'penisGirth'].includes(key) && options.penisUnits === 'imperial') { | ||||
| 			const convertedValue = Math.round(convert(value, 'inches').to('cm')); | ||||
| 
 | ||||
| 			if (baseActor[key] === convertedValue) { | ||||
| 				return null; | ||||
| 			} | ||||
| 
 | ||||
| 			return { | ||||
| 				key, | ||||
| 				value: convertedValue, | ||||
|  | @ -854,6 +890,17 @@ export async function createActorRevision(actorId, { | |||
| 			}; | ||||
| 		} | ||||
| 
 | ||||
| 		if (Array.isArray(value)) { | ||||
| 			const valueSet = new Set(value); | ||||
| 			const baseSet = new Set(baseActor[key]); | ||||
| 
 | ||||
| 			if (valueSet.size === baseSet.size && baseActor[key].every((id) => valueSet.has(id))) { | ||||
| 				return null; | ||||
| 			} | ||||
| 
 | ||||
| 			return { key, value: Array.from(valueSet) }; | ||||
| 		} | ||||
| 
 | ||||
| 		return { key, value }; | ||||
| 	}).filter(Boolean); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue