aboutsummaryrefslogtreecommitdiff
path: root/front-end/src/views
diff options
context:
space:
mode:
authorLibravatar vnugent <public@vaughnnugent.com>2023-09-30 21:43:19 -0400
committerLibravatar vnugent <public@vaughnnugent.com>2023-09-30 21:43:19 -0400
commit95d60952b3ea470495003b0d0e51840cd8e68605 (patch)
tree79f5179c4dd9349c7b88b7b1d2ed13b53152d166 /front-end/src/views
parent62da31eb31baf7e27bf4c6d3d15e2c69617e2f74 (diff)
configure html podcast description support and minor ui tweaks
Diffstat (limited to 'front-end/src/views')
-rw-r--r--front-end/src/views/Blog/ckeditor/Editor.vue32
-rw-r--r--front-end/src/views/Blog/components/ContentSearch.vue8
-rw-r--r--front-end/src/views/Blog/components/Posts/PostEdit.vue26
-rw-r--r--front-end/src/views/Blog/components/podcast-helpers/EpisodeAdder.vue36
-rw-r--r--front-end/src/views/Blog/components/podcast-helpers/podcast-form.ts12
5 files changed, 87 insertions, 27 deletions
diff --git a/front-end/src/views/Blog/ckeditor/Editor.vue b/front-end/src/views/Blog/ckeditor/Editor.vue
index 3cd9a8c..4fc534b 100644
--- a/front-end/src/views/Blog/ckeditor/Editor.vue
+++ b/front-end/src/views/Blog/ckeditor/Editor.vue
@@ -1,7 +1,21 @@
<template>
<div class="pt-6">
<div class="flex justify-end w-full gap-2 my-2">
- <div class="w-fit">
+ <div class="w-fit">
+ <div class="flex flex-row py-2 mr-auto">
+ <Switch v-model="podcastMode"
+ :class="$props.podcastMode ? 'bg-primary-500' : 'bg-gray-300 dark:bg-dark-500'"
+ class="relative inline-flex items-center w-10 h-5 my-auto duration-75 rounded-full">
+ <span class="sr-only">Podcast Mode</span>
+ <span :class="$props.podcastMode ? 'translate-x-6' : 'translate-x-1'"
+ class="inline-block w-3 h-3 transition transform bg-white rounded-full" />
+ </Switch>
+ <div class="my-auto ml-3">
+ Podcast Mode
+ </div>
+ </div>
+ </div>
+ <div class="w-fit">
<Popover class="relative">
<PopoverButton class="btn">
Add
@@ -56,11 +70,11 @@
<script setup lang="ts">
import { debounce, defer } from 'lodash-es';
-import { ref } from 'vue';
+import { computed, ref, toRefs } from 'vue';
import { useSessionStorage } from '@vueuse/core';
import { tryOnMounted } from '@vueuse/shared';
import { apiCall } from '@vnuge/vnlib.browser';
-import { Popover, PopoverButton, PopoverPanel } from '@headlessui/vue'
+import { Popover, PopoverButton, PopoverPanel, Switch } from '@headlessui/vue'
import { BlogState } from '../blog-api'
import { Converter } from 'showdown'
@@ -68,18 +82,24 @@ import { Converter } from 'showdown'
import { config } from './build.ts'
import ContentSearch from '../components/ContentSearch.vue';
-const emit = defineEmits(['change', 'load'])
+const emit = defineEmits(['change', 'load', 'mode-change'])
-defineProps<{
- blog: BlogState
+const props = defineProps<{
+ blog: BlogState,
+ podcastMode: boolean
}>()
let editor = {}
+const propRefs = toRefs(props)
//Init new shodown converter
const showdownConverter = new Converter()
const mdBuffer = ref('')
const editorFrame = ref(null)
const crashBuffer = useSessionStorage('post-crash', '')
+const podcastMode = computed({
+ get: () => propRefs.podcastMode.value,
+ set: (v) => emit('mode-change', v)
+})
const recoverFromCrash = () => {
//Set editor content from crash buffer
diff --git a/front-end/src/views/Blog/components/ContentSearch.vue b/front-end/src/views/Blog/components/ContentSearch.vue
index 03cb432..78cfa1a 100644
--- a/front-end/src/views/Blog/components/ContentSearch.vue
+++ b/front-end/src/views/Blog/components/ContentSearch.vue
@@ -79,8 +79,8 @@ const searchResults = computed<ContentResult[]>(() => {
return {
...content,
//truncate the id and name for display
- shortId: truncate(content.id, { length: 15 }),
- shortName: truncate(content.name, { length: 24 }),
+ shortId: truncate(content.id, { length: 18 }),
+ shortName: truncate(content.name, { length: 36 }),
copyLink: () => copyLink(content, copy),
copied
}
@@ -110,6 +110,10 @@ const onSelected = (result: ContentResult) => {
.controls{
@apply min-w-[4rem] text-center;
}
+
+ &.name{
+ @apply text-sm;
+ }
}
</style> \ No newline at end of file
diff --git a/front-end/src/views/Blog/components/Posts/PostEdit.vue b/front-end/src/views/Blog/components/Posts/PostEdit.vue
index e55deee..6ea0bac 100644
--- a/front-end/src/views/Blog/components/Posts/PostEdit.vue
+++ b/front-end/src/views/Blog/components/Posts/PostEdit.vue
@@ -9,9 +9,6 @@
</div>
<div class="mx-auto">
<h4 class="text-center">Edit Post</h4>
- <p>
- Add or edit a post to publish to your blog.
- </p>
</div>
<div class="relative">
<div class="absolute top-2 right-10">
@@ -28,7 +25,7 @@
/>
<div id="post-content-editor" class="px-6" :class="{'invalid':v$.content.$invalid}">
- <Editor @change="onContentChanged" :blog="$props.blog" @load="onEditorLoad" />
+ <Editor :podcast-mode="podcastMode" :blog="$props.blog" @change="onContentChanged" @mode-change="onModeChange" @load="onEditorLoad" />
</div>
<FeedFields :properties="postProperties" :blog="$props.blog" />
@@ -44,7 +41,7 @@
</div>
</template>
<script setup lang="ts">
-import { computed } from 'vue';
+import { computed, ref } from 'vue';
import { BlogState } from '../../blog-api';
import { reactiveComputed } from '@vueuse/core';
import { isNil, isString, split } from 'lodash-es';
@@ -64,6 +61,7 @@ const { getProfile } = useUser();
const { schema, getValidator } = getPostForm();
const { posts, content } = props.blog;
+const podcastMode = ref(false)
const isNew = computed(() => isNil(posts.selectedItem.value));
@@ -98,6 +96,14 @@ const onSubmit = async () =>{
//Remove the content from the post object
delete post.content;
+ //Store the post content on the html descrption if in podcast mode
+ if(podcastMode.value){
+ post.html_description = v$.value.content.$model;
+ }
+ else{
+ delete post.html_description;
+ }
+
//Convert the tags string to an array of strings
post.tags = isString(post.tags) ? split(post.tags, ',') : post.tags;
@@ -136,6 +142,10 @@ const setMeAsAuthor = () => {
})
}
+const onModeChange = (e: boolean) => {
+ podcastMode.value = e;
+}
+
const onEditorLoad = async (editor : any) =>{
//Get the initial content
@@ -146,6 +156,12 @@ const onEditorLoad = async (editor : any) =>{
onContentChanged(postContent);
editor.setData(postContent);
}
+
+ //If the post has an html description, set podcast mode
+ if(postBuffer.html_description){
+ //Set podcast mode to true
+ podcastMode.value = true;
+ }
}
</script>
diff --git a/front-end/src/views/Blog/components/podcast-helpers/EpisodeAdder.vue b/front-end/src/views/Blog/components/podcast-helpers/EpisodeAdder.vue
index d4adb6f..6d1e473 100644
--- a/front-end/src/views/Blog/components/podcast-helpers/EpisodeAdder.vue
+++ b/front-end/src/views/Blog/components/podcast-helpers/EpisodeAdder.vue
@@ -13,12 +13,26 @@
<div class="fixed inset-0 flex justify-center pt-[8rem]">
<DialogPanel class="dialog">
<div class="">
- <DialogTitle>Set feed enclosure</DialogTitle>
- <DialogDescription>
+ <DialogTitle class="text-2xl font-bold">Add Media Enclosure</DialogTitle>
+ <DialogDescription class="text-xs">
You may set a podcast episode or other rss enclosure from
content stored in the cms.
</DialogDescription>
- <div class="my-3 ml-auto w-fit">
+ <div class="flex flex-row gap-3 my-3 ml-auto w-fit">
+ <div class="flex flex-row gap-2 my-auto">
+ <div class="text-sm">
+ Explicit
+ </div>
+ <div class="">
+ <Switch v-model="isExplicit"
+ :class="isExplicit ? 'bg-red-500' : 'bg-gray-300 dark:bg-dark-500'"
+ class="relative inline-flex items-center w-10 h-5 my-auto duration-75 rounded-full">
+ <span class="sr-only">Podcast Mode</span>
+ <span :class="isExplicit ? 'translate-x-6' : 'translate-x-1'"
+ class="inline-block w-3 h-3 transition transform bg-white rounded-full" />
+ </Switch>
+ </div>
+ </div>
<Popover class="relative">
<PopoverButton class="btn">
Add media
@@ -57,7 +71,7 @@
</template>
<script setup lang="ts">
-import { ref, reactive } from 'vue';
+import { ref, reactive, computed } from 'vue';
import { BlogState } from '../../blog-api';
import { PodcastEntity, getPodcastForm } from './podcast-form'
import {
@@ -68,6 +82,7 @@ import {
PopoverButton,
PopoverPanel,
Popover,
+ Switch
} from '@headlessui/vue'
import ContentSearch from '../ContentSearch.vue'
import { apiCall, debugLog } from '@vnuge/vnlib.browser';
@@ -87,6 +102,11 @@ const buffer = reactive<PodcastEntity>({} as PodcastEntity)
const { v$, validate } = getValidator(buffer)
+const isExplicit = computed({
+ get : () => buffer.explicit,
+ set : (v: boolean) => buffer.explicit = v
+});
+
const setIsOpen = (value: boolean) => isOpen.value = value
const onFormSubmit = async () =>{
@@ -102,15 +122,13 @@ const onFormSubmit = async () =>{
setIsOpen(false)
}
-const onCancel = () =>{
- setIsOpen(false)
-}
+const onCancel = () => setIsOpen(false)
const onContentSelected = (content: ContentMeta) =>{
apiCall(async () =>{
//Get the content link from the server
const url = await getPublicUrl(content)
-
+
//set the form content
setEnclosureContent(buffer, content, `/${url}`)
})
@@ -147,7 +165,7 @@ const onContentSelected = (content: ContentMeta) =>{
@apply py-1.5 bg-transparent;
&:disabled{
- @apply bg-gray-100 dark:bg-transparent dark:border-transparent;
+ @apply bg-gray-100 py-0.5 bg-transparent disabled:text-sm disabled:border-0 dark:text-gray-400 text-black;
}
&:focus{
diff --git a/front-end/src/views/Blog/components/podcast-helpers/podcast-form.ts b/front-end/src/views/Blog/components/podcast-helpers/podcast-form.ts
index ab8ad8a..56b898c 100644
--- a/front-end/src/views/Blog/components/podcast-helpers/podcast-form.ts
+++ b/front-end/src/views/Blog/components/podcast-helpers/podcast-form.ts
@@ -25,6 +25,7 @@ export interface EnclosureEntity{
contentUrl: string;
contentLength: number;
contentType: string;
+ explicit: boolean;
}
export interface PodcastEntity extends EnclosureEntity{
@@ -58,7 +59,6 @@ export const getPodcastForm = (editMode?: Ref<boolean>) => {
label: 'File Id',
name: 'fileId',
placeholder: '',
- description: 'The file id of the episode already in the channel',
disabled: true,
},
{
@@ -67,7 +67,6 @@ export const getPodcastForm = (editMode?: Ref<boolean>) => {
label: 'Content url',
name: 'contentUrl',
placeholder: '',
- description: 'This the relative url to the episode content file',
disabled: true,
},
{
@@ -76,16 +75,14 @@ export const getPodcastForm = (editMode?: Ref<boolean>) => {
label: 'Content length',
name: 'contentLength',
placeholder: '',
- description: 'This the length in bytes of the episode content file',
disabled: true,
},
{
id: 'content-type',
type: 'text',
- label: 'The MIME content type',
+ label: 'MIME content type',
name: 'contentType',
placeholder: '',
- description: 'The MIME content type for the episode content file',
disabled: true,
}
]
@@ -159,6 +156,11 @@ export const getPodcastForm = (editMode?: Ref<boolean>) => {
length: podcast.contentLength?.toString(),
type: podcast.contentType
},
+ },
+ {
+ name: 'explicit',
+ namespace: 'itunes',
+ value: podcast.explicit ? 'true' : 'false'
}
]
}