Commit 32327aec by Jonathan Thomas

Use API status for demo mode

parent 5b051b94
VUE_APP_OPENSHOT_API_URL=https://cloud.openshot.org
VUE_APP_GA_ID=UA-4381101-7 VUE_APP_GA_ID=UA-4381101-7
VUE_APP_SHOW_API_LINKS=true VUE_APP_SHOW_API_LINKS=true
...@@ -38,7 +38,7 @@ npm install ...@@ -38,7 +38,7 @@ npm install
npm run serve npm run serve
``` ```
- 1: Modify `.env.development` file and update the `VUE_APP_OPENSHOT_API_URL` variable used in development mode. - 1: Modify `.env.development` and set `VUE_APP_OPENSHOT_API_URL` to the API used by the development server.
This is a required step when building this application for use with your own **OpenShot Cloud API** server. This is a required step when building this application for use with your own **OpenShot Cloud API** server.
- 2: Modify `vue.config.js` file and update the `publicPath` variable to the path you are serving the app from. - 2: Modify `vue.config.js` file and update the `publicPath` variable to the path you are serving the app from.
For example: `/` is the web server root, `/apps/simple-editor` if serving from a sub-folder, etc... For example: `/` is the web server root, `/apps/simple-editor` if serving from a sub-folder, etc...
...@@ -48,8 +48,7 @@ npm run serve ...@@ -48,8 +48,7 @@ npm run serve
npm run build npm run build
``` ```
- 1: Modify `.env.production` file and update the `VUE_APP_OPENSHOT_API_URL` variable used in production/build mode. - 1: Build the app. Production builds use the origin serving Simple Editor as the OpenShot API URL.
This is a required step when building this application for use with your own **OpenShot Cloud API** server.
- 2: Modify `vue.config.js` file and update the `publicPath` variable to the path you are serving the app from. - 2: Modify `vue.config.js` file and update the `publicPath` variable to the path you are serving the app from.
For example: `/` is the web server root, `/apps/simple-editor` if serving from a sub-folder, etc... For example: `/` is the web server root, `/apps/simple-editor` if serving from a sub-folder, etc...
...@@ -99,8 +98,12 @@ npm run lint ...@@ -99,8 +98,12 @@ npm run lint
Configuration variables are stored in `.env` and `vue.config.js` files. Configuration variables are stored in `.env` and `vue.config.js` files.
- `VUE_APP_GA_ID`: Global site tag (gtag.js) for tracking on Google Analytics - `VUE_APP_GA_ID`: Global site tag (gtag.js) for tracking on Google Analytics
- `VUE_APP_OPENSHOT_API_URL`: URL of your own OpenShot Cloud API instance - `VUE_APP_OPENSHOT_API_URL`: Optional API URL override. Production defaults to the origin serving Simple Editor; development can set this when the API runs elsewhere.
- `VUE_APP_SHOW_API_LINKS`: Set to `false` to hide the API navigation link and all contextual "View in API" actions (defaults to enabled) - `VUE_APP_SHOW_API_LINKS`: Set to `false` to hide the API navigation link and all contextual "View in API" actions (defaults to enabled)
- `publicPath`: Relative path where this app will be served by your production web server - `publicPath`: Relative path where this app will be served by your production web server
Simple Editor reads the API version and demo-mode state from the public
`/info/status/` endpoint. If that request is unavailable, it safely defaults to
normal (non-demo) behavior.
See [Configuration Reference](https://cli.vuejs.org/config/). See [Configuration Reference](https://cli.vuejs.org/config/).
...@@ -586,18 +586,12 @@ export default { ...@@ -586,18 +586,12 @@ export default {
}, },
computed: { computed: {
...mapGetters(['totalClipDuration', 'thumbnailedClips']), ...mapGetters(['totalClipDuration', 'thumbnailedClips']),
...mapState(['clips', 'preview', 'scrollToClip', 'current_export']), ...mapState(['clips', 'preview', 'scrollToClip', 'current_export', 'apiStatus']),
isDragging() { isDragging() {
return !!this.draggingClip return !!this.draggingClip
}, },
isDemoMode() { isDemoMode() {
const apiUrl = (process.env.VUE_APP_OPENSHOT_API_URL || '').trim() return this.apiStatus.demo_mode
if (!apiUrl) {
return false
}
const normalized = apiUrl.replace(/\/+$/, '').toLowerCase()
const host = normalized.replace(/^https?:\/\//, '')
return host.startsWith('cloud.openshot.org')
}, },
isExportInProgress() { isExportInProgress() {
const hasPendingRecord = !!(this.current_export && this.current_export.id && !this.current_export.output) const hasPendingRecord = !!(this.current_export && this.current_export.id && !this.current_export.output)
......
...@@ -49,7 +49,7 @@ export default { ...@@ -49,7 +49,7 @@ export default {
this.creating = true this.creating = true
this.error = null this.error = null
try { try {
const response = await instance.post('/demo-access/') const response = await instance.post('/auth/demo/')
const auth = `Basic ${btoa(`${response.data.username}:${response.data.password}`)}` const auth = `Basic ${btoa(`${response.data.username}:${response.data.password}`)}`
localStorage.auth = auth localStorage.auth = auth
this.auth = auth this.auth = auth
......
...@@ -14,7 +14,7 @@ export default { ...@@ -14,7 +14,7 @@ export default {
data() { return { isDemo: false, expiresAt: null, remaining: '--:--:--', timer: null } }, data() { return { isDemo: false, expiresAt: null, remaining: '--:--:--', timer: null } },
async mounted() { async mounted() {
try { try {
const response = await instance.get('/demo-access/status/') const response = await instance.get('/auth/demo/')
if (response.data.is_demo) { if (response.data.is_demo) {
this.isDemo = true this.isDemo = true
const secondsRemaining = Math.max(1, Number(response.data.seconds_remaining) || 0) const secondsRemaining = Math.max(1, Number(response.data.seconds_remaining) || 0)
......
export function getCloudApiUrl() {
const configured = (process.env.VUE_APP_OPENSHOT_API_URL || '').trim()
if (configured) {
return configured.replace(/\/+$/, '')
}
if (typeof window !== 'undefined' && window.location?.origin) {
return window.location.origin
}
return ''
}
...@@ -5,7 +5,7 @@ import store from './store' ...@@ -5,7 +5,7 @@ import store from './store'
import "bootstrap/dist/css/bootstrap.min.css" import "bootstrap/dist/css/bootstrap.min.css"
import "bootstrap" import "bootstrap"
import { createGtag } from "vue-gtag" import { createGtag } from "vue-gtag"
import { initAdsConversions, isDemoEnvironment } from "./utils/adsConversions" import { initAdsConversions } from "./utils/adsConversions"
const app = createApp(App) const app = createApp(App)
...@@ -23,9 +23,13 @@ if (tagId) { ...@@ -23,9 +23,13 @@ if (tagId) {
})) }))
} }
initAdsConversions({ async function start() {
await store.dispatch('loadApiStatus')
initAdsConversions({
router, router,
demoMode: isDemoEnvironment() demoMode: store.state.apiStatus.demo_mode
}) })
app.use(store).use(router).mount('#app')
}
app.use(store).use(router).mount('#app') start()
import axios from "axios"; import axios from "axios";
import { getCloudApiUrl } from "../config";
// Init a new axios instance, with auth // Init a new axios instance, with auth
const instance = axios.create({ const instance = axios.create({
baseURL: process.env.VUE_APP_OPENSHOT_API_URL, baseURL: getCloudApiUrl(),
headers: {'X-Requested-With': 'XMLHttpRequest'} headers: {'X-Requested-With': 'XMLHttpRequest'}
}); });
......
...@@ -5,6 +5,10 @@ import { instance, blob_instance, fixImageDuration, reorderArray } from "./axios ...@@ -5,6 +5,10 @@ import { instance, blob_instance, fixImageDuration, reorderArray } from "./axios
export default createStore({ export default createStore({
state: { state: {
apiStatus: {
version: null,
demo_mode: false
},
projects: [], projects: [],
files: [], files: [],
clips: [], clips: [],
...@@ -29,6 +33,12 @@ export default createStore({ ...@@ -29,6 +33,12 @@ export default createStore({
}, },
mutations: { mutations: {
setApiStatus(state, status) {
state.apiStatus = {
version: status?.version || null,
demo_mode: status?.demo_mode === true
}
},
addError(state, message) { addError(state, message) {
if (typeof(message) == "object") { if (typeof(message) == "object") {
// Loop through object keys (potentially multiple errors) // Loop through object keys (potentially multiple errors)
...@@ -230,6 +240,14 @@ export default createStore({ ...@@ -230,6 +240,14 @@ export default createStore({
} }
}, },
actions: { actions: {
async loadApiStatus({commit}) {
try {
const response = await instance.get('/info/status/')
commit('setApiStatus', response.data)
} catch (_error) {
commit('setApiStatus', {version: null, demo_mode: false})
}
},
async login({commit}, auth) { async login({commit}, auth) {
try { try {
const response = await instance.get('/users/') const response = await instance.get('/users/')
......
...@@ -7,15 +7,6 @@ const CONVERSIONS = { ...@@ -7,15 +7,6 @@ const CONVERSIONS = {
google: 'AW-994591350/W6AWCOyvgaAYEPaEodoD' google: 'AW-994591350/W6AWCOyvgaAYEPaEodoD'
} }
export function isDemoEnvironment() {
const apiUrl = (process.env.VUE_APP_OPENSHOT_API_URL || '').trim()
if (!apiUrl) {
return false
}
const normalized = apiUrl.replace(/\/+$/, '').toLowerCase()
return normalized === 'https://cloud.openshot.org'
}
function hasGtag() { function hasGtag() {
return typeof window !== 'undefined' && typeof window.gtag === 'function' return typeof window !== 'undefined' && typeof window.gtag === 'function'
} }
......
...@@ -41,9 +41,8 @@ ...@@ -41,9 +41,8 @@
</template> </template>
<script> <script>
import { mapActions, mapGetters, mapMutations } from 'vuex' import { mapActions, mapGetters, mapMutations, mapState } from 'vuex'
import DemoAccessModal from '../components/DemoAccessModal.vue' import DemoAccessModal from '../components/DemoAccessModal.vue'
import { instance } from '../store/axios'
export default { export default {
name: "Login.vue", name: "Login.vue",
...@@ -52,8 +51,7 @@ export default { ...@@ -52,8 +51,7 @@ export default {
return { return {
username: null, username: null,
password: null, password: null,
showDemoAccess: false, showDemoAccess: false
demoAccessEnabled: false
} }
}, },
methods: { methods: {
...@@ -82,17 +80,10 @@ export default { ...@@ -82,17 +80,10 @@ export default {
}, },
computed: { computed: {
isDemoEnvironment() { isDemoEnvironment() {
return this.demoAccessEnabled return this.apiStatus.demo_mode
}, },
...mapGetters(['isAuthenticated']) ...mapGetters(['isAuthenticated']),
}, ...mapState(['apiStatus'])
async created() {
try {
const response = await instance.get('/demo-access/status/')
this.demoAccessEnabled = response.data.demo_access_enabled === true
} catch (error) {
this.demoAccessEnabled = false
}
} }
} }
</script> </script>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment