diff --git a/src/common/playlists/PlayList.jsx b/src/common/playlists/PlayList.jsx
index 22e4d63c3..751c47293 100644
--- a/src/common/playlists/PlayList.jsx
+++ b/src/common/playlists/PlayList.jsx
@@ -8,6 +8,7 @@ import { useParams } from "react-router-dom";
import useGetPlays from 'common/hooks/useGetPlays'
import "./playlist.css";
+import { toSanitized } from "common/services/string";
const PlayList = () => {
const [loading, error, plays] = useGetPlays();
@@ -37,7 +38,7 @@ const PlayList = () => {
{
- all_plays[play.component ? play.component : play.title_name] &&
+ all_plays[play.component ? play.component : toSanitized(play.title_name)] &&
}
diff --git a/src/common/playlists/PlayMeta.jsx b/src/common/playlists/PlayMeta.jsx
index eca01ddf0..1fc84f0df 100644
--- a/src/common/playlists/PlayMeta.jsx
+++ b/src/common/playlists/PlayMeta.jsx
@@ -4,8 +4,8 @@ import * as plays from "plays";
import { useParams } from "react-router-dom";
import { submit } from "common/services/request";
import Loader from "common/spinner/spinner";
-import { toTitleCase } from "common/services/string";
-import { FetchPlaysByNameAndUser } from "common/services/request/query/fetch-plays";
+import { toSanitized, toTitleCase, toTitleCaseTrimmed } from "common/services/string";
+import { FetchPlaysBySlugAndUser } from "common/services/request/query/fetch-plays";
import { PageNotFound } from "common";
function PlayMeta() {
@@ -16,9 +16,10 @@ function PlayMeta() {
const [metaImage, setMetaImage] = useState();
useEffect(() => {
- submit(FetchPlaysByNameAndUser(decodeURI(playname), decodeURI(username)))
+ submit(FetchPlaysBySlugAndUser(decodeURI(playname), decodeURI(username)))
.then((res) => {
const play_obj = res[0];
+ play_obj.title_name = toTitleCaseTrimmed(play_obj.name);
setPlay(play_obj);
setMetaImage(play_obj.cover);
setLoading(false);
@@ -38,7 +39,7 @@ function PlayMeta() {
const renderPlayComponent = () => {
const Comp =
- plays[play.component || toTitleCase(play.name).replace(/ /g, "")];
+ plays[play.component || toSanitized(play.title_name)] ;
return ;
};
diff --git a/src/common/playlists/PlayThumbnail.jsx b/src/common/playlists/PlayThumbnail.jsx
index 18d95621a..6b8d60ec2 100644
--- a/src/common/playlists/PlayThumbnail.jsx
+++ b/src/common/playlists/PlayThumbnail.jsx
@@ -53,8 +53,7 @@ const PlayThumbnail = ({ play }) => {
// if it is not passed as a meta data
// check in the play folder for a cover image
// with the name cover.png
- const playFolder = play.path.split("/")[2];
- import(`plays/${playFolder}/cover.png`)
+ import(`plays/${play.slug}/cover.png`)
.then((Cover) => {
setCover(Cover.default);
})
@@ -72,7 +71,7 @@ const PlayThumbnail = ({ play }) => {
return (
diff --git a/src/common/services/plays.js b/src/common/services/plays.js
index 357ac8036..f38950f2f 100644
--- a/src/common/services/plays.js
+++ b/src/common/services/plays.js
@@ -4,7 +4,7 @@ import {
associatePlayWithTagQuery,
createPlayQuery,
} from "./request/query/play";
-import { toKebabCase } from "./string";
+import { toKebabCase, toSlug } from "./string";
import { Tags } from "./tags";
// Create a play
@@ -25,6 +25,9 @@ const createPlay = (playObject) => {
? objectToSubmit.style.value
: "css";
+ // Prepare slug
+ objectToSubmit.slug = toSlug(objectToSubmit.name);
+
// Prepare level
objectToSubmit.level_id = objectToSubmit.level.value;
delete objectToSubmit.level;
diff --git a/src/common/services/request/query/fetch-plays.js b/src/common/services/request/query/fetch-plays.js
index 006b5aba2..dbd6eb69f 100644
--- a/src/common/services/request/query/fetch-plays.js
+++ b/src/common/services/request/query/fetch-plays.js
@@ -1,9 +1,9 @@
export function FetchPlaysSimple() {
- return {...BasiFetchParam}
+ return { ...BasiFetchParam };
}
export function FetchPlaysByID(id) {
- const payload = { ...BasiFetchParam };
+ const payload = { ...DetailedFetchParam };
payload.where = {
clause: {
@@ -19,17 +19,17 @@ export function FetchPlaysByID(id) {
return payload;
}
-export function FetchPlaysByNameAndUser(playname, username) {
- const payload = { ...BasiFetchParam };
+export function FetchPlaysBySlugAndUser(playslug, username) {
+ const payload = { ...DetailedFetchParam };
payload.where = {
clause: {
operator: "and",
conditions: [
{
- field: "name",
+ field: "slug",
operator: "ilike",
- value: playname,
+ value: playslug,
type: "string",
},
{
@@ -50,23 +50,30 @@ const BasiFetchParam = {
function: "plays",
write: false,
return: [
- "blog",
"component",
"cover",
- "created_at",
"description",
"featured",
"dev_mode",
"github",
- "id",
"language",
{ play_like: ["liked", "play_id", "user_id"] },
- { level: ["name"] },
"name",
- "path",
- { play_tags: { tag: ["name"] } },
- "updated_at",
+ "slug",
{ user: ["id", "displayName", "avatarUrl"] },
- "video",
],
};
+
+const DetailedFetchParam = {
+ ...BasiFetchParam,
+ ...{
+ return: [
+ ...BasiFetchParam.return,
+ "blog",
+ "id",
+ { level: ["name"] },
+ "video",
+ { play_tags: { tag: ["name"] } },
+ ],
+ },
+};
diff --git a/src/common/services/string.js b/src/common/services/string.js
index 52339f9b2..abcab5313 100644
--- a/src/common/services/string.js
+++ b/src/common/services/string.js
@@ -35,3 +35,17 @@ export const toTitleCaseTrimmed = (str) => {
const titleCse = toTitleCase(str);
return titleCse.replace(/\s/g, "");
};
+
+export const toSlug = (str) => {
+ return toSanitized(str).toLowerCase();
+};
+
+export const toSanitized = (str) => {
+ //replace all special characters | symbols with a space
+ str = str.replace(/[`~!@#$%^&*()_\-+=\[\]{};:'"\\|\/,.<>?\s]/g, " ");
+ // trim spaces at start and end of string
+ str = str.replace(/^\s+|\s+$/gm, "");
+ // replace space with dash/hyphen
+ str = str.replace(/\s+/g, "-");
+ return str;
+};