Julian Bilcke
commited on
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' },
|