Commit
•
c8c2f6c
1
Parent(s):
831b708
add button for more randomness
Browse files- package-lock.json +6 -0
- package.json +1 -0
- src/app/main.tsx +55 -5
- src/app/store.ts +5 -2
- src/lib/fun-words/declaration.d.ts +22 -0
- src/lib/fun-words/filterSensitiveContent.ts +82 -0
- src/lib/fun-words/index.ts +35 -0
- src/lib/utils/generateRandomStory.ts +102 -0
- src/lib/utils/pick.ts +21 -1
- src/lib/utils/{putTextInInput.ts → putTextInTextAreaElement.ts} +2 -2
- tailwind.config.js +8 -2
package-lock.json
CHANGED
@@ -38,6 +38,7 @@
|
|
38 |
"cmdk": "^0.2.1",
|
39 |
"eslint": "8.56.0",
|
40 |
"eslint-config-next": "14.1.0",
|
|
|
41 |
"jimp": "^0.22.12",
|
42 |
"jose": "^5.2.4",
|
43 |
"lucide-react": "^0.334.0",
|
@@ -4526,6 +4527,11 @@
|
|
4526 |
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
4527 |
}
|
4528 |
},
|
|
|
|
|
|
|
|
|
|
|
4529 |
"node_modules/function-bind": {
|
4530 |
"version": "1.1.2",
|
4531 |
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
|
|
38 |
"cmdk": "^0.2.1",
|
39 |
"eslint": "8.56.0",
|
40 |
"eslint-config-next": "14.1.0",
|
41 |
+
"fun-word-list": "^1.0.1",
|
42 |
"jimp": "^0.22.12",
|
43 |
"jose": "^5.2.4",
|
44 |
"lucide-react": "^0.334.0",
|
|
|
4527 |
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
4528 |
}
|
4529 |
},
|
4530 |
+
"node_modules/fun-word-list": {
|
4531 |
+
"version": "1.0.1",
|
4532 |
+
"resolved": "https://registry.npmjs.org/fun-word-list/-/fun-word-list-1.0.1.tgz",
|
4533 |
+
"integrity": "sha512-WoUxTcjSPLSWhyMQaDiYgIWGOPHS7SnsZL8TVQrX8qdMyHXz8uPWnfMHq/Kx+kxQpQJ0GZkMjKgynv+INhbzBg=="
|
4534 |
+
},
|
4535 |
"node_modules/function-bind": {
|
4536 |
"version": "1.1.2",
|
4537 |
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
package.json
CHANGED
@@ -39,6 +39,7 @@
|
|
39 |
"cmdk": "^0.2.1",
|
40 |
"eslint": "8.56.0",
|
41 |
"eslint-config-next": "14.1.0",
|
|
|
42 |
"jimp": "^0.22.12",
|
43 |
"jose": "^5.2.4",
|
44 |
"lucide-react": "^0.334.0",
|
|
|
39 |
"cmdk": "^0.2.1",
|
40 |
"eslint": "8.56.0",
|
41 |
"eslint-config-next": "14.1.0",
|
42 |
+
"fun-word-list": "^1.0.1",
|
43 |
"jimp": "^0.22.12",
|
44 |
"jose": "^5.2.4",
|
45 |
"lucide-react": "^0.334.0",
|
src/app/main.tsx
CHANGED
@@ -2,6 +2,7 @@
|
|
2 |
|
3 |
import React, { useEffect, useRef, useTransition } from 'react'
|
4 |
import { IoMdPhonePortrait } from 'react-icons/io'
|
|
|
5 |
import { useLocalStorage } from "usehooks-ts"
|
6 |
import { ClapProject, ClapMediaOrientation, ClapSegmentCategory, updateClap } from '@aitube/clap'
|
7 |
import Image from 'next/image'
|
@@ -31,6 +32,7 @@ import { Label } from '@/components/form/label'
|
|
31 |
import { getParam } from '@/lib/utils/getParam'
|
32 |
import { GenerationStage } from '@/types'
|
33 |
import { FileContent } from 'use-file-picker/dist/interfaces'
|
|
|
34 |
|
35 |
export function Main() {
|
36 |
const [storyPromptDraft, setStoryPromptDraft] = useLocalStorage<string>(
|
@@ -641,10 +643,12 @@ export function Main() {
|
|
641 |
inputClassName="
|
642 |
transition-all duration-200 ease-in-out
|
643 |
h-32 md:h-56 lg:h-64
|
|
|
644 |
"
|
645 |
disabled={isBusy}
|
646 |
value={storyPromptDraft}
|
647 |
/>
|
|
|
648 |
|
649 |
{/* END OF MAIN PROMPT INPUT */}
|
650 |
</div>
|
@@ -682,7 +686,8 @@ export function Main() {
|
|
682 |
flex flex-row
|
683 |
justify-between items-center
|
684 |
space-x-3">
|
685 |
-
|
|
|
686 |
<Button
|
687 |
onClick={openFilePicker}
|
688 |
disabled={isBusy}
|
@@ -697,8 +702,9 @@ export function Main() {
|
|
697 |
>
|
698 |
<span className="hidden xl:inline mr-1">Load</span>
|
699 |
<span className="inline xl:hidden mr-1">Load</span>
|
700 |
-
</Button>
|
701 |
-
}
|
|
|
702 |
|
703 |
{canSeeBetaFeatures ?
|
704 |
<Button
|
@@ -725,20 +731,60 @@ export function Main() {
|
|
725 |
space-x-3
|
726 |
select-none
|
727 |
">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
728 |
{/* ORIENTATION SWITCH */}
|
729 |
<div className="
|
730 |
flex flex-row
|
731 |
justify-between items-center
|
732 |
cursor-pointer
|
|
|
|
|
|
|
|
|
|
|
|
|
733 |
"
|
734 |
onClick={() => toggleOrientation()}>
|
735 |
<div>
|
736 |
-
<span className="hidden xl:inline mr-1">Orientation:</span>
|
737 |
-
<span className="inline xl:hidden mr-1"></span>
|
738 |
</div>
|
739 |
<div className="
|
740 |
w-8 h-8
|
741 |
flex flex-row items-center justify-center
|
|
|
|
|
742 |
"
|
743 |
>
|
744 |
<div className={cn(
|
@@ -870,6 +916,10 @@ export function Main() {
|
|
870 |
|
871 |
</div>
|
872 |
</DeviceFrameset>
|
|
|
|
|
|
|
|
|
873 |
</div>
|
874 |
</div>
|
875 |
</div>
|
|
|
2 |
|
3 |
import React, { useEffect, useRef, useTransition } from 'react'
|
4 |
import { IoMdPhonePortrait } from 'react-icons/io'
|
5 |
+
import { GiRollingDices } from 'react-icons/gi'
|
6 |
import { useLocalStorage } from "usehooks-ts"
|
7 |
import { ClapProject, ClapMediaOrientation, ClapSegmentCategory, updateClap } from '@aitube/clap'
|
8 |
import Image from 'next/image'
|
|
|
32 |
import { getParam } from '@/lib/utils/getParam'
|
33 |
import { GenerationStage } from '@/types'
|
34 |
import { FileContent } from 'use-file-picker/dist/interfaces'
|
35 |
+
import { generateRandomStory } from '@/lib/utils/generateRandomStory'
|
36 |
|
37 |
export function Main() {
|
38 |
const [storyPromptDraft, setStoryPromptDraft] = useLocalStorage<string>(
|
|
|
643 |
inputClassName="
|
644 |
transition-all duration-200 ease-in-out
|
645 |
h-32 md:h-56 lg:h-64
|
646 |
+
|
647 |
"
|
648 |
disabled={isBusy}
|
649 |
value={storyPromptDraft}
|
650 |
/>
|
651 |
+
|
652 |
|
653 |
{/* END OF MAIN PROMPT INPUT */}
|
654 |
</div>
|
|
|
686 |
flex flex-row
|
687 |
justify-between items-center
|
688 |
space-x-3">
|
689 |
+
|
690 |
+
{/*
|
691 |
<Button
|
692 |
onClick={openFilePicker}
|
693 |
disabled={isBusy}
|
|
|
702 |
>
|
703 |
<span className="hidden xl:inline mr-1">Load</span>
|
704 |
<span className="inline xl:hidden mr-1">Load</span>
|
705 |
+
</Button>
|
706 |
+
*/}
|
707 |
+
|
708 |
|
709 |
{canSeeBetaFeatures ?
|
710 |
<Button
|
|
|
731 |
space-x-3
|
732 |
select-none
|
733 |
">
|
734 |
+
|
735 |
+
|
736 |
+
{/* RANDOMNESS SWITCH */}
|
737 |
+
<div className="
|
738 |
+
flex flex-row
|
739 |
+
justify-between items-center
|
740 |
+
cursor-pointer
|
741 |
+
transition-all duration-150 ease-in-out
|
742 |
+
hover:scale-110 active:scale-150
|
743 |
+
text-stone-800
|
744 |
+
hover:text-stone-950
|
745 |
+
active:text-black
|
746 |
+
group
|
747 |
+
"
|
748 |
+
onClick={() => {
|
749 |
+
const randomStory = generateRandomStory()
|
750 |
+
setStoryPromptDraft(randomStory)
|
751 |
+
promptDraftRef.current = randomStory
|
752 |
+
}}>
|
753 |
+
<div>
|
754 |
+
</div>
|
755 |
+
<div className="
|
756 |
+
w-6 h-8
|
757 |
+
flex flex-row items-center justify-center
|
758 |
+
transition-all duration-150 ease-out
|
759 |
+
group-hover:animate-swing
|
760 |
+
"
|
761 |
+
>
|
762 |
+
<GiRollingDices size={24} />
|
763 |
+
</div>
|
764 |
+
</div>
|
765 |
+
{/* END OF RANDOMNESS SWITCH */}
|
766 |
+
|
767 |
+
|
768 |
{/* ORIENTATION SWITCH */}
|
769 |
<div className="
|
770 |
flex flex-row
|
771 |
justify-between items-center
|
772 |
cursor-pointer
|
773 |
+
transition-all duration-150 ease-out
|
774 |
+
hover:scale-110 active:scale-150
|
775 |
+
text-stone-800
|
776 |
+
hover:text-stone-950
|
777 |
+
active:text-black
|
778 |
+
group
|
779 |
"
|
780 |
onClick={() => toggleOrientation()}>
|
781 |
<div>
|
|
|
|
|
782 |
</div>
|
783 |
<div className="
|
784 |
w-8 h-8
|
785 |
flex flex-row items-center justify-center
|
786 |
+
transition-all duration-150 ease-in-out
|
787 |
+
group-hover:animate-swing
|
788 |
"
|
789 |
>
|
790 |
<div className={cn(
|
|
|
916 |
|
917 |
</div>
|
918 |
</DeviceFrameset>
|
919 |
+
|
920 |
+
{/*
|
921 |
+
<div className={handleDownload}>Download</div>
|
922 |
+
*/}
|
923 |
</div>
|
924 |
</div>
|
925 |
</div>
|
src/app/store.ts
CHANGED
@@ -7,7 +7,7 @@ import { GenerationStage, GlobalStatus, TaskStatus } from "@/types"
|
|
7 |
import { getVideoOrientation } from "@/lib/utils/getVideoOrientation"
|
8 |
|
9 |
import { RESOLUTION_LONG, RESOLUTION_SHORT } from "./server/aitube/config"
|
10 |
-
import {
|
11 |
|
12 |
export const useStore = create<{
|
13 |
mainCharacterImage: string
|
@@ -230,7 +230,10 @@ export const useStore = create<{
|
|
230 |
|
231 |
const storyPrompt = currentClap.meta.description.split("||").pop() || ""
|
232 |
|
233 |
-
|
|
|
|
|
|
|
234 |
|
235 |
// TODO: parseVideoOrientation should be put inside @aitube/clap (in the utils)
|
236 |
// const orientation = parseVideoOrientation(currentClap.meta.orientation)
|
|
|
7 |
import { getVideoOrientation } from "@/lib/utils/getVideoOrientation"
|
8 |
|
9 |
import { RESOLUTION_LONG, RESOLUTION_SHORT } from "./server/aitube/config"
|
10 |
+
import { putTextInTextAreaElement } from "@/lib/utils/putTextInTextAreaElement"
|
11 |
|
12 |
export const useStore = create<{
|
13 |
mainCharacterImage: string
|
|
|
230 |
|
231 |
const storyPrompt = currentClap.meta.description.split("||").pop() || ""
|
232 |
|
233 |
+
putTextInTextAreaElement(
|
234 |
+
document.getElementById("story-prompt-draft") as HTMLTextAreaElement,
|
235 |
+
storyPrompt
|
236 |
+
)
|
237 |
|
238 |
// TODO: parseVideoOrientation should be put inside @aitube/clap (in the utils)
|
239 |
// const orientation = parseVideoOrientation(currentClap.meta.orientation)
|
src/lib/fun-words/declaration.d.ts
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
declare module 'fun-word-list' {
|
2 |
+
import * as funWordList from 'fun-word-list';
|
3 |
+
|
4 |
+
type FunWordList = {
|
5 |
+
addons: string[] // Fragments to add to the end of sentences for different moods. Many include preceding commas or periods.
|
6 |
+
adjectives: string[] // For use with `nouns` or `concepts`
|
7 |
+
concepts: string[] // Complex nouns
|
8 |
+
descriptions: string[] // For use with `locations`
|
9 |
+
gametypes: string[] // Video game genres/playstyles/feels
|
10 |
+
locations: string[] // Nouns that represent places
|
11 |
+
nouns: string[][] // Simple things that can act or be acted upon
|
12 |
+
|
13 |
+
superlatives: string[] // Adjectives that express the extremes of something. For use with `nouns`, `concepts`, or `locations`
|
14 |
+
verbs: { // All verbs in this list are used for acting in relation to another thing.
|
15 |
+
secondPerson: string[] // Verbs for use with "you" or "they" as in "you help the aardvark" or "they fight a bird"
|
16 |
+
secondConcepts: string[] // Verbs for use with "you" or "they" in combination with `concepts` as in "you are helped by the King" or "they fight against traditions"
|
17 |
+
thirdPerson: string[] // Verbs for use with `nouns` as in "The aardvark anticipates rain"
|
18 |
+
}
|
19 |
+
}
|
20 |
+
|
21 |
+
export default funWordList as FunWordList
|
22 |
+
}
|
src/lib/fun-words/filterSensitiveContent.ts
ADDED
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
// unfortunately the lib comes with some words
|
3 |
+
// that, when combined, could create some bad buzz
|
4 |
+
export const sensitiveTopics = [
|
5 |
+
"The Pope",
|
6 |
+
"gag",
|
7 |
+
"sadist",
|
8 |
+
"actress",
|
9 |
+
"razor",
|
10 |
+
"female",
|
11 |
+
"destroyer",
|
12 |
+
"prisonner",
|
13 |
+
"rib",
|
14 |
+
"cultist",
|
15 |
+
"candy",
|
16 |
+
"candies",
|
17 |
+
"skull",
|
18 |
+
"injury",
|
19 |
+
"lungs",
|
20 |
+
"field",
|
21 |
+
"child",
|
22 |
+
"kid",
|
23 |
+
"walk",
|
24 |
+
"stranger",
|
25 |
+
"children",
|
26 |
+
"faker",
|
27 |
+
"fake",
|
28 |
+
"curse",
|
29 |
+
"scissor",
|
30 |
+
"hobo",
|
31 |
+
"maniac",
|
32 |
+
"drug",
|
33 |
+
"gang",
|
34 |
+
"predator",
|
35 |
+
"hostage",
|
36 |
+
"cutthroat",
|
37 |
+
"swallow",
|
38 |
+
"shotgun",
|
39 |
+
"gun",
|
40 |
+
"pickaxe",
|
41 |
+
"clergymen",
|
42 |
+
"clergyman",
|
43 |
+
"clergy",
|
44 |
+
"dictator",
|
45 |
+
"microbe",
|
46 |
+
"convict",
|
47 |
+
"sniper",
|
48 |
+
"skeleton",
|
49 |
+
"aborigine",
|
50 |
+
"skirt",
|
51 |
+
"thug",
|
52 |
+
"thief",
|
53 |
+
"handgun",
|
54 |
+
"executioner",
|
55 |
+
"beast",
|
56 |
+
"nymph",
|
57 |
+
"rabbis",
|
58 |
+
"rabbies",
|
59 |
+
"rabbi",
|
60 |
+
"giblet",
|
61 |
+
"prisoner",
|
62 |
+
"machine gun",
|
63 |
+
"infant",
|
64 |
+
"crucifix",
|
65 |
+
"hatchet",
|
66 |
+
"beggar",
|
67 |
+
"indian",
|
68 |
+
"japanese",
|
69 |
+
"corrupted",
|
70 |
+
"russian",
|
71 |
+
"italian",
|
72 |
+
"greek",
|
73 |
+
"bandit",
|
74 |
+
"vulture",
|
75 |
+
"scavenger",
|
76 |
+
"hacksaw",
|
77 |
+
"chick"
|
78 |
+
]
|
79 |
+
|
80 |
+
export function filterSensitiveContent(words: string[], badWords: string[] = sensitiveTopics): string[] {
|
81 |
+
return words.filter(x => !badWords.some(y => y.toLowerCase().startsWith(x.toLowerCase().trim())))
|
82 |
+
}
|
src/lib/fun-words/index.ts
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import funWordList from "fun-word-list"
|
2 |
+
import { filterSensitiveContent, sensitiveTopics } from "./filterSensitiveContent"
|
3 |
+
|
4 |
+
const {
|
5 |
+
addons, // Fragments to add to the end of sentences for different moods. Many include preceding commas or periods.
|
6 |
+
adjectives, // For use with `nouns` or `concepts`
|
7 |
+
concepts: rawConcepts, // Complex nouns
|
8 |
+
descriptions, // For use with `locations`
|
9 |
+
gametypes, // Video game genres/playstyles/feels
|
10 |
+
locations, // Nouns that represent places
|
11 |
+
nouns: rawNouns, // Simple things that can act or be acted upon
|
12 |
+
superlatives, // Adjectives that express the extremes of something. For use with `nouns`, `concepts`, or `locations`
|
13 |
+
verbs: { // All verbs in this list are used for acting in relation to another thing.
|
14 |
+
secondPerson: verbSecondPerson, // Verbs for use with "you" or "they" as in "you help the aardvark" or "they fight a bird"
|
15 |
+
secondConcepts: verbSecondConcepts, // Verbs for use with "you" or "they" in combination with `concepts` as in "you are helped by the King" or "they fight against traditions"
|
16 |
+
thirdPerson: verbThirdPerson, // Verbs for use with `nouns` as in "The aardvark anticipates rain"
|
17 |
+
}
|
18 |
+
} = funWordList
|
19 |
+
|
20 |
+
const nouns = rawNouns.filter(x => !sensitiveTopics.includes(x[0].toLowerCase().trim()))
|
21 |
+
const concepts = filterSensitiveContent(rawConcepts)
|
22 |
+
|
23 |
+
export {
|
24 |
+
addons, // Fragments to add to the end of sentences for different moods. Many include preceding commas or periods.
|
25 |
+
adjectives, // For use with `nouns` or `concepts`
|
26 |
+
concepts, // Complex nouns
|
27 |
+
descriptions, // For use with `locations`
|
28 |
+
gametypes, // Video game genres/playstyles/feels
|
29 |
+
locations, // Nouns that represent places
|
30 |
+
nouns, // Simple things that can act or be acted upon
|
31 |
+
superlatives, // Adjectives that express the extremes of something. For use with `nouns`, `concepts`, or `locations`
|
32 |
+
verbSecondPerson, // Verbs for use with "you" or "they" as in "you help the aardvark" or "they fight a bird"
|
33 |
+
verbSecondConcepts, // Verbs for use with "you" or "they" in combination with `concepts` as in "you are helped by the King" or "they fight against traditions"
|
34 |
+
verbThirdPerson, // Verbs for use with `nouns` as in "The aardvark anticipates rain"
|
35 |
+
}
|
src/lib/utils/generateRandomStory.ts
ADDED
@@ -0,0 +1,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { pick } from "@/lib/utils/pick"
|
2 |
+
import {
|
3 |
+
addons, // Fragments to add to the end of sentences for different moods. Many include preceding commas or periods.
|
4 |
+
adjectives, // For use with `nouns` or `concepts`
|
5 |
+
concepts, // Complex nouns
|
6 |
+
descriptions, // For use with `locations`
|
7 |
+
gametypes, // Video game genres/playstyles/feels
|
8 |
+
locations, // Nouns that represent places
|
9 |
+
nouns, // Simple things that can act or be acted upon
|
10 |
+
superlatives, // Adjectives that express the extremes of something. For use with `nouns`, `concepts`, or `locations`
|
11 |
+
verbSecondPerson, // Verbs for use with "you" or "they" as in "you help the aardvark" or "they fight a bird"
|
12 |
+
verbSecondConcepts, // Verbs for use with "you" or "they" in combination with `concepts` as in "you are helped by the King" or "they fight against traditions"
|
13 |
+
verbThirdPerson, // Verbs for use with `nouns` as in "The aardvark anticipates rain"
|
14 |
+
} from "@/lib/fun-words"
|
15 |
+
|
16 |
+
|
17 |
+
const moodTypes = [
|
18 |
+
"A fantasy",
|
19 |
+
"An epic",
|
20 |
+
"A beautiful",
|
21 |
+
"A science-fiction",
|
22 |
+
"A boring",
|
23 |
+
"A sad",
|
24 |
+
"A cheerful",
|
25 |
+
"A funny",
|
26 |
+
"A funny",
|
27 |
+
"A trending",
|
28 |
+
"A cute",
|
29 |
+
"An interesting",
|
30 |
+
"An outrageous",
|
31 |
+
"A dark",
|
32 |
+
"A 3D-rendered",
|
33 |
+
"An animated",
|
34 |
+
"Burlesque",
|
35 |
+
"Short",
|
36 |
+
"Long",
|
37 |
+
"An inspiring",
|
38 |
+
"A marketing",
|
39 |
+
"A commercial",
|
40 |
+
"An internet",
|
41 |
+
"A stupid",
|
42 |
+
"A vintage",
|
43 |
+
]
|
44 |
+
|
45 |
+
const videoTypes = [
|
46 |
+
"fail compilation",
|
47 |
+
"influencer meltdown",
|
48 |
+
"breaking news",
|
49 |
+
"newscast",
|
50 |
+
"politician speech",
|
51 |
+
"found footage",
|
52 |
+
"meme video",
|
53 |
+
"rap video",
|
54 |
+
"animal documentary",
|
55 |
+
"music video",
|
56 |
+
"live video",
|
57 |
+
"advert",
|
58 |
+
"instagram video",
|
59 |
+
"short movie",
|
60 |
+
"documentary",
|
61 |
+
"movie trailer",
|
62 |
+
"TikTok video",
|
63 |
+
]
|
64 |
+
|
65 |
+
const locationTypes = [
|
66 |
+
"in some",
|
67 |
+
// "set somewhere in",
|
68 |
+
"near some",
|
69 |
+
]
|
70 |
+
|
71 |
+
export function generateRandomStory() {
|
72 |
+
|
73 |
+
let pickedWords: any[] = []
|
74 |
+
|
75 |
+
function randomize<T>(words: T[]): T {
|
76 |
+
const picked = pick(words, '' as T)
|
77 |
+
pickedWords.push(picked as any)
|
78 |
+
return picked
|
79 |
+
}
|
80 |
+
|
81 |
+
return `${
|
82 |
+
pick(moodTypes, '')
|
83 |
+
} ${
|
84 |
+
pick(videoTypes, '')
|
85 |
+
}${
|
86 |
+
Math.random() > 0.5 ? "," : ""
|
87 |
+
} ${
|
88 |
+
pick(locationTypes, '')
|
89 |
+
} ${
|
90 |
+
randomize(descriptions)
|
91 |
+
} and ${
|
92 |
+
randomize(descriptions)
|
93 |
+
} ${
|
94 |
+
randomize(locations)
|
95 |
+
}. It is about ${
|
96 |
+
randomize(nouns)[1]
|
97 |
+
}, ${
|
98 |
+
randomize(nouns)[0]
|
99 |
+
} ${
|
100 |
+
randomize(nouns)[1]
|
101 |
+
} and..`
|
102 |
+
}
|
src/lib/utils/pick.ts
CHANGED
@@ -1,2 +1,22 @@
|
|
1 |
|
2 |
-
export
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
|
2 |
+
export function pick<T>(items: T[], defaultValue: T, {
|
3 |
+
skipList = [],
|
4 |
+
maxRetries = 10
|
5 |
+
}: {
|
6 |
+
skipList?: T[]
|
7 |
+
maxRetries?: number
|
8 |
+
} = {
|
9 |
+
skipList: [],
|
10 |
+
maxRetries: 10
|
11 |
+
}): T {
|
12 |
+
let candidate: T | undefined = undefined
|
13 |
+
for (let i = 0; i < maxRetries; i++) {
|
14 |
+
candidate = items[Math.floor(Math.random() * items.length)] as T
|
15 |
+
if (skipList.includes(candidate)) { continue }
|
16 |
+
}
|
17 |
+
if (typeof candidate === "undefined") {
|
18 |
+
return defaultValue
|
19 |
+
} else {
|
20 |
+
return candidate
|
21 |
+
}
|
22 |
+
}
|
src/lib/utils/{putTextInInput.ts → putTextInTextAreaElement.ts}
RENAMED
@@ -1,8 +1,8 @@
|
|
1 |
-
export function
|
2 |
if (!input) { return }
|
3 |
|
4 |
const nativeTextAreaValueSetter = Object.getOwnPropertyDescriptor(
|
5 |
-
window.
|
6 |
"value"
|
7 |
)?.set;
|
8 |
|
|
|
1 |
+
export function putTextInTextAreaElement(input?: HTMLTextAreaElement , text: string = "") {
|
2 |
if (!input) { return }
|
3 |
|
4 |
const nativeTextAreaValueSetter = Object.getOwnPropertyDescriptor(
|
5 |
+
window.HTMLTextAreaElement.prototype,
|
6 |
"value"
|
7 |
)?.set;
|
8 |
|
tailwind.config.js
CHANGED
@@ -37,10 +37,16 @@ module.exports = {
|
|
37 |
from: { height: "var(--radix-accordion-content-height)" },
|
38 |
to: { height: 0 },
|
39 |
},
|
|
|
|
|
|
|
|
|
|
|
40 |
},
|
41 |
animation: {
|
42 |
-
"accordion-down": "accordion-down 0.2s ease-out",
|
43 |
-
"accordion-up": "accordion-up 0.2s ease-out",
|
|
|
44 |
},
|
45 |
screens: {
|
46 |
'print': { 'raw': 'print' },
|
|
|
37 |
from: { height: "var(--radix-accordion-content-height)" },
|
38 |
to: { height: 0 },
|
39 |
},
|
40 |
+
|
41 |
+
swing: {
|
42 |
+
'0%,100%' : { transform: 'rotate(10deg)' },
|
43 |
+
'50%' : { transform: 'rotate(-10deg)' },
|
44 |
+
}
|
45 |
},
|
46 |
animation: {
|
47 |
+
"accordion-down": "accordion-down 0.2s ease-in-out",
|
48 |
+
"accordion-up": "accordion-up 0.2s ease-in-out",
|
49 |
+
'swing': 'swing 0.8s ease-in-out infinite'
|
50 |
},
|
51 |
screens: {
|
52 |
'print': { 'raw': 'print' },
|