mirror of
https://github.com/igorski/bitmappery.git
synced 2026-06-16 19:25:38 +02:00
Shuffling layer order now triggers a tile re-render
This commit is contained in:
@@ -21,9 +21,11 @@
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
import { type Store } from "vuex";
|
||||
import { type Document } from "@/definitions/document";
|
||||
import type { Document, RelId } from "@/definitions/document";
|
||||
import { enqueueState } from "@/factories/history-state-factory";
|
||||
import { createGroupTile } from "@/rendering/cache/tile-cache";
|
||||
import { type BitMapperyState } from "@/store";
|
||||
import { getTileByLayer } from "@/utils/timeline-util";
|
||||
|
||||
/**
|
||||
* layerIds represents an ordered list
|
||||
@@ -45,15 +47,22 @@ export const reorderLayers = ( store: Store<BitMapperyState>, activeDocument: Do
|
||||
subsetIndices.forEach(( idx: number, i: number ) => {
|
||||
updatedOrder[ idx ] = layerIds[ i ];
|
||||
});
|
||||
|
||||
|
||||
const tileIds = activeDocument.type === "timeline" ? [ ...layerIds.reduce(( acc, layerId ) => {
|
||||
acc.add( getTileByLayer( activeDocument, layerId ));
|
||||
return acc;
|
||||
}, new Set<RelId>())] : [];
|
||||
|
||||
const commit = () => {
|
||||
store.commit( "reorderLayers", { document: activeDocument, layerIds: updatedOrder } );
|
||||
}
|
||||
store.commit( "reorderLayers", { activeDocument, layerIds: updatedOrder } );
|
||||
tileIds.forEach( tileId => createGroupTile( tileId, activeDocument ));
|
||||
};
|
||||
commit();
|
||||
|
||||
enqueueState( `reorderLayers_${layerIds.join()}`, {
|
||||
undo() {
|
||||
store.commit( "reorderLayers", { document: activeDocument, layerIds: originalOrder });
|
||||
undo(): void {
|
||||
store.commit( "reorderLayers", { activeDocument, layerIds: originalOrder });
|
||||
tileIds.forEach( tileId => createGroupTile( tileId, activeDocument ));
|
||||
},
|
||||
redo: commit,
|
||||
});
|
||||
|
||||
@@ -147,14 +147,14 @@ const DocumentModule: Module<DocumentState, any> = {
|
||||
layers[ index1 ] = layers[ index2 ];
|
||||
layers[ index2 ] = obj1;
|
||||
},
|
||||
reorderLayers( _state: DocumentState, { document, layerIds }: { document: Document, layerIds: string[] }): void {
|
||||
const oldLayers = [ ...document.layers ];
|
||||
const layers = [ ...document.layers ];
|
||||
reorderLayers( _state: DocumentState, { activeDocument, layerIds }: { activeDocument: Document, layerIds: string[] }): void {
|
||||
const oldLayers = [ ...activeDocument.layers ];
|
||||
const layers = [ ...activeDocument.layers ];
|
||||
layers.splice( 0, oldLayers.length );
|
||||
layerIds.forEach( id => {
|
||||
layers.push( oldLayers.find( layer => layer.id === id ));
|
||||
});
|
||||
document.layers = layers;
|
||||
activeDocument.layers = layers;
|
||||
flushBlendedLayerCache( true );
|
||||
},
|
||||
removeLayer( state: DocumentState, index: number ): void {
|
||||
|
||||
@@ -4,6 +4,7 @@ import { createStore, mockZCanvas } from "../../mocks";
|
||||
|
||||
mockZCanvas();
|
||||
|
||||
import type { Document } from "@/definitions/document";
|
||||
import DocumentFactory from "@/factories/document-factory";
|
||||
import LayerFactory from "@/factories/layer-factory";
|
||||
import { type BitMapperyState } from "@/store";
|
||||
@@ -14,6 +15,11 @@ vi.mock( "@/factories/history-state-factory", () => ({
|
||||
enqueueState: ( ...args: any[] ) => mockEnqueueState( ...args ),
|
||||
}));
|
||||
|
||||
const mockCreateGroupTile = vi.fn();
|
||||
vi.mock( "@/rendering/cache/tile-cache", () => ({
|
||||
createGroupTile: ( ...args: any[] ) => mockCreateGroupTile( ...args ),
|
||||
}));
|
||||
|
||||
describe( "reorder layers action", () => {
|
||||
const tile1layer1 = LayerFactory.create({ rel: { type: "tile", id: 0 }});
|
||||
const tile1layer2 = LayerFactory.create({ rel: { type: "tile", id: 0 }});
|
||||
@@ -24,24 +30,27 @@ describe( "reorder layers action", () => {
|
||||
|
||||
const tile3layer1 = LayerFactory.create({ rel: { type: "tile", id: 2 }});
|
||||
|
||||
const document = DocumentFactory.create({
|
||||
layers: [
|
||||
tile1layer1, tile1layer2,
|
||||
tile2layer1, tile2layer2, tile2layer3,
|
||||
tile3layer1,
|
||||
]
|
||||
});
|
||||
|
||||
const originalLayerIds = document.layers.map( layer => layer.id );
|
||||
const shuffledLayerIds = [
|
||||
tile1layer1.id, tile1layer2.id,
|
||||
tile2layer3.id, tile2layer1.id, tile2layer2.id, // reorder is on this line!
|
||||
tile3layer1.id,
|
||||
];
|
||||
let originalLayerIds: string[];
|
||||
let activeDocument: Document;
|
||||
let store: Store<BitMapperyState>;
|
||||
|
||||
beforeEach(() => {
|
||||
store = createStore();
|
||||
|
||||
activeDocument = DocumentFactory.create({
|
||||
type: "timeline",
|
||||
layers: [
|
||||
tile1layer1, tile1layer2,
|
||||
tile2layer1, tile2layer2, tile2layer3,
|
||||
tile3layer1,
|
||||
]
|
||||
});
|
||||
originalLayerIds = activeDocument.layers.map( layer => layer.id );
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -49,28 +58,28 @@ describe( "reorder layers action", () => {
|
||||
});
|
||||
|
||||
it( "should be able to reorder the Layers within the Document by their ids", () => {
|
||||
reorderLayers( store, document, shuffledLayerIds);
|
||||
reorderLayers( store, activeDocument, shuffledLayerIds);
|
||||
|
||||
expect( store.commit ).toHaveBeenCalledTimes( 1 );
|
||||
expect( store.commit ).toHaveBeenCalledWith( "reorderLayers", {
|
||||
document,
|
||||
activeDocument,
|
||||
layerIds: shuffledLayerIds,
|
||||
});
|
||||
});
|
||||
|
||||
it( "should be able to reorder the Layers within the Document when receiving only a subset of all Layer content", () => {
|
||||
const shuffledSubSet = [ tile2layer3.id, tile2layer1.id, tile2layer2.id ];
|
||||
reorderLayers( store, document, shuffledSubSet);
|
||||
reorderLayers( store, activeDocument, shuffledSubSet);
|
||||
|
||||
expect( store.commit ).toHaveBeenCalledTimes( 1 );
|
||||
expect( store.commit ).toHaveBeenCalledWith( "reorderLayers", {
|
||||
document,
|
||||
activeDocument,
|
||||
layerIds: shuffledLayerIds, // expect shuffled set to have been applied to full content
|
||||
});
|
||||
});
|
||||
|
||||
it( "should store the action in state history", () => {
|
||||
reorderLayers( store, document, shuffledLayerIds );
|
||||
reorderLayers( store, activeDocument, shuffledLayerIds );
|
||||
|
||||
expect( mockEnqueueState ).toHaveBeenCalledWith(
|
||||
`reorderLayers_${shuffledLayerIds.join()}`, {
|
||||
@@ -81,20 +90,20 @@ describe( "reorder layers action", () => {
|
||||
});
|
||||
|
||||
it( "should restore the original order when calling undo in state history", () => {
|
||||
reorderLayers( store, document, shuffledLayerIds );
|
||||
reorderLayers( store, activeDocument, shuffledLayerIds );
|
||||
|
||||
const { undo } = mockEnqueueState.mock.calls[ 0 ][ 1 ];
|
||||
undo();
|
||||
|
||||
expect( store.commit ).toHaveBeenCalledTimes( 2 );
|
||||
expect( store.commit ).toHaveBeenNthCalledWith( 2, "reorderLayers", {
|
||||
document,
|
||||
activeDocument,
|
||||
layerIds: originalLayerIds,
|
||||
});
|
||||
});
|
||||
|
||||
it( "should reapply the new order when calling redo in state history", () => {
|
||||
reorderLayers( store, document, shuffledLayerIds );
|
||||
reorderLayers( store, activeDocument, shuffledLayerIds );
|
||||
|
||||
const { undo, redo } = mockEnqueueState.mock.calls[ 0 ][ 1 ];
|
||||
undo();
|
||||
@@ -102,8 +111,25 @@ describe( "reorder layers action", () => {
|
||||
|
||||
expect( store.commit ).toHaveBeenCalledTimes( 3 );
|
||||
expect( store.commit ).toHaveBeenNthCalledWith( 3, "reorderLayers", {
|
||||
document,
|
||||
activeDocument,
|
||||
layerIds: shuffledLayerIds,
|
||||
});
|
||||
});
|
||||
|
||||
it( "should request a re-render of tiles associated with the layers", () => {
|
||||
reorderLayers( store, activeDocument, shuffledLayerIds );
|
||||
|
||||
expect( mockCreateGroupTile ).toHaveBeenCalledTimes( 3 );
|
||||
expect( mockCreateGroupTile ).toHaveBeenNthCalledWith( 1, 0, activeDocument );
|
||||
expect( mockCreateGroupTile ).toHaveBeenNthCalledWith( 2, 1, activeDocument );
|
||||
expect( mockCreateGroupTile ).toHaveBeenNthCalledWith( 3, 2, activeDocument );
|
||||
});
|
||||
|
||||
it( "should not request a re-render of tiles associated with the layers for non-timeline type Documents", () => {
|
||||
activeDocument.type = "default";
|
||||
|
||||
reorderLayers( store, activeDocument, shuffledLayerIds );
|
||||
|
||||
expect( mockCreateGroupTile ).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -523,7 +523,7 @@ describe( "Vuex document module", () => {
|
||||
documents: [ DocumentFactory.create({ name: "foo", layers })],
|
||||
activeIndex: 0
|
||||
});
|
||||
mutations.reorderLayers( state, { document: state.documents[ 0 ], layerIds: [
|
||||
mutations.reorderLayers( state, { activeDocument: state.documents[ 0 ], layerIds: [
|
||||
layers[ 1 ].id, layers[ 2 ].id, layers[ 0 ].id, layers[ 3 ].id
|
||||
] });
|
||||
// note we check by reference to ensure all bindings remain
|
||||
|
||||
Reference in New Issue
Block a user