Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

90 prompt before navigating during draft #34

Merged
merged 2 commits into from
Jul 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions src/components/Messages/PromptDirtyDraft.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<template>
<Modal :is-open="isModalOpen" @close-modal="closeModal">
<template v-slot:title>Draft will be lost.</template>
<div class="font-semibold">
<p>Are you sure you want to leave?</p>
<p>Your thread draft will be lost.</p>
</div>
<template v-slot:actions>
<button class="btn success" @click="emit('response', true)">Yes</button>
<button class="btn error" @click="emit('response', false)">No</button>
</template>
</Modal>
</template>

<script setup>
import { TrashIcon } from "@heroicons/vue/outline";
import { ref } from "@vue/reactivity";
import { watch } from "vue";
import Modal from "../Shared/Modal.vue";

const props = defineProps({
show: {
type: Boolean,
required: true,
},
});

const emit = defineEmits(["response"]);

const isModalOpen = ref(false);

watch(
() => props.show,
async (val) => {
if (val) {
window.scrollTo({ top: 0, left: 0 });
document.querySelector("body").classList.add("modal-open");
isModalOpen.value = true;
} else {
document.querySelector("body").classList.remove("modal-open");
isModalOpen.value = false;
}
}
);

function closeModal() {}

function openModal() {}
</script>

<style scoped>
.btn {
@apply w-20 my-2 bg-white border-2 border-gray-500 text-lg h-10 leading-3 hover:text-white cursor-pointer;
}

.btn.success {
@apply hover:bg-green-500;
}

.btn.error {
@apply hover:bg-red-500;
}
</style>
46 changes: 45 additions & 1 deletion src/views/MessagesPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,11 @@
placeholder="Message (hit enter to send)"
>
</textarea>
<PromptDirtyDraft :show="prompt" @response="response" />
</template>

<script setup>
import { useRoute } from "vue-router";
import { useRoute, onBeforeRouteLeave, onBeforeRouteUpdate } from "vue-router";
import {
onMounted,
ref,
Expand All @@ -53,6 +54,7 @@ import {
} from "vue";
import MessagesView from "../components/Messages/MessagesView.vue";
import TagList from "../components/Messages/TagList.vue";
import PromptDirtyDraft from "../components/Messages/PromptDirtyDraft.vue";
import useStore from "../composables/global/useStore";
import SocketioService from "../service/socket.service";
import { VueCookieNext } from "vue-cookie-next";
Expand Down Expand Up @@ -86,6 +88,47 @@ const thread = ref(getThread(route.params.threadId));
const searchTag = ref("");
const goodReputation = ref(false);
const wsInstance = reactive({});

/**
* Dialog feature
*/
const resolve = ref({});
const reject = ref({});
const prompt = ref(false);

onBeforeRouteLeave(async (to, from) => {
return await processDirtyMessage();
});

onBeforeRouteUpdate(async (to, from) => {
return await processDirtyMessage();
});

const processDirtyMessage = async () => {
const promise = new Promise((res, rej) => {
resolve.value = res;
reject.value = rej;
});
if (message.value.trim().length > 0) {
prompt.value = true;
} else {
resolve.value(true);
}
let val = await promise;
if (val) {
message.value = "";
}
return val;
};

/**
* Dialog prompt response call
*/
const response = (value) => {
resolve.value(value);
prompt.value = false;
};

/**
* Get tags based on messages
*/
Expand Down Expand Up @@ -311,6 +354,7 @@ onUnmounted(() => {
textarea {
resize: none;
}

.messages-title {
@apply overflow-hidden;
text-overflow: ellipsis;
Expand Down
3 changes: 2 additions & 1 deletion src/views/ThreadsPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ const isThreadActive = ref(false);
const isThreadOwner = computed(
() => getId.value === getActiveThread.value?.owner
);
const isChannelOwner = computed(() => getId.value === channel.value?.owner);
/**
* Watch thread id to show/hide edit/delete buttons on the side of
* create thread button
Expand Down Expand Up @@ -142,7 +143,7 @@ function threadHandler(data) {
}

const canEditDelete = computed(
() => isThreadOwner.value && isThreadActive.value
() => (isThreadOwner.value || isChannelOwner.value) && isThreadActive.value
);

async function processDelete() {
Expand Down