jbilcke-hf HF staff commited on
Commit
c8c2f6c
1 Parent(s): 831b708

add button for more randomness

Browse files
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
- {canSeeBetaFeatures ?
 
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> : <div></div>
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 { putTextInInput } from "@/lib/utils/putTextInInput"
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
- putTextInInput(document.getElementById("story-prompt-draft") as HTMLInputElement, storyPrompt)
 
 
 
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 const pick = (items: string[]) => items[Math.floor(Math.random()*items.length)]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 putTextInInput(input?: HTMLInputElement, text: string = "") {
2
  if (!input) { return }
3
 
4
  const nativeTextAreaValueSetter = Object.getOwnPropertyDescriptor(
5
- window.HTMLInputElement.prototype,
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' },