feat: 사령부에서 다른 수뇌의 턴을 '복사하기' 기능
This commit is contained in:
@@ -31,11 +31,16 @@ $modcolor2: color.adjust($nbase2color, $lightness: -5%);
|
|||||||
line-height: 30px;
|
line-height: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.time_pad.inverted{
|
||||||
|
background-color: gray;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
.turn_pad {
|
.turn_pad {
|
||||||
line-height: 30px;
|
line-height: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.row:nth-child(odd) .turn_pad {
|
.row:nth-of-type(odd) .turn_pad {
|
||||||
background-color: $modcolor2;
|
background-color: $modcolor2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,7 +88,7 @@ $modcolor2: color.adjust($nbase2color, $lightness: -5%);
|
|||||||
}
|
}
|
||||||
|
|
||||||
.commandBox .controlPad {
|
.commandBox .controlPad {
|
||||||
.turn_pad:nth-child(2n) {
|
.turn_pad:nth-of-type(even) {
|
||||||
background-color: $modcolor2;
|
background-color: $modcolor2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,7 +135,7 @@ $modcolor2: color.adjust($nbase2color, $lightness: -5%);
|
|||||||
.commandBox .controlPad {
|
.commandBox .controlPad {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
|
||||||
.turn_pad:nth-child(even) {
|
.turn_pad:nth-of-type(even) {
|
||||||
background-color: $modcolor2;
|
background-color: $modcolor2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -144,7 +149,7 @@ $modcolor2: color.adjust($nbase2color, $lightness: -5%);
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
|
|
||||||
.turn_pad:nth-child(even) {
|
.turn_pad:nth-of-type(even) {
|
||||||
background-color: $modcolor2;
|
background-color: $modcolor2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+150
-68
@@ -1,88 +1,170 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :class="['subRows', 'chiefCommand']" :style="style">
|
<div style="position:relative">
|
||||||
<div class="bg1 center row gx-0" style="font-size: 1.2em">
|
<DragSelect
|
||||||
<div class="col-5 align-self-center text-end">
|
:class="['subRows', 'chiefCommand']"
|
||||||
{{ officer ? `${officer.officerLevelText} : ` : "" }}
|
:style="style"
|
||||||
|
:disabled="!props.officer || !isEditMode"
|
||||||
|
attribute="turnIdx"
|
||||||
|
@dragStart="dragStart()"
|
||||||
|
@dragDone="dragDone(...$event)"
|
||||||
|
v-slot="{ selected }"
|
||||||
|
>
|
||||||
|
<div class="bg1 center row gx-0" style="font-size: 1.2em">
|
||||||
|
<div
|
||||||
|
class="col-5 align-self-center text-end"
|
||||||
|
>{{ officer ? `${officer.officerLevelText} : ` : "" }}</div>
|
||||||
|
<div
|
||||||
|
class="col-7 align-self-center"
|
||||||
|
:style="{
|
||||||
|
color: getNpcColor(officer?.npcType ?? 0),
|
||||||
|
}"
|
||||||
|
>{{ officer?.name }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div :turnIdx="vidx" class="row c-bg2 gx-0" v-for="vidx in maxTurn" :key="vidx">
|
||||||
class="col-7 align-self-center"
|
<div
|
||||||
:style="{
|
:class="['col-2', 'time_pad', 'f_tnum', ((isDragToggle || isCopyButtonShown) && selected.has(vidx.toString())) ? 'inverted' : undefined]"
|
||||||
color: getNpcColor(officer?.npcType ?? 0),
|
>{{ turnTimes[vidx - 1] }}</div>
|
||||||
}"
|
<div class="center" v-if="!officer || (!officer.turn) || !(vidx - 1 in officer.turn)"></div>
|
||||||
>
|
<div
|
||||||
{{ officer?.name }}
|
v-else
|
||||||
|
class="tableCell align-self-center col-10 center turn_pad"
|
||||||
|
:style="{
|
||||||
|
fontSize:
|
||||||
|
mb_strwidth(officer.turn[vidx - 1].brief) > 28
|
||||||
|
? `${28 / mb_strwidth(officer.turn[vidx - 1].brief)}em`
|
||||||
|
: undefined,
|
||||||
|
}"
|
||||||
|
>{{ officer.turn[vidx - 1].brief }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</DragSelect>
|
||||||
<div class="row c-bg2 gx-0" v-for="vidx in maxTurn" :key="vidx">
|
<BButton
|
||||||
<div class="col-2 time_pad f_tnum">
|
ref="btnCopy"
|
||||||
{{ turnTimes[vidx - 1] }}
|
:style="{
|
||||||
</div>
|
position: 'absolute',
|
||||||
<div
|
display: isCopyButtonShown ? 'block' : 'none',
|
||||||
class="center"
|
top: `${btnPos * 30 + 25}px`,
|
||||||
v-if="!officer || (!officer.turn) || !(vidx - 1 in officer.turn)"
|
right: '10px',
|
||||||
></div>
|
}"
|
||||||
<div
|
@blur="isCopyButtonShown = false"
|
||||||
v-else
|
@click="tryCopy()"
|
||||||
class="tableCell align-self-center col-10 center turn_pad"
|
>복사하기</BButton>
|
||||||
:style="{
|
|
||||||
fontSize:
|
|
||||||
mb_strwidth(officer.turn[vidx - 1].brief) > 28
|
|
||||||
? `${28 / mb_strwidth(officer.turn[vidx - 1].brief)}em`
|
|
||||||
: undefined,
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
{{ officer.turn[vidx - 1].brief }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script setup lang="ts">
|
||||||
import { getNpcColor } from "@/common_legacy";
|
import { getNpcColor } from "@/common_legacy";
|
||||||
import type { ChiefResponse } from "@/defs";
|
import type { ChiefResponse } from "@/defs";
|
||||||
import { formatTime } from "@/util/formatTime";
|
import { formatTime } from "@/util/formatTime";
|
||||||
import { mb_strwidth } from "@/util/mb_strwidth";
|
import { mb_strwidth } from "@/util/mb_strwidth";
|
||||||
import { parseTime } from "@/util/parseTime";
|
import { parseTime } from "@/util/parseTime";
|
||||||
|
import type { StoredActionsHelper } from "@/util/StoredActionsHelper";
|
||||||
import addMinutes from "date-fns/esm/addMinutes/index";
|
import addMinutes from "date-fns/esm/addMinutes/index";
|
||||||
import { range } from "lodash";
|
import { range } from "lodash";
|
||||||
import { defineComponent, type PropType } from "vue";
|
import { defineProps, inject, onMounted, ref, type PropType } from "vue";
|
||||||
import VueTypes from "vue-types";
|
import VueTypes from "vue-types";
|
||||||
|
import DragSelect from "@/components/DragSelect.vue";
|
||||||
|
import { BButton } from "bootstrap-vue-3";
|
||||||
|
import { QueryActionHelper } from "@/util/QueryActionHelper";
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
props: {
|
const props = defineProps({
|
||||||
style: VueTypes.object.isRequired,
|
style: VueTypes.object.isRequired,
|
||||||
officer: {
|
officer: {
|
||||||
type: Object as PropType<ChiefResponse["chiefList"][0]>,
|
type: Object as PropType<ChiefResponse["chiefList"][0]>,
|
||||||
},
|
|
||||||
turnTerm: VueTypes.integer.isRequired,
|
|
||||||
maxTurn: VueTypes.integer.isRequired,
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getNpcColor,
|
|
||||||
mb_strwidth,
|
|
||||||
},
|
},
|
||||||
|
turnTerm: VueTypes.integer.isRequired,
|
||||||
|
maxTurn: VueTypes.integer.isRequired,
|
||||||
|
})
|
||||||
|
|
||||||
data() {
|
const btnPos = ref(0);
|
||||||
const turnTimes: string[] = [];
|
const btnCopy = ref<InstanceType<typeof BButton> | null>(null);
|
||||||
if (!this.officer || !this.officer.turnTime) {
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
for (const _ of range(this.maxTurn)) {
|
|
||||||
turnTimes.push("\xa0");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const baseTurnTime = parseTime(this.officer.turnTime);
|
|
||||||
for (const idx of range(this.officer.turn.length)) {
|
|
||||||
turnTimes.push(
|
|
||||||
formatTime(
|
|
||||||
addMinutes(baseTurnTime, idx * this.turnTerm),
|
|
||||||
this.turnTerm >= 5 ? "HH:mm" : "mm:ss"
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const storedActionsHelper = inject<StoredActionsHelper>('storedNationActionsHelper');
|
||||||
|
const isEditMode = (storedActionsHelper?.isEditMode) ?? ref(false);
|
||||||
|
const isDragToggle = ref(false);
|
||||||
|
|
||||||
|
const isCopyButtonShown = ref(false);
|
||||||
|
|
||||||
|
const queryActionHelper = new QueryActionHelper(props.maxTurn);
|
||||||
|
const selectedTurnList = queryActionHelper.selectedTurnList;
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (props.officer === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
queryActionHelper.reservedCommandList.value = props.officer.turn.map(rawTurn => {
|
||||||
return {
|
return {
|
||||||
turnTimes,
|
...rawTurn,
|
||||||
};
|
time: '',
|
||||||
},
|
}
|
||||||
|
});
|
||||||
|
console.log(queryActionHelper.reservedCommandList.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function dragStart() {
|
||||||
|
isDragToggle.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function eqSet<T>(as: Set<T>, bs: Set<T>) {
|
||||||
|
if (as.size !== bs.size) return false;
|
||||||
|
for (var a of as) if (!bs.has(a)) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragDone(...rawSelectedTurn: string[]) {
|
||||||
|
if (rawSelectedTurn.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const newSelectedTurnList = new Set<number>();
|
||||||
|
|
||||||
|
let maxPos = -1;
|
||||||
|
for (const rawIdx of rawSelectedTurn) {
|
||||||
|
const idx = parseInt(rawIdx) - 1;
|
||||||
|
newSelectedTurnList.add(idx);
|
||||||
|
maxPos = Math.max(maxPos, idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
btnPos.value = maxPos;
|
||||||
|
|
||||||
|
isDragToggle.value = false;
|
||||||
|
if (newSelectedTurnList.size == 1 && eqSet(selectedTurnList.value, newSelectedTurnList)) {
|
||||||
|
isCopyButtonShown.value = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
selectedTurnList.value = newSelectedTurnList;
|
||||||
|
isCopyButtonShown.value = true;
|
||||||
|
setTimeout(() => {
|
||||||
|
(btnCopy.value?.$el as HTMLButtonElement).focus();
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function tryCopy() {
|
||||||
|
|
||||||
|
const actions = queryActionHelper.extractQueryActions();
|
||||||
|
isCopyButtonShown.value = false;
|
||||||
|
|
||||||
|
if (!storedActionsHelper) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
storedActionsHelper.clipboard.value = [...actions];
|
||||||
|
}
|
||||||
|
|
||||||
|
const turnTimes = ref<string[]>([]);
|
||||||
|
|
||||||
|
if (!props.officer || !props.officer.turnTime) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
for (const _ of range(props.maxTurn)) {
|
||||||
|
turnTimes.value.push("\xa0");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const baseTurnTime = parseTime(props.officer.turnTime);
|
||||||
|
for (const idx of range(props.officer.turn.length)) {
|
||||||
|
turnTimes.value.push(
|
||||||
|
formatTime(
|
||||||
|
addMinutes(baseTurnTime, idx * props.turnTerm),
|
||||||
|
props.turnTerm >= 5 ? "HH:mm" : "mm:ss"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -38,9 +38,6 @@
|
|||||||
/>
|
/>
|
||||||
<ChiefReservedCommand
|
<ChiefReservedCommand
|
||||||
v-else
|
v-else
|
||||||
:serverNick="serverNick"
|
|
||||||
:mapName="mapName"
|
|
||||||
:unitSet="unitSet"
|
|
||||||
:key="idx"
|
:key="idx"
|
||||||
:targetIsMe="targetIsMe"
|
:targetIsMe="targetIsMe"
|
||||||
:year="year"
|
:year="year"
|
||||||
@@ -113,7 +110,7 @@ import "@scss/common/bootstrap5.scss";
|
|||||||
import "@scss/game_bg.scss";
|
import "@scss/game_bg.scss";
|
||||||
import "../../css/config.css";
|
import "../../css/config.css";
|
||||||
|
|
||||||
import { computed, defineProps, reactive, ref, toRefs, watch } from "vue";
|
import { computed, defineProps, provide, reactive, ref, toRefs, watch } from "vue";
|
||||||
import ChiefReservedCommand from "@/components/ChiefReservedCommand.vue";
|
import ChiefReservedCommand from "@/components/ChiefReservedCommand.vue";
|
||||||
import TopBackBar from "@/components/TopBackBar.vue";
|
import TopBackBar from "@/components/TopBackBar.vue";
|
||||||
import BottomBar from "@/components/BottomBar.vue";
|
import BottomBar from "@/components/BottomBar.vue";
|
||||||
@@ -126,6 +123,7 @@ import BottomItem from "@/ChiefCenter/BottomItem.vue";
|
|||||||
import type { ChiefResponse, OptionalFull } from "./defs";
|
import type { ChiefResponse, OptionalFull } from "./defs";
|
||||||
import { SammoAPI } from "./SammoAPI";
|
import { SammoAPI } from "./SammoAPI";
|
||||||
import { unwrap } from "@/util/unwrap";
|
import { unwrap } from "@/util/unwrap";
|
||||||
|
import { StoredActionsHelper } from "./util/StoredActionsHelper";
|
||||||
|
|
||||||
const {
|
const {
|
||||||
serverNick,
|
serverNick,
|
||||||
@@ -236,6 +234,8 @@ const subTableGridRows = computed(() => {
|
|||||||
|
|
||||||
void reloadTable();
|
void reloadTable();
|
||||||
|
|
||||||
|
const storedActionsHelper = new StoredActionsHelper(staticValues.serverNick, 'nation', staticValues.mapName, staticValues.unitSet);
|
||||||
|
provide('storedNationActionsHelper', storedActionsHelper);
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|||||||
@@ -289,7 +289,7 @@ toggleTurn(...$event);
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import addMinutes from "date-fns/esm/addMinutes";
|
import addMinutes from "date-fns/esm/addMinutes";
|
||||||
import { stringifyUrl } from "query-string";
|
import { stringifyUrl } from "query-string";
|
||||||
import { defineProps, defineEmits, defineExpose, onMounted, ref, watch, type PropType } from "vue";
|
import { defineProps, defineEmits, defineExpose, onMounted, ref, watch, type PropType, inject } from "vue";
|
||||||
import { formatTime } from "@util/formatTime";
|
import { formatTime } from "@util/formatTime";
|
||||||
import { joinYearMonth } from "@util/joinYearMonth";
|
import { joinYearMonth } from "@util/joinYearMonth";
|
||||||
import { mb_strwidth } from "@util/mb_strwidth";
|
import { mb_strwidth } from "@util/mb_strwidth";
|
||||||
@@ -303,7 +303,7 @@ import { SammoAPI } from "@/SammoAPI";
|
|||||||
import type { ChiefResponse, CommandItem, TurnObj } from "@/defs";
|
import type { ChiefResponse, CommandItem, TurnObj } from "@/defs";
|
||||||
import { QueryActionHelper } from "@/util/QueryActionHelper";
|
import { QueryActionHelper } from "@/util/QueryActionHelper";
|
||||||
import type { Args } from "@/processing/args";
|
import type { Args } from "@/processing/args";
|
||||||
import { StoredActionsHelper } from "@/util/StoredActionsHelper";
|
import type { StoredActionsHelper } from "@/util/StoredActionsHelper";
|
||||||
import { getNpcColor } from "@/common_legacy";
|
import { getNpcColor } from "@/common_legacy";
|
||||||
import { BButton, BDropdownItem, BDropdownText, BButtonGroup, BDropdownDivider, BDropdown } from "bootstrap-vue-3";
|
import { BButton, BDropdownItem, BDropdownText, BButtonGroup, BDropdownDivider, BDropdown } from "bootstrap-vue-3";
|
||||||
import addMilliseconds from "date-fns/addMilliseconds";
|
import addMilliseconds from "date-fns/addMilliseconds";
|
||||||
@@ -319,10 +319,6 @@ type TurnObjWithTime = TurnObj & {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
serverNick: VueTypes.string.isRequired,
|
|
||||||
mapName: VueTypes.string.isRequired,
|
|
||||||
unitSet: VueTypes.string.isRequired,
|
|
||||||
|
|
||||||
maxTurn: VueTypes.integer.isRequired,
|
maxTurn: VueTypes.integer.isRequired,
|
||||||
maxPushTurn: VueTypes.integer.isRequired,
|
maxPushTurn: VueTypes.integer.isRequired,
|
||||||
date: VueTypes.string.isRequired,
|
date: VueTypes.string.isRequired,
|
||||||
@@ -613,7 +609,7 @@ function chooseCommand(val?: string) {
|
|||||||
const emptyTurnObj: TurnObj = { action: '휴식', brief: '휴식', arg: {} };
|
const emptyTurnObj: TurnObj = { action: '휴식', brief: '휴식', arg: {} };
|
||||||
|
|
||||||
|
|
||||||
const storedActionsHelper = new StoredActionsHelper(props.serverNick, 'nation', props.mapName, props.unitSet);
|
const storedActionsHelper = inject('storedNationActionsHelper') as StoredActionsHelper;
|
||||||
|
|
||||||
const recentActions = storedActionsHelper.recentActions;
|
const recentActions = storedActionsHelper.recentActions;
|
||||||
const storedActions = storedActionsHelper.storedActions;
|
const storedActions = storedActionsHelper.storedActions;
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ export default defineComponent({
|
|||||||
document.addEventListener("touchmove", touchMove);
|
document.addEventListener("touchmove", touchMove);
|
||||||
box.style.top = start.y + "px";
|
box.style.top = start.y + "px";
|
||||||
box.style.left = start.x + "px";
|
box.style.left = start.x + "px";
|
||||||
uContainer.prepend(box);
|
uContainer.append(box);
|
||||||
intersection();
|
intersection();
|
||||||
isMine = true;
|
isMine = true;
|
||||||
emit("dragStart");
|
emit("dragStart");
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ export class StoredActionsHelper {
|
|||||||
this.clipboard.value = JSON.parse(rawClipboard);
|
this.clipboard.value = JSON.parse(rawClipboard);
|
||||||
}
|
}
|
||||||
watch(this.clipboard, (newValue) => {
|
watch(this.clipboard, (newValue) => {
|
||||||
console.log(newValue);
|
|
||||||
localStorage.setItem(this.clipboardKey, JSON.stringify(newValue));
|
localStorage.setItem(this.clipboardKey, JSON.stringify(newValue));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user