Skip to content

Commit

Permalink
Implement one user concurrent access for storylines.
Browse files Browse the repository at this point in the history
Co-authored-by: szczz <[email protected]>
  • Loading branch information
mohsin-r and szczz committed Dec 16, 2024
1 parent aaef709 commit 4c35f79
Show file tree
Hide file tree
Showing 17 changed files with 847 additions and 198 deletions.
5 changes: 4 additions & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
VITE_APP_API_URL=#{API_URL}#
VITE_APP_SOCKET_URL=#{SOCKET_URL}#
VITE_APP_CURR_ENV=#{CURR_ENV}#
VITE_APP_NET_API_URL=#{NET_API_URL}#
VITE_APP_NET_API_URL=#{NET_API_URL}#
VITE_SESSION_END=#{SESSION_END}#
VITE_SESSION_WARN=#{SESSION_WARN}#
2 changes: 1 addition & 1 deletion server/.env
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ SERVER_CURR_ENV=#{CURR_ENV}#
SERVER_LOG_PATH=#{LOG_PATH}#
SERVER_UPLOAD_PATH=#{UPLOAD_PATH}#
SERVER_TARGET_PATH=#{TARGET_PATH}#
SERVER_API_URL=#{NET_API_URL}#
SERVER_API_URL=#{NET_API_URL}#
265 changes: 220 additions & 45 deletions server/index.js

Large diffs are not rendered by default.

79 changes: 78 additions & 1 deletion server/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,15 @@
"decompress": "^4.2.1",
"dotenv": "^16.3.1",
"express": "^4.18.2",
"express-ws": "^5.0.2",
"formidable": "^2.1.2",
"fs-extra": "^11.1.0",
"https": "^1.0.0",
"moment": "^2.29.4",
"path": "^0.12.7",
"recursive-readdir": "^2.2.3",
"simple-git": "^3.27.0"
"simple-git": "^3.27.0",
"uuid": "^11.0.3",
"ws": "^8.18.0"
}
}
14 changes: 13 additions & 1 deletion server/web.config
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
<configuration>
<system.webServer>
<handlers>
<add name="StorylinesExpress" path="index.js" verb="*" modules="iisnode" />
<add name="StorylinesExpress" path="index.js" verb="*" modules="iisnode" resourceType="Unspecified" />
</handlers>
<webSocket enabled="true" />
<rewrite>
<rules>
<rule name="WebSocket remove keep-alive header" stopProcessing="true">
<match url="(.*)" />
<serverVariables>
<set name="HTTP_CONNECTION" value="Upgrade" />
</serverVariables>
<action type="Rewrite" url="index.js" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_CONNECTION}" pattern="keep-alive, Upgrade" />
<add input="{HTTP_CONNECTION}" pattern="Upgrade, keep-alive" />
</conditions>
</rule>
<rule name="sendToNode">
<match url="/*" />
<action type="Rewrite" url="index.js" />
Expand Down
5 changes: 3 additions & 2 deletions src/app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import { Vue, Watch } from 'vue-property-decorator';
import { RouteLocationNormalized } from 'vue-router';
import { useUserStore } from './stores/userStore';
import { useLockStore } from './stores/lockStore';
export default class App extends Vue {
@Watch('$route', { immediate: true })
Expand All @@ -24,10 +25,10 @@ export default class App extends Vue {
if (import.meta.env.VITE_APP_CURR_ENV) {
userStore.fetchUserProfile();
}
const lockStore = useLockStore();
lockStore.initConnection(); // start the handshake with the web socket server as soon as the app starts to save time
}
}
</script>

<style lang="scss">
Expand Down
7 changes: 5 additions & 2 deletions src/components/editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ import MetadataContentV from './helpers/metadata-content.vue';
import ConfirmationModalV from './helpers/confirmation-modal.vue';
import HelpPanelV from './help-panel.vue';
import HelpSectionV from './helpers/help-section.vue';
import { useLockStore } from '@/stores/lockStore';
@Options({
components: {
Expand Down Expand Up @@ -561,7 +562,7 @@ export default class EditorV extends Vue {
previewConfigs.fr!.slides = previewConfigs.fr!.slides.map((slide) => {
return slide ?? JSON.parse(JSON.stringify(this.defaultBlankSlide));
});
const lockStore = useLockStore();
setTimeout(() => {
const routeData = this.$router.resolve({
name: 'preview',
Expand All @@ -570,7 +571,9 @@ export default class EditorV extends Vue {
const previewTab = window.open(routeData.href, '_blank');
(previewTab as Window).props = {
configs: previewConfigs,
configFileStructure: this.configFileStructure
configFileStructure: this.configFileStructure,
secret: lockStore.secret,
timeRemaining: lockStore.timeRemaining
};
}, 5);
}
Expand Down
5 changes: 4 additions & 1 deletion src/components/helpers/confirmation-modal.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
<template>
<vue-final-modal
:clickToClose="false"
:escToClose="false"
:modalId="name"
class="flex justify-center items-center"
content-class="flex flex-col max-w-xl mx-4 p-4 bg-white dark:bg-gray-900 border dark:border-gray-700 rounded-lg space-y-2"
>
<h2 slot="header" class="text-lg font-bold">{{ message }}</h2>
<h2 slot="header" :class="messageClass ?? 'text-lg font-bold'">{{ message }}</h2>
<div class="w-full flex justify-end">
<button class="editor-button confirm-button hover:bg-gray-800" @click.stop="onOk">
{{ $t('editor.confirm') }}
Expand All @@ -28,6 +30,7 @@ import { VueFinalModal } from 'vue-final-modal';
export default class MetadataEditorV extends Vue {
@Prop() message!: string;
@Prop() name!: string;
@Prop() messageClass?: string;
onOk(): void {
this.$emit('ok');
Expand Down
9 changes: 8 additions & 1 deletion src/components/home.vue
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,13 @@
</template>

<script lang="ts">
import { Vue } from 'vue-property-decorator';
import { Prop, Vue } from 'vue-property-decorator';
import { Storyline, UserProfile, useUserStore } from '../stores/userStore';
import Message from 'vue-m-message';
export default class HomeV extends Vue {
@Prop({ default: false }) sessionExpired!: boolean; // true if user was redirected here due to session expiring, false otherwise
userStore = useUserStore();
currLang = 'en';
sourceFile = 'index.html#';
Expand All @@ -175,6 +178,10 @@ export default class HomeV extends Vue {
mounted(): void {
this.currLang = (this.$route.params.lang as string) || 'en';
this.sourceFile = window.location.href.split('/').find((s) => s.includes('#'));
// If the user was redirected here due to session end, show session end popup.
if (this.sessionExpired) {
Message.error(this.$t('editor.session.ended'));
}
this.userStore
.fetchUserProfile()
.then(() => {
Expand Down
14 changes: 14 additions & 0 deletions src/components/landing.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,26 @@
</template>

<script lang="ts">
import { ref } from 'vue';
import { Vue } from 'vue-property-decorator';
import { useUserStore } from '../stores/userStore';
export default class LandingV extends Vue {
title = document.title;
mounted(): void {
const socketUrl = `${
import.meta.env.VITE_APP_CURR_ENV ? import.meta.env.VITE_APP_API_URL : 'http://localhost:6040'
}`;
const socket = ref(null);
socket.value = new WebSocket(socketUrl + '/Storylines-Editor-STB-Server/');
socket.value.onopen = () => {
console.log('Web socket connected');
};
}
get userName(): string {
const userStore = useUserStore();
return userStore.userProfile?.userName || 'Guest';
Expand Down
Loading

0 comments on commit 4c35f79

Please sign in to comment.