diff --git a/src/app/class/card-stack.ts b/src/app/class/card-stack.ts index 1198736a5..6f5e17e28 100644 --- a/src/app/class/card-stack.ts +++ b/src/app/class/card-stack.ts @@ -118,7 +118,7 @@ export class CardStack extends TabletopObject { putOnTop(card: Card): Card { if (!this.cardRoot) return null; if (!this.topCard) return this.putOnBottom(card); - card.owner = ''; + card.owners = []; card.zindex = 0; let delta = Math.abs(card.rotate - this.rotate); if (180 < delta) delta = 360 - delta; @@ -129,7 +129,7 @@ export class CardStack extends TabletopObject { putOnBottom(card: Card): Card { if (!this.cardRoot) return null; - card.owner = ''; + card.owners = []; card.zindex = 0; let delta = Math.abs(card.rotate - this.rotate); if (180 < delta) delta = 360 - delta; diff --git a/src/app/class/card.ts b/src/app/class/card.ts index d97196f04..0923e8420 100644 --- a/src/app/class/card.ts +++ b/src/app/class/card.ts @@ -15,7 +15,7 @@ export enum CardState { export class Card extends TabletopObject { @SyncVar() state: CardState = CardState.FRONT; @SyncVar() rotate: number = 0; - @SyncVar() owner: string = ''; + @SyncVar() owners: Array = []; @SyncVar() zindex: number = 0; get isVisibleOnTable(): boolean { return this.location.name === 'table' && (!this.parentIsAssigned || this.parentIsDestroyed); } @@ -29,23 +29,25 @@ export class Card extends TabletopObject { get imageFile(): ImageFile { return this.isVisible ? this.frontImage : this.backImage; } get ownerName(): string { - let object = PeerCursor.findByUserId(this.owner); - return object ? object.name : ''; + return this.owners.map(owner => PeerCursor.findByUserId(owner)) + .filter(peerCursor => peerCursor) + .map(peerCursor => peerCursor.name) + .join(', '); } - get hasOwner(): boolean { return 0 < this.owner.length; } - get isHand(): boolean { return Network.peerContext.userId === this.owner; } + get hasOwner(): boolean { return 0 < this.owners.length; } + get isHand(): boolean { return this.owners.includes(Network.peerContext.userId); } get isFront(): boolean { return this.state === CardState.FRONT; } get isVisible(): boolean { return this.isHand || this.isFront; } faceUp() { this.state = CardState.FRONT; - this.owner = ''; + this.owners = []; } faceDown() { this.state = CardState.BACK; - this.owner = ''; + this.owners = []; } toTopmost() { diff --git a/src/app/component/card/card.component.ts b/src/app/component/card/card.component.ts index 2a56edf48..0a6728aa5 100644 --- a/src/app/component/card/card.component.ts +++ b/src/app/component/card/card.component.ts @@ -43,8 +43,8 @@ export class CardComponent implements OnInit, OnDestroy, AfterViewInit { set state(state: CardState) { this.card.state = state; } get rotate(): number { return this.card.rotate; } set rotate(rotate: number) { this.card.rotate = rotate; } - get owner(): string { return this.card.owner; } - set owner(owner: string) { this.card.owner = owner; } + get owners(): Array { return this.card.owners; } + set owners(owners: Array) { this.card.owners = owners; } get zindex(): number { return this.card.zindex; } get size(): number { return this.adjustMinBounds(this.card.size); } @@ -89,7 +89,7 @@ export class CardComponent implements OnInit, OnDestroy, AfterViewInit { if (!this.card || !object) return; if ((this.card === object) || (object instanceof ObjectNode && this.card.contains(object)) - || (object instanceof PeerCursor && object.userId === this.card.owner)) { + || (object instanceof PeerCursor && this.card.owners.includes(object.userId))) { this.changeDetector.markForCheck(); } }) @@ -101,7 +101,7 @@ export class CardComponent implements OnInit, OnDestroy, AfterViewInit { }) .on('DISCONNECT_PEER', event => { let cursor = PeerCursor.findByPeerId(event.data.peerId); - if (!cursor || this.card.owner === cursor.userId) this.changeDetector.markForCheck(); + if (!cursor || this.card.owners.includes(cursor.userId)) this.changeDetector.markForCheck(); }); this.movableOption = { tabletopObject: this.card, @@ -173,7 +173,7 @@ export class CardComponent implements OnInit, OnDestroy, AfterViewInit { console.log('onDoubleClick !!!!'); if (this.hasOwner && !this.isHand) return; this.state = this.isVisible && !this.isHand ? CardState.BACK : CardState.FRONT; - this.owner = ''; + this.owners = []; SoundEffect.play(PresetSound.cardDraw); } } @@ -213,8 +213,8 @@ export class CardComponent implements OnInit, OnDestroy, AfterViewInit { ), (this.isHand ? { - name: '裏にする', action: () => { - this.card.faceDown(); + name: '見るのをやめる', action: () => { + this.owners = this.owners.filter(owner => owner !== Network.peerContext.userId); SoundEffect.play(PresetSound.cardDraw); } } @@ -222,9 +222,22 @@ export class CardComponent implements OnInit, OnDestroy, AfterViewInit { name: '自分だけ見る', action: () => { SoundEffect.play(PresetSound.cardDraw); this.card.faceDown(); - this.owner = Network.peerContext.userId; + this.owners = [Network.peerContext.userId]; } }), + (!this.isHand && this.hasOwner + ? { + name: '自分も見る', action: () => { + SoundEffect.play(PresetSound.cardDraw); + let newOwners = this.owners.concat(Network.peerContext.userId); + this.card.faceDown(); + this.owners = newOwners; + } + } + : { + name: null, enabled: false + } + ), ContextMenuSeparator, { name: '重なったカードで山札を作る', action: () => { diff --git a/src/app/service/context-menu.service.ts b/src/app/service/context-menu.service.ts index 3945aa315..1a56699b7 100644 --- a/src/app/service/context-menu.service.ts +++ b/src/app/service/context-menu.service.ts @@ -61,7 +61,7 @@ export class ContextMenuService { childPanelService.panelComponentRef = panelComponentRef; if (actions) { - childPanelService.actions = actions; + childPanelService.actions = actions.filter(act => act.enabled === undefined || act.enabled); } if (position) { childPanelService.position.x = position.x;