diff --git a/scripts/setup-mysql.sql b/scripts/setup-mysql.sql
index 8a6251e..90c61e3 100644
--- a/scripts/setup-mysql.sql
+++ b/scripts/setup-mysql.sql
@@ -27,9 +27,9 @@ GRANT INSERT ON modeling_logs TO impress2020;
-- User data tables
GRANT SELECT, INSERT, DELETE ON closet_hangers TO impress2020;
GRANT SELECT, UPDATE ON closet_lists TO impress2020;
-GRANT SELECT ON item_outfit_relationships TO impress2020;
+GRANT SELECT, DELETE ON item_outfit_relationships TO impress2020;
GRANT SELECT ON neopets_connections TO impress2020;
-GRANT SELECT ON outfits TO impress2020;
+GRANT SELECT, INSERT, UPDATE ON outfits TO impress2020;
GRANT SELECT, UPDATE ON users TO impress2020;
GRANT SELECT, UPDATE ON openneo_id.users TO impress2020;
diff --git a/src/app/WardrobePage/ItemsPanel.js b/src/app/WardrobePage/ItemsPanel.js
index 6a73317..a89a93c 100644
--- a/src/app/WardrobePage/ItemsPanel.js
+++ b/src/app/WardrobePage/ItemsPanel.js
@@ -258,7 +258,7 @@ function ItemZoneGroupSkeleton({ itemCount }) {
);
}
-function useOutfitSaving(outfitState) {
+function useOutfitSaving(outfitState, dispatchToOutfit) {
const { isLoggedIn, id: currentUserId } = useCurrentUser();
const history = useHistory();
const toast = useToast();
@@ -272,9 +272,25 @@ function useOutfitSaving(outfitState) {
const isNewOutfit = outfitState.id == null;
// Whether this outfit's latest local changes have been saved to the server.
+ // And log it to the console!
const latestVersionIsSaved =
outfitState.savedOutfitState &&
- outfitStatesAreEqual(outfitState, outfitState.savedOutfitState);
+ outfitStatesAreEqual(
+ outfitState.outfitStateWithoutExtras,
+ outfitState.savedOutfitState
+ );
+ React.useEffect(() => {
+ console.debug(
+ "[useOutfitSaving] Latest version is saved? %s\nCurrent: %o\nSaved: %o",
+ latestVersionIsSaved,
+ outfitState.outfitStateWithoutExtras,
+ outfitState.savedOutfitState
+ );
+ }, [
+ latestVersionIsSaved,
+ outfitState.outfitStateWithoutExtras,
+ outfitState.savedOutfitState,
+ ]);
// Only logged-in users can save outfits - and they can only save new outfits,
// or outfits they created.
@@ -347,6 +363,15 @@ function useOutfitSaving(outfitState) {
},
},
});
+
+ // Also, send a `reset` action, to show whatever the server returned.
+ // This is important for suffix changes to `name`, but can also be
+ // relevant for graceful failure when a bug causes a change not to
+ // persist.
+ dispatchToOutfit({
+ type: "resetToSavedOutfitData",
+ savedOutfitData: outfit,
+ });
},
}
);
@@ -360,8 +385,8 @@ function useOutfitSaving(outfitState) {
speciesId: outfitState.speciesId,
colorId: outfitState.colorId,
pose: outfitState.pose,
- wornItemIds: outfitState.wornItemIds,
- closetedItemIds: outfitState.closetedItemIds,
+ wornItemIds: [...outfitState.wornItemIds],
+ closetedItemIds: [...outfitState.closetedItemIds],
},
})
.then(({ data: { outfit } }) => {
@@ -416,7 +441,7 @@ function useOutfitSaving(outfitState) {
!outfitStatesAreEqual(debouncedOutfitState, outfitState.savedOutfitState)
) {
console.info(
- "[useOutfitSaving] Auto-saving outfit from old state to new state",
+ "[useOutfitSaving] Auto-saving outfit\nSaved: %o\nCurrent (debounced): %o",
outfitState.savedOutfitState,
debouncedOutfitState
);
@@ -452,7 +477,7 @@ function useOutfitSaving(outfitState) {
* OutfitSavingIndicator shows a Save button, or the "Saved" or "Saving" state,
* if the user can save this outfit. If not, this is empty!
*/
-function OutfitSavingIndicator({ outfitState }) {
+function OutfitSavingIndicator({ outfitState, dispatchToOutfit }) {
const {
canSaveOutfit,
isNewOutfit,
@@ -460,7 +485,7 @@ function OutfitSavingIndicator({ outfitState }) {
latestVersionIsSaved,
saveError,
saveOutfit,
- } = useOutfitSaving(outfitState);
+ } = useOutfitSaving(outfitState, dispatchToOutfit);
const errorTextColor = useColorModeValue("red.600", "red.400");
@@ -579,7 +604,10 @@ function OutfitHeading({ outfitState, dispatchToOutfit }) {
-
+