jbilcke-hf HF Staff commited on
Commit
a3d40b4
·
1 Parent(s): 4b590f9

rename aitube2 to tikslop

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. DEPLOYMENT.md +13 -13
  2. README.md +10 -10
  3. android/app/build.gradle +2 -2
  4. android/app/src/main/AndroidManifest.xml +1 -1
  5. android/app/src/main/kotlin/com/example/{aitube2 → tikslop}/MainActivity.kt +1 -1
  6. api_config.py +2 -2
  7. assets/logo/{aitube.png → tikslop.png} +0 -0
  8. assets/logo/{aitube.svg → tikslop.svg} +0 -0
  9. build/web/assets/AssetManifest.bin +1 -1
  10. build/web/assets/AssetManifest.bin.json +1 -1
  11. build/web/assets/AssetManifest.json +1 -1
  12. build/web/assets/assets/config/aitube.yaml +0 -61
  13. assets/config/aitube.yaml → build/web/assets/assets/config/tikslop.yaml +0 -0
  14. build/web/flutter_bootstrap.js +1 -1
  15. build/web/flutter_service_worker.js +13 -13
  16. build/web/index.html +4 -4
  17. build/web/main.dart.js +0 -0
  18. build/web/manifest.json +2 -2
  19. build/web/{aitube.png → tikslop.png} +0 -0
  20. build/web/{aitube.svg → tikslop.svg} +0 -0
  21. build/web/version.json +1 -1
  22. ios/Runner.xcodeproj/project.pbxproj +6 -6
  23. ios/Runner/Info.plist +2 -2
  24. lib/config/README.md +2 -2
  25. lib/config/config.dart +1 -1
  26. lib/config/secrets.sample.dart +1 -1
  27. lib/main.dart +36 -36
  28. lib/screens/home_screen.dart +26 -26
  29. lib/screens/settings_screen.dart +4 -4
  30. lib/screens/video_screen.dart +28 -28
  31. lib/services/chat_service.dart +1 -1
  32. lib/services/clip_queue/clip_generation_handler.dart +1 -1
  33. lib/services/clip_queue/clip_queue_manager.dart +1 -1
  34. lib/services/settings_service.dart +1 -1
  35. lib/services/websocket_api_service.dart +8 -8
  36. lib/theme/colors.dart +1 -1
  37. lib/widgets/api_key_dialog.dart +6 -6
  38. lib/widgets/chat_widget.dart +16 -16
  39. lib/widgets/maintenance_screen.dart +2 -2
  40. lib/widgets/search_box.dart +4 -4
  41. lib/widgets/video_card.dart +12 -12
  42. lib/widgets/video_player/buffer_manager.dart +5 -5
  43. lib/widgets/video_player/nano_clip_manager.dart +5 -5
  44. lib/widgets/video_player/nano_video_player.dart +6 -6
  45. lib/widgets/video_player/playback_controller.dart +2 -2
  46. lib/widgets/video_player/ui_components.dart +4 -4
  47. lib/widgets/video_player/video_player_widget.dart +5 -5
  48. lib/widgets/web_utils.dart +1 -1
  49. linux/CMakeLists.txt +2 -2
  50. linux/my_application.cc +2 -2
DEPLOYMENT.md CHANGED
@@ -1,7 +1,7 @@
1
 
2
- ## Deploying aitube2 to https://aitube.at
3
 
4
- Note: this document is meant for aitube administrators only, not the general public.
5
 
6
  Aitube is not an app/tool but a website, it is not designed to be cloned (technically you can, but since this is not a goal it is not documented).
7
 
@@ -29,7 +29,7 @@ See paragraph "Running the gateway scheduler"
29
 
30
  ### Deployment to production
31
 
32
- To deploy the aitube2 api to production:
33
 
34
  $ flutter build web
35
  $ git add .
@@ -38,13 +38,13 @@ To deploy the aitube2 api to production:
38
 
39
  and upload the assets to:
40
 
41
- https://huggingface.co/spaces/jbilcke-hf/aitube2/tree/main/public
42
 
43
  #### Running a rendering node
44
 
45
- Current aitube uses `jbilcke-hf/LTX-Video-0-9-6-HFIE` as a rendering node.
46
 
47
- aitube uses a round-robin schedule implemented on the gateway.
48
  This helps ensuring a smooth attribution of requests.
49
 
50
  What works well is to use the target number of users in parallel (eg. 3) and use 50% more capability to make sure we can handle the load, so in this case about 5 servers.
@@ -62,7 +62,7 @@ curl https://api.endpoints.huggingface.cloud/v2/endpoint/<YOUR_ACCOUNT_NAME> -X
62
  # (if you haven't done it already for this shell session)
63
  source .python_venv/bin/activate
64
 
65
- PRODUCT_NAME="AiTube" \
66
  MAX_NODES="3" \
67
  MAINTENANCE_MODE=false \
68
  HF_TOKEN="<USE YOUR OWN HF TOKEN>" \
@@ -82,10 +82,10 @@ PRODUCT_NAME="AiTube" \
82
 
83
  ```bash
84
  # For local development with default configuration
85
- flutter run --dart-define=CONFIG_PATH=assets/config/aitube.yaml -d chrome
86
 
87
  # For production build to be deployed on a server
88
- flutter build web --dart-define=CONFIG_PATH=assets/config/aitube.yaml
89
  ```
90
 
91
  ### WebSocket Connection
@@ -98,22 +98,22 @@ The application automatically determines the WebSocket URL:
98
  - No configuration needed for deployment
99
 
100
  2. **Native Platforms**:
101
- - Production: Automatically uses `wss://aitube.at/ws` when built with production flag
102
  - Development: Uses `ws://localhost:8080/ws` by default
103
  - Custom: Can override with `API_WS_URL` environment variable (highest priority)
104
 
105
  #### Production Native Build
106
 
107
- For production builds (connecting to aitube.at):
108
  ```bash
109
- flutter build apk --dart-define=CONFIG_PATH=assets/config/aitube.yaml --dart-define=PRODUCTION_MODE=true
110
  ```
111
 
112
  #### Custom API Server
113
 
114
  For connecting to a different server:
115
  ```bash
116
- flutter build apk --dart-define=CONFIG_PATH=assets/config/aitube.yaml --dart-define=API_WS_URL=ws://custom-api.example.com/ws
117
  ```
118
 
119
  Note: The `API_WS_URL` parameter takes precedence over the production setting.
 
1
 
2
+ ## Deploying tikslop to https://tikslop.at
3
 
4
+ Note: this document is meant for tikslop administrators only, not the general public.
5
 
6
  Aitube is not an app/tool but a website, it is not designed to be cloned (technically you can, but since this is not a goal it is not documented).
7
 
 
29
 
30
  ### Deployment to production
31
 
32
+ To deploy the tikslop api to production:
33
 
34
  $ flutter build web
35
  $ git add .
 
38
 
39
  and upload the assets to:
40
 
41
+ https://huggingface.co/spaces/jbilcke-hf/tikslop/tree/main/public
42
 
43
  #### Running a rendering node
44
 
45
+ Current tikslop uses `jbilcke-hf/LTX-Video-0-9-6-HFIE` as a rendering node.
46
 
47
+ tikslop uses a round-robin schedule implemented on the gateway.
48
  This helps ensuring a smooth attribution of requests.
49
 
50
  What works well is to use the target number of users in parallel (eg. 3) and use 50% more capability to make sure we can handle the load, so in this case about 5 servers.
 
62
  # (if you haven't done it already for this shell session)
63
  source .python_venv/bin/activate
64
 
65
+ PRODUCT_NAME="TikSlop" \
66
  MAX_NODES="3" \
67
  MAINTENANCE_MODE=false \
68
  HF_TOKEN="<USE YOUR OWN HF TOKEN>" \
 
82
 
83
  ```bash
84
  # For local development with default configuration
85
+ flutter run --dart-define=CONFIG_PATH=assets/config/tikslop.yaml -d chrome
86
 
87
  # For production build to be deployed on a server
88
+ flutter build web --dart-define=CONFIG_PATH=assets/config/tikslop.yaml
89
  ```
90
 
91
  ### WebSocket Connection
 
98
  - No configuration needed for deployment
99
 
100
  2. **Native Platforms**:
101
+ - Production: Automatically uses `wss://tikslop.at/ws` when built with production flag
102
  - Development: Uses `ws://localhost:8080/ws` by default
103
  - Custom: Can override with `API_WS_URL` environment variable (highest priority)
104
 
105
  #### Production Native Build
106
 
107
+ For production builds (connecting to tikslop.at):
108
  ```bash
109
+ flutter build apk --dart-define=CONFIG_PATH=assets/config/tikslop.yaml --dart-define=PRODUCTION_MODE=true
110
  ```
111
 
112
  #### Custom API Server
113
 
114
  For connecting to a different server:
115
  ```bash
116
+ flutter build apk --dart-define=CONFIG_PATH=assets/config/tikslop.yaml --dart-define=API_WS_URL=ws://custom-api.example.com/ws
117
  ```
118
 
119
  Note: The `API_WS_URL` parameter takes precedence over the production setting.
README.md CHANGED
@@ -1,5 +1,5 @@
1
  ---
2
- title: "#aitube2"
3
  emoji: 🍿
4
  colorFrom: red
5
  colorTo: red
@@ -19,41 +19,41 @@ hf_oauth_scopes:
19
  ---
20
 
21
 
22
- # #aitube2
23
 
24
  ## Configuration
25
 
26
  ### WebSocket Connection
27
  - **Web Platform**: Automatically connects to the host serving the page (adapts to both HTTP/HTTPS)
28
  - **Native Platforms**:
29
- - Production: Uses `wss://aitube.at/ws` when built with `--dart-define=PRODUCTION_MODE=true`
30
  - Development: Uses `ws://localhost:8080/ws` by default
31
  - Custom: Set `API_WS_URL` during build with `--dart-define=API_WS_URL=ws://your-server:port/ws` (highest priority)
32
 
33
  ## News
34
 
35
- #aitube2 is coming sooner than expected!
36
 
37
  Stay hooked at @flngr on X!
38
 
39
 
40
- ## What is AiTube?
41
 
42
- #aitube2 is a reboot of [AiTube 1](https://x.com/danielpikl/status/1737882643625078835), a project made in 2023 which generated AI videos in the background using LLM agents, to simulate an AI generated video platform.
43
 
44
- In [#aitube2](https://x.com/flngr/status/1864127796945011016), this concept is put upside down: now the content is generated on demand (when the user types something in the latent search input) and on the fly (video chunks are generated within a few seconds and streamed continuously).
45
 
46
  This allows for new ways of consuming AI generated content, such as collaborative and interactive prompting.
47
 
48
  # Where can I use it?
49
 
50
- #aitube2 is not ready yet: this is an experimental side project and the [platform](https://aitube.at), code and documentation will be in development for most of 2025.
51
 
52
  # Why can't I use it?
53
 
54
  As this is a personal project I only have limited ressources to develop it on the side, but there are also technological bottlenecks.
55
 
56
- Right now it is not economically viable to operate a platform like AiTube, it requires hardware that is too expensive and/or not powerful enough to give an enjoyable and reactive streaming experience.
57
 
58
  I am evaluating various options to make it available sooner for people with the financial ressources to try it, such as creating a system to deploy render nodes to Hugging Face, GPU-on-demand blockchains.. etc.
59
 
@@ -61,6 +61,6 @@ I am evaluating various options to make it available sooner for people with the
61
 
62
  I estimate it will take up to 1 to 2 years for more powerful and/or cheaper hardware to become available.
63
 
64
- I already have a open-source prototype of AiTube which I use for R&D, based on free (as in "can run on your own machine") AI video models that can run fast with low quality settings (such as LTX Video).
65
 
66
  It's not representative of the final experience, but that's a start and I use that as a basis to imagine the experiences of the future (collaborative generation, broadcasted live streams, interactive gaming, and artistic experiences that are hybrid between video and gaming).
 
1
  ---
2
+ title: "#tikslop"
3
  emoji: 🍿
4
  colorFrom: red
5
  colorTo: red
 
19
  ---
20
 
21
 
22
+ # #tikslop
23
 
24
  ## Configuration
25
 
26
  ### WebSocket Connection
27
  - **Web Platform**: Automatically connects to the host serving the page (adapts to both HTTP/HTTPS)
28
  - **Native Platforms**:
29
+ - Production: Uses `wss://tikslop.at/ws` when built with `--dart-define=PRODUCTION_MODE=true`
30
  - Development: Uses `ws://localhost:8080/ws` by default
31
  - Custom: Set `API_WS_URL` during build with `--dart-define=API_WS_URL=ws://your-server:port/ws` (highest priority)
32
 
33
  ## News
34
 
35
+ #tikslop is coming sooner than expected!
36
 
37
  Stay hooked at @flngr on X!
38
 
39
 
40
+ ## What is TikSlop?
41
 
42
+ #tikslop is a reboot of [TikSlop 1](https://x.com/danielpikl/status/1737882643625078835), a project made in 2023 which generated AI videos in the background using LLM agents, to simulate an AI generated video platform.
43
 
44
+ In [#tikslop](https://x.com/flngr/status/1864127796945011016), this concept is put upside down: now the content is generated on demand (when the user types something in the latent search input) and on the fly (video chunks are generated within a few seconds and streamed continuously).
45
 
46
  This allows for new ways of consuming AI generated content, such as collaborative and interactive prompting.
47
 
48
  # Where can I use it?
49
 
50
+ #tikslop is not ready yet: this is an experimental side project and the [platform](https://tikslop.at), code and documentation will be in development for most of 2025.
51
 
52
  # Why can't I use it?
53
 
54
  As this is a personal project I only have limited ressources to develop it on the side, but there are also technological bottlenecks.
55
 
56
+ Right now it is not economically viable to operate a platform like TikSlop, it requires hardware that is too expensive and/or not powerful enough to give an enjoyable and reactive streaming experience.
57
 
58
  I am evaluating various options to make it available sooner for people with the financial ressources to try it, such as creating a system to deploy render nodes to Hugging Face, GPU-on-demand blockchains.. etc.
59
 
 
61
 
62
  I estimate it will take up to 1 to 2 years for more powerful and/or cheaper hardware to become available.
63
 
64
+ I already have a open-source prototype of TikSlop which I use for R&D, based on free (as in "can run on your own machine") AI video models that can run fast with low quality settings (such as LTX Video).
65
 
66
  It's not representative of the final experience, but that's a start and I use that as a basis to imagine the experiences of the future (collaborative generation, broadcasted live streams, interactive gaming, and artistic experiences that are hybrid between video and gaming).
android/app/build.gradle CHANGED
@@ -6,7 +6,7 @@ plugins {
6
  }
7
 
8
  android {
9
- namespace = "com.example.aitube2"
10
  compileSdk = flutter.compileSdkVersion
11
  ndkVersion = flutter.ndkVersion
12
 
@@ -21,7 +21,7 @@ android {
21
 
22
  defaultConfig {
23
  // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
24
- applicationId = "com.example.aitube2"
25
  // You can update the following values to match your application needs.
26
  // For more information, see: https://flutter.dev/to/review-gradle-config.
27
  minSdk = flutter.minSdkVersion
 
6
  }
7
 
8
  android {
9
+ namespace = "com.example.tikslop"
10
  compileSdk = flutter.compileSdkVersion
11
  ndkVersion = flutter.ndkVersion
12
 
 
21
 
22
  defaultConfig {
23
  // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
24
+ applicationId = "com.example.tikslop"
25
  // You can update the following values to match your application needs.
26
  // For more information, see: https://flutter.dev/to/review-gradle-config.
27
  minSdk = flutter.minSdkVersion
android/app/src/main/AndroidManifest.xml CHANGED
@@ -1,6 +1,6 @@
1
  <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
  <application
3
- android:label="aitube2"
4
  android:name="${applicationName}"
5
  android:icon="@mipmap/ic_launcher">
6
  <activity
 
1
  <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
  <application
3
+ android:label="tikslop"
4
  android:name="${applicationName}"
5
  android:icon="@mipmap/ic_launcher">
6
  <activity
android/app/src/main/kotlin/com/example/{aitube2 → tikslop}/MainActivity.kt RENAMED
@@ -1,4 +1,4 @@
1
- package com.example.aitube2
2
 
3
  import io.flutter.embedding.android.FlutterActivity
4
 
 
1
+ package com.example.tikslop
2
 
3
  import io.flutter.embedding.android.FlutterActivity
4
 
api_config.py CHANGED
@@ -1,6 +1,6 @@
1
  import os
2
 
3
- PRODUCT_NAME = os.environ.get('PRODUCT_NAME', 'AiTube')
4
  PRODUCT_VERSION = "2.0.0"
5
 
6
  # you should use Mistral 7b instruct for good performance and accuracy balance
@@ -47,7 +47,7 @@ GUIDANCE_SCALE = 1.0
47
 
48
  THUMBNAIL_FRAMES = 65
49
 
50
- # anonymous users are people browing AiTube2 without being connected
51
  # this category suffers from regular abuse so we need to enforce strict limitations
52
  CONFIG_FOR_ANONYMOUS_USERS = {
53
 
 
1
  import os
2
 
3
+ PRODUCT_NAME = os.environ.get('PRODUCT_NAME', 'TikSlop')
4
  PRODUCT_VERSION = "2.0.0"
5
 
6
  # you should use Mistral 7b instruct for good performance and accuracy balance
 
47
 
48
  THUMBNAIL_FRAMES = 65
49
 
50
+ # anonymous users are people browing TikSlop without being connected
51
  # this category suffers from regular abuse so we need to enforce strict limitations
52
  CONFIG_FOR_ANONYMOUS_USERS = {
53
 
assets/logo/{aitube.png → tikslop.png} RENAMED
File without changes
assets/logo/{aitube.svg → tikslop.svg} RENAMED
File without changes
build/web/assets/AssetManifest.bin CHANGED
@@ -1 +1 @@
1
-
 
1
+
build/web/assets/AssetManifest.bin.json CHANGED
@@ -1 +1 @@
1
- "DQUHF2Fzc2V0cy9jb25maWcvUkVBRE1FLm1kDAENAQcFYXNzZXQHF2Fzc2V0cy9jb25maWcvUkVBRE1FLm1kBxlhc3NldHMvY29uZmlnL2FpdHViZS55YW1sDAENAQcFYXNzZXQHGWFzc2V0cy9jb25maWcvYWl0dWJlLnlhbWwHGWFzc2V0cy9jb25maWcvY3VzdG9tLnlhbWwMAQ0BBwVhc3NldAcZYXNzZXRzL2NvbmZpZy9jdXN0b20ueWFtbAcaYXNzZXRzL2NvbmZpZy9kZWZhdWx0LnlhbWwMAQ0BBwVhc3NldAcaYXNzZXRzL2NvbmZpZy9kZWZhdWx0LnlhbWwHMnBhY2thZ2VzL2N1cGVydGlub19pY29ucy9hc3NldHMvQ3VwZXJ0aW5vSWNvbnMudHRmDAENAQcFYXNzZXQHMnBhY2thZ2VzL2N1cGVydGlub19pY29ucy9hc3NldHMvQ3VwZXJ0aW5vSWNvbnMudHRm"
 
1
+ "DQUHF2Fzc2V0cy9jb25maWcvUkVBRE1FLm1kDAENAQcFYXNzZXQHF2Fzc2V0cy9jb25maWcvUkVBRE1FLm1kBxlhc3NldHMvY29uZmlnL2N1c3RvbS55YW1sDAENAQcFYXNzZXQHGWFzc2V0cy9jb25maWcvY3VzdG9tLnlhbWwHGmFzc2V0cy9jb25maWcvZGVmYXVsdC55YW1sDAENAQcFYXNzZXQHGmFzc2V0cy9jb25maWcvZGVmYXVsdC55YW1sBxphc3NldHMvY29uZmlnL3Rpa3Nsb3AueWFtbAwBDQEHBWFzc2V0Bxphc3NldHMvY29uZmlnL3Rpa3Nsb3AueWFtbAcycGFja2FnZXMvY3VwZXJ0aW5vX2ljb25zL2Fzc2V0cy9DdXBlcnRpbm9JY29ucy50dGYMAQ0BBwVhc3NldAcycGFja2FnZXMvY3VwZXJ0aW5vX2ljb25zL2Fzc2V0cy9DdXBlcnRpbm9JY29ucy50dGY="
build/web/assets/AssetManifest.json CHANGED
@@ -1 +1 @@
1
- {"assets/config/README.md":["assets/config/README.md"],"assets/config/aitube.yaml":["assets/config/aitube.yaml"],"assets/config/custom.yaml":["assets/config/custom.yaml"],"assets/config/default.yaml":["assets/config/default.yaml"],"packages/cupertino_icons/assets/CupertinoIcons.ttf":["packages/cupertino_icons/assets/CupertinoIcons.ttf"]}
 
1
+ {"assets/config/README.md":["assets/config/README.md"],"assets/config/custom.yaml":["assets/config/custom.yaml"],"assets/config/default.yaml":["assets/config/default.yaml"],"assets/config/tikslop.yaml":["assets/config/tikslop.yaml"],"packages/cupertino_icons/assets/CupertinoIcons.ttf":["packages/cupertino_icons/assets/CupertinoIcons.ttf"]}
build/web/assets/assets/config/aitube.yaml DELETED
@@ -1,61 +0,0 @@
1
- ui:
2
- product_name: "#aitube2"
3
- showChatInVideoView: false
4
-
5
- render_queue:
6
- # how many clips should be stored in advance
7
- buffer_size: 3
8
-
9
- # how many requests for clips can be run in parallel
10
- max_concurrent_generations: 2
11
-
12
- # start playback as soon as we have 1 video over 3 (25%)
13
- minimum_buffer_percent_to_start_playback: 5
14
-
15
- simulation:
16
- # how often the description should evolve (in seconds)
17
- # setting to 0 disables description evolution
18
- sim_loop_frequency_in_sec: 10
19
-
20
- # it's OK to use high values here,
21
- # because some of those values are limited by the backend config,
22
- # such as the resoltuion or number of frames
23
- video:
24
- default_negative_prompt: ""
25
-
26
- # transition time between each clip
27
- # the exit (older) clip will see its playback time reduced by this amount
28
- transition_buffer_duration_ms: 300
29
-
30
- # how long a generated clip should be, in Duration
31
- original_clip_duration_seconds: 3
32
-
33
- # The model works on resolutions that are divisible by 32
34
- # and number of frames that are divisible by 8 + 1 (e.g. 257).
35
- #
36
- # In case the resolution or number of frames are not divisible
37
- # by 32 or 8 + 1, the input will be padded with -1 and then
38
- # cropped to the desired resolution and number of frames.
39
- #
40
- # The model works best on resolutions under 720 x 1280 and
41
- # number of frames below 257.
42
-
43
- # number of inference steps
44
- # (this is capped by the backend API)
45
- num_inference_steps: 8
46
-
47
- guidance_scale: 1.0
48
-
49
- # original frame-rate of each clip (before we slow them down)
50
- # in frames per second (so an integer)
51
- original_clip_frame_rate: 25
52
-
53
- # (this is capped by the backend API)
54
- original_clip_width: 1216
55
-
56
- # (this is capped by the backend API)
57
- original_clip_height: 672
58
-
59
- # to do more with less, we slow down the videos (a 3s video will become a 4s video)
60
- # but if you are GPU rich feel feel to play them back at 100% of their speed!
61
- clip_playback_speed: 0.7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/config/aitube.yaml → build/web/assets/assets/config/tikslop.yaml RENAMED
File without changes
build/web/flutter_bootstrap.js CHANGED
@@ -39,6 +39,6 @@ _flutter.buildConfig = {"engineRevision":"382be0028d370607f76215a9be322e5514b263
39
 
40
  _flutter.loader.load({
41
  serviceWorkerSettings: {
42
- serviceWorkerVersion: "3100260862"
43
  }
44
  });
 
39
 
40
  _flutter.loader.load({
41
  serviceWorkerSettings: {
42
+ serviceWorkerVersion: "3718327370"
43
  }
44
  });
build/web/flutter_service_worker.js CHANGED
@@ -3,31 +3,32 @@ const MANIFEST = 'flutter-app-manifest';
3
  const TEMP = 'flutter-temp-cache';
4
  const CACHE_NAME = 'flutter-app-cache';
5
 
6
- const RESOURCES = {"flutter_bootstrap.js": "aa0de14d9015e57eee1c8b8d203d37cc",
7
- "version.json": "b5eaae4fc120710a3c35125322173615",
8
- "index.html": "2677c99782b3eb75aae7c757748ccacb",
9
- "/": "2677c99782b3eb75aae7c757748ccacb",
10
- "main.dart.js": "1990588d3a6b9429f5509a0d68c2e0c5",
 
 
11
  "flutter.js": "83d881c1dbb6d6bcd6b42e274605b69c",
12
- "aitube.svg": "26140ba0d153b213b122bc6ebcc17f6c",
13
  "favicon.png": "c8a183c516004e648a7bac7497c89b97",
14
  "icons/Icon-192.png": "9d17785814071b986002307441ec7a8f",
15
  "icons/Icon-maskable-192.png": "9d17785814071b986002307441ec7a8f",
16
  "icons/Icon-maskable-512.png": "8682b581a7dab984ef4f9b7f21976a64",
17
  "icons/Icon-512.png": "8682b581a7dab984ef4f9b7f21976a64",
18
- "manifest.json": "7dc942a630334c1017089988a6ca07d4",
19
- "assets/AssetManifest.json": "51a53d0237971d07d6d88304c41bf6fb",
20
  "assets/NOTICES": "f0cfae681e209e19b2b144a9f062a96f",
21
  "assets/FontManifest.json": "dc3d03800ccca4601324923c0b1d6d57",
22
- "assets/AssetManifest.bin.json": "f7a7f5619c8ca1575d7a5e0c6cd4d529",
23
  "assets/packages/cupertino_icons/assets/CupertinoIcons.ttf": "33b7d9392238c04c131b6ce224e13711",
24
  "assets/shaders/ink_sparkle.frag": "ecc85a2e95f5e9f53123dcaf8cb9b6ce",
25
- "assets/AssetManifest.bin": "6c597105edcadb9c676bdc998c88545a",
26
  "assets/fonts/MaterialIcons-Regular.otf": "06b86454c633cc9510ad85ddc0523a91",
27
  "assets/assets/config/README.md": "07a87720dd00dd1ca98c9d6884440e31",
28
  "assets/assets/config/custom.yaml": "e5c0b238b6f217f1215fbc813f093656",
29
- "assets/assets/config/aitube.yaml": "7df9de77da965c3bea94f2c6d33a4b5f",
30
  "assets/assets/config/default.yaml": "d1304586fd15839a754f53dda3dd8a44",
 
31
  "canvaskit/skwasm.js": "ea559890a088fe28b4ddf70e17e60052",
32
  "canvaskit/skwasm.js.symbols": "9fe690d47b904d72c7d020bd303adf16",
33
  "canvaskit/canvaskit.js.symbols": "27361387bc24144b46a745f1afe92b50",
@@ -36,8 +37,7 @@ const RESOURCES = {"flutter_bootstrap.js": "aa0de14d9015e57eee1c8b8d203d37cc",
36
  "canvaskit/chromium/canvaskit.js": "8191e843020c832c9cf8852a4b909d4c",
37
  "canvaskit/chromium/canvaskit.wasm": "c054c2c892172308ca5a0bd1d7a7754b",
38
  "canvaskit/canvaskit.js": "728b2d477d9b8c14593d4f9b82b484f3",
39
- "canvaskit/canvaskit.wasm": "a37f2b0af4995714de856e21e882325c",
40
- "aitube.png": "570e1db759046e2d224fef729983634e"};
41
  // The application shell files that are downloaded before a service worker can
42
  // start.
43
  const CORE = ["main.dart.js",
 
3
  const TEMP = 'flutter-temp-cache';
4
  const CACHE_NAME = 'flutter-app-cache';
5
 
6
+ const RESOURCES = {"flutter_bootstrap.js": "fe60adda51a3823633b786075b6d10eb",
7
+ "version.json": "68350cac7987de2728345c72918dd067",
8
+ "tikslop.png": "570e1db759046e2d224fef729983634e",
9
+ "index.html": "820eb02576e6d66488611f1b19e15b63",
10
+ "/": "820eb02576e6d66488611f1b19e15b63",
11
+ "main.dart.js": "2c8a8ae55422254bad36b497dd408761",
12
+ "tikslop.svg": "26140ba0d153b213b122bc6ebcc17f6c",
13
  "flutter.js": "83d881c1dbb6d6bcd6b42e274605b69c",
 
14
  "favicon.png": "c8a183c516004e648a7bac7497c89b97",
15
  "icons/Icon-192.png": "9d17785814071b986002307441ec7a8f",
16
  "icons/Icon-maskable-192.png": "9d17785814071b986002307441ec7a8f",
17
  "icons/Icon-maskable-512.png": "8682b581a7dab984ef4f9b7f21976a64",
18
  "icons/Icon-512.png": "8682b581a7dab984ef4f9b7f21976a64",
19
+ "manifest.json": "c0904388ddaba6a9bd572a80f79a8dcc",
20
+ "assets/AssetManifest.json": "bf40bd52b84d1c4e4f27946b18178ffc",
21
  "assets/NOTICES": "f0cfae681e209e19b2b144a9f062a96f",
22
  "assets/FontManifest.json": "dc3d03800ccca4601324923c0b1d6d57",
23
+ "assets/AssetManifest.bin.json": "f7cde9e4f9fb8303a6858e8ce1b573db",
24
  "assets/packages/cupertino_icons/assets/CupertinoIcons.ttf": "33b7d9392238c04c131b6ce224e13711",
25
  "assets/shaders/ink_sparkle.frag": "ecc85a2e95f5e9f53123dcaf8cb9b6ce",
26
+ "assets/AssetManifest.bin": "87dcd71e038a4b45c095cccdab2777d4",
27
  "assets/fonts/MaterialIcons-Regular.otf": "06b86454c633cc9510ad85ddc0523a91",
28
  "assets/assets/config/README.md": "07a87720dd00dd1ca98c9d6884440e31",
29
  "assets/assets/config/custom.yaml": "e5c0b238b6f217f1215fbc813f093656",
 
30
  "assets/assets/config/default.yaml": "d1304586fd15839a754f53dda3dd8a44",
31
+ "assets/assets/config/tikslop.yaml": "7df9de77da965c3bea94f2c6d33a4b5f",
32
  "canvaskit/skwasm.js": "ea559890a088fe28b4ddf70e17e60052",
33
  "canvaskit/skwasm.js.symbols": "9fe690d47b904d72c7d020bd303adf16",
34
  "canvaskit/canvaskit.js.symbols": "27361387bc24144b46a745f1afe92b50",
 
37
  "canvaskit/chromium/canvaskit.js": "8191e843020c832c9cf8852a4b909d4c",
38
  "canvaskit/chromium/canvaskit.wasm": "c054c2c892172308ca5a0bd1d7a7754b",
39
  "canvaskit/canvaskit.js": "728b2d477d9b8c14593d4f9b82b484f3",
40
+ "canvaskit/canvaskit.wasm": "a37f2b0af4995714de856e21e882325c"};
 
41
  // The application shell files that are downloaded before a service worker can
42
  // start.
43
  const CORE = ["main.dart.js",
build/web/index.html CHANGED
@@ -29,7 +29,7 @@
29
  <!-- Favicon -->
30
  <link rel="icon" type="image/png" href="favicon.png"/>
31
 
32
- <title>#aitube2</title>
33
  <link rel="manifest" href="manifest.json">
34
 
35
  <style>
@@ -130,9 +130,9 @@
130
 
131
  <div class="loading-container" id="loading">
132
  <div class="logo-container">
133
- <img src="aitube.svg" alt="AITube Logo" class="logo">
134
  </div>
135
- <div class="loading-text">Loading #aitube2...</div>
136
  </div>
137
 
138
  <script>
@@ -156,7 +156,7 @@
156
  </script>
157
 
158
  <!-- Add version parameter for cache busting -->
159
- <script src="flutter_bootstrap.js?v=1747072784" async></script>
160
 
161
  <!-- Add cache busting script -->
162
  <script>
 
29
  <!-- Favicon -->
30
  <link rel="icon" type="image/png" href="favicon.png"/>
31
 
32
+ <title>#tikslop</title>
33
  <link rel="manifest" href="manifest.json">
34
 
35
  <style>
 
130
 
131
  <div class="loading-container" id="loading">
132
  <div class="logo-container">
133
+ <img src="tikslop.svg" alt="AITube Logo" class="logo">
134
  </div>
135
+ <div class="loading-text">Loading #tikslop...</div>
136
  </div>
137
 
138
  <script>
 
156
  </script>
157
 
158
  <!-- Add version parameter for cache busting -->
159
+ <script src="flutter_bootstrap.js?v=1747138236" async></script>
160
 
161
  <!-- Add cache busting script -->
162
  <script>
build/web/main.dart.js CHANGED
The diff for this file is too large to render. See raw diff
 
build/web/manifest.json CHANGED
@@ -1,6 +1,6 @@
1
  {
2
- "name": "aitube2",
3
- "short_name": "aitube2",
4
  "start_url": ".",
5
  "display": "standalone",
6
  "background_color": "#0175C2",
 
1
  {
2
+ "name": "tikslop",
3
+ "short_name": "tikslop",
4
  "start_url": ".",
5
  "display": "standalone",
6
  "background_color": "#0175C2",
build/web/{aitube.png → tikslop.png} RENAMED
File without changes
build/web/{aitube.svg → tikslop.svg} RENAMED
File without changes
build/web/version.json CHANGED
@@ -1 +1 @@
1
- {"app_name":"aitube2","version":"1.0.0","build_number":"1","package_name":"aitube2"}
 
1
+ {"app_name":"tikslop","version":"1.0.0","build_number":"1","package_name":"tikslop"}
ios/Runner.xcodeproj/project.pbxproj CHANGED
@@ -368,7 +368,7 @@
368
  "$(inherited)",
369
  "@executable_path/Frameworks",
370
  );
371
- PRODUCT_BUNDLE_IDENTIFIER = com.example.aitube2;
372
  PRODUCT_NAME = "$(TARGET_NAME)";
373
  SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
374
  SWIFT_VERSION = 5.0;
@@ -384,7 +384,7 @@
384
  CURRENT_PROJECT_VERSION = 1;
385
  GENERATE_INFOPLIST_FILE = YES;
386
  MARKETING_VERSION = 1.0;
387
- PRODUCT_BUNDLE_IDENTIFIER = com.example.aitube2.RunnerTests;
388
  PRODUCT_NAME = "$(TARGET_NAME)";
389
  SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
390
  SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@@ -401,7 +401,7 @@
401
  CURRENT_PROJECT_VERSION = 1;
402
  GENERATE_INFOPLIST_FILE = YES;
403
  MARKETING_VERSION = 1.0;
404
- PRODUCT_BUNDLE_IDENTIFIER = com.example.aitube2.RunnerTests;
405
  PRODUCT_NAME = "$(TARGET_NAME)";
406
  SWIFT_VERSION = 5.0;
407
  TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
@@ -416,7 +416,7 @@
416
  CURRENT_PROJECT_VERSION = 1;
417
  GENERATE_INFOPLIST_FILE = YES;
418
  MARKETING_VERSION = 1.0;
419
- PRODUCT_BUNDLE_IDENTIFIER = com.example.aitube2.RunnerTests;
420
  PRODUCT_NAME = "$(TARGET_NAME)";
421
  SWIFT_VERSION = 5.0;
422
  TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
@@ -547,7 +547,7 @@
547
  "$(inherited)",
548
  "@executable_path/Frameworks",
549
  );
550
- PRODUCT_BUNDLE_IDENTIFIER = com.example.aitube2;
551
  PRODUCT_NAME = "$(TARGET_NAME)";
552
  SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
553
  SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@@ -569,7 +569,7 @@
569
  "$(inherited)",
570
  "@executable_path/Frameworks",
571
  );
572
- PRODUCT_BUNDLE_IDENTIFIER = com.example.aitube2;
573
  PRODUCT_NAME = "$(TARGET_NAME)";
574
  SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
575
  SWIFT_VERSION = 5.0;
 
368
  "$(inherited)",
369
  "@executable_path/Frameworks",
370
  );
371
+ PRODUCT_BUNDLE_IDENTIFIER = com.example.tikslop;
372
  PRODUCT_NAME = "$(TARGET_NAME)";
373
  SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
374
  SWIFT_VERSION = 5.0;
 
384
  CURRENT_PROJECT_VERSION = 1;
385
  GENERATE_INFOPLIST_FILE = YES;
386
  MARKETING_VERSION = 1.0;
387
+ PRODUCT_BUNDLE_IDENTIFIER = com.example.tikslop.RunnerTests;
388
  PRODUCT_NAME = "$(TARGET_NAME)";
389
  SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
390
  SWIFT_OPTIMIZATION_LEVEL = "-Onone";
 
401
  CURRENT_PROJECT_VERSION = 1;
402
  GENERATE_INFOPLIST_FILE = YES;
403
  MARKETING_VERSION = 1.0;
404
+ PRODUCT_BUNDLE_IDENTIFIER = com.example.tikslop.RunnerTests;
405
  PRODUCT_NAME = "$(TARGET_NAME)";
406
  SWIFT_VERSION = 5.0;
407
  TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
 
416
  CURRENT_PROJECT_VERSION = 1;
417
  GENERATE_INFOPLIST_FILE = YES;
418
  MARKETING_VERSION = 1.0;
419
+ PRODUCT_BUNDLE_IDENTIFIER = com.example.tikslop.RunnerTests;
420
  PRODUCT_NAME = "$(TARGET_NAME)";
421
  SWIFT_VERSION = 5.0;
422
  TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
 
547
  "$(inherited)",
548
  "@executable_path/Frameworks",
549
  );
550
+ PRODUCT_BUNDLE_IDENTIFIER = com.example.tikslop;
551
  PRODUCT_NAME = "$(TARGET_NAME)";
552
  SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
553
  SWIFT_OPTIMIZATION_LEVEL = "-Onone";
 
569
  "$(inherited)",
570
  "@executable_path/Frameworks",
571
  );
572
+ PRODUCT_BUNDLE_IDENTIFIER = com.example.tikslop;
573
  PRODUCT_NAME = "$(TARGET_NAME)";
574
  SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
575
  SWIFT_VERSION = 5.0;
ios/Runner/Info.plist CHANGED
@@ -5,7 +5,7 @@
5
  <key>CFBundleDevelopmentRegion</key>
6
  <string>$(DEVELOPMENT_LANGUAGE)</string>
7
  <key>CFBundleDisplayName</key>
8
- <string>Aitube2</string>
9
  <key>CFBundleExecutable</key>
10
  <string>$(EXECUTABLE_NAME)</string>
11
  <key>CFBundleIdentifier</key>
@@ -13,7 +13,7 @@
13
  <key>CFBundleInfoDictionaryVersion</key>
14
  <string>6.0</string>
15
  <key>CFBundleName</key>
16
- <string>aitube2</string>
17
  <key>CFBundlePackageType</key>
18
  <string>APPL</string>
19
  <key>CFBundleShortVersionString</key>
 
5
  <key>CFBundleDevelopmentRegion</key>
6
  <string>$(DEVELOPMENT_LANGUAGE)</string>
7
  <key>CFBundleDisplayName</key>
8
+ <string>TikSlop</string>
9
  <key>CFBundleExecutable</key>
10
  <string>$(EXECUTABLE_NAME)</string>
11
  <key>CFBundleIdentifier</key>
 
13
  <key>CFBundleInfoDictionaryVersion</key>
14
  <string>6.0</string>
15
  <key>CFBundleName</key>
16
+ <string>tikslop</string>
17
  <key>CFBundlePackageType</key>
18
  <string>APPL</string>
19
  <key>CFBundleShortVersionString</key>
lib/config/README.md CHANGED
@@ -3,10 +3,10 @@ Put secrets in here, used only during development
3
  eg
4
 
5
  ```
6
- class AiTubeSecrets {
7
  final String huggingfaceToken;
8
 
9
- AiTubeSecrets({
10
  this.huggingfaceToken = '',
11
  })
12
  }
 
3
  eg
4
 
5
  ```
6
+ class TikSlopSecrets {
7
  final String huggingfaceToken;
8
 
9
+ TikSlopSecrets({
10
  this.huggingfaceToken = '',
11
  })
12
  }
lib/config/config.dart CHANGED
@@ -20,7 +20,7 @@ class Configuration {
20
  // Get custom config path from environment
21
  const customConfigPath = String.fromEnvironment(
22
  'CONFIG_PATH',
23
- defaultValue: 'assets/config/aitube.yaml'
24
  );
25
 
26
  try {
 
20
  // Get custom config path from environment
21
  const customConfigPath = String.fromEnvironment(
22
  'CONFIG_PATH',
23
+ defaultValue: 'assets/config/tikslop.yaml'
24
  );
25
 
26
  try {
lib/config/secrets.sample.dart CHANGED
@@ -1,4 +1,4 @@
1
  /// SECRETS - KEEP THIS OUT OF GIT
2
- class AiTubeSecrets {
3
  static const huggingfaceToken = '<HIDDEN FOR CONFIDENTIALITY>';
4
  }
 
1
  /// SECRETS - KEEP THIS OUT OF GIT
2
+ class TikSlopSecrets {
3
  static const huggingfaceToken = '<HIDDEN FOR CONFIDENTIALITY>';
4
  }
lib/main.dart CHANGED
@@ -1,12 +1,12 @@
1
  // lib/main.dart
2
- import 'package:aitube2/config/config.dart';
3
- import 'package:aitube2/models/video_result.dart';
4
- import 'package:aitube2/screens/video_screen.dart';
5
- import 'package:aitube2/services/settings_service.dart';
6
- import 'package:aitube2/services/websocket_api_service.dart';
7
- import 'package:aitube2/theme/colors.dart';
8
- import 'package:aitube2/widgets/maintenance_screen.dart';
9
- import 'package:aitube2/widgets/web_utils.dart';
10
  import 'package:flutter/foundation.dart';
11
  import 'package:flutter/material.dart';
12
  import 'screens/home_screen.dart';
@@ -91,7 +91,7 @@ void main() async {
91
  wsService.statusStream.listen((status) {
92
  if (status == ConnectionStatus.maintenance) {
93
  // Force update to maintenance screen if server goes into maintenance mode later
94
- runApp(AiTubeApp(home: const MaintenanceScreen(error: null)));
95
  }
96
  });
97
 
@@ -107,13 +107,13 @@ void main() async {
107
  }
108
  }
109
 
110
- runApp(AiTubeApp(home: homeWidget));
111
  }
112
 
113
- class AiTubeApp extends StatelessWidget {
114
  final Widget home;
115
 
116
- const AiTubeApp({super.key, required this.home});
117
 
118
  @override
119
  Widget build(BuildContext context) {
@@ -121,56 +121,56 @@ class AiTubeApp extends StatelessWidget {
121
  title: Configuration.instance.uiProductName,
122
  theme: ThemeData.dark().copyWith(
123
  colorScheme: const ColorScheme.dark(
124
- surface: AiTubeColors.surface,
125
- surfaceContainerHighest: AiTubeColors.surfaceVariant,
126
- primary: AiTubeColors.primary,
127
- onSurface: AiTubeColors.onSurface,
128
- onSurfaceVariant: AiTubeColors.onSurfaceVariant,
129
  ),
130
- scaffoldBackgroundColor: AiTubeColors.background,
131
  cardTheme: CardThemeData(
132
- color: AiTubeColors.surface,
133
  elevation: 0,
134
  shape: RoundedRectangleBorder(
135
  borderRadius: BorderRadius.circular(12),
136
  ),
137
  ),
138
  appBarTheme: const AppBarTheme(
139
- backgroundColor: AiTubeColors.background,
140
  elevation: 0,
141
  ),
142
  textTheme: const TextTheme(
143
- titleLarge: TextStyle(color: AiTubeColors.onBackground),
144
- titleMedium: TextStyle(color: AiTubeColors.onBackground),
145
- bodyLarge: TextStyle(color: AiTubeColors.onSurface),
146
- bodyMedium: TextStyle(color: AiTubeColors.onSurfaceVariant),
147
  ),
148
  ),
149
  darkTheme: ThemeData.dark().copyWith(
150
  colorScheme: const ColorScheme.dark(
151
- surface: AiTubeColors.surface,
152
- surfaceContainerHighest: AiTubeColors.surfaceVariant,
153
- primary: AiTubeColors.primary,
154
- onSurface: AiTubeColors.onSurface,
155
- onSurfaceVariant: AiTubeColors.onSurfaceVariant,
156
  ),
157
- scaffoldBackgroundColor: AiTubeColors.background,
158
  cardTheme: CardThemeData(
159
- color: AiTubeColors.surface,
160
  elevation: 0,
161
  shape: RoundedRectangleBorder(
162
  borderRadius: BorderRadius.circular(12),
163
  ),
164
  ),
165
  appBarTheme: const AppBarTheme(
166
- backgroundColor: AiTubeColors.background,
167
  elevation: 0,
168
  ),
169
  textTheme: const TextTheme(
170
- titleLarge: TextStyle(color: AiTubeColors.onBackground),
171
- titleMedium: TextStyle(color: AiTubeColors.onBackground),
172
- bodyLarge: TextStyle(color: AiTubeColors.onSurface),
173
- bodyMedium: TextStyle(color: AiTubeColors.onSurfaceVariant),
174
  ),
175
  ),
176
  // Use custom route handling to support deep linking with URL parameters on web
 
1
  // lib/main.dart
2
+ import 'package:tikslop/config/config.dart';
3
+ import 'package:tikslop/models/video_result.dart';
4
+ import 'package:tikslop/screens/video_screen.dart';
5
+ import 'package:tikslop/services/settings_service.dart';
6
+ import 'package:tikslop/services/websocket_api_service.dart';
7
+ import 'package:tikslop/theme/colors.dart';
8
+ import 'package:tikslop/widgets/maintenance_screen.dart';
9
+ import 'package:tikslop/widgets/web_utils.dart';
10
  import 'package:flutter/foundation.dart';
11
  import 'package:flutter/material.dart';
12
  import 'screens/home_screen.dart';
 
91
  wsService.statusStream.listen((status) {
92
  if (status == ConnectionStatus.maintenance) {
93
  // Force update to maintenance screen if server goes into maintenance mode later
94
+ runApp(TikSlopApp(home: const MaintenanceScreen(error: null)));
95
  }
96
  });
97
 
 
107
  }
108
  }
109
 
110
+ runApp(TikSlopApp(home: homeWidget));
111
  }
112
 
113
+ class TikSlopApp extends StatelessWidget {
114
  final Widget home;
115
 
116
+ const TikSlopApp({super.key, required this.home});
117
 
118
  @override
119
  Widget build(BuildContext context) {
 
121
  title: Configuration.instance.uiProductName,
122
  theme: ThemeData.dark().copyWith(
123
  colorScheme: const ColorScheme.dark(
124
+ surface: TikSlopColors.surface,
125
+ surfaceContainerHighest: TikSlopColors.surfaceVariant,
126
+ primary: TikSlopColors.primary,
127
+ onSurface: TikSlopColors.onSurface,
128
+ onSurfaceVariant: TikSlopColors.onSurfaceVariant,
129
  ),
130
+ scaffoldBackgroundColor: TikSlopColors.background,
131
  cardTheme: CardThemeData(
132
+ color: TikSlopColors.surface,
133
  elevation: 0,
134
  shape: RoundedRectangleBorder(
135
  borderRadius: BorderRadius.circular(12),
136
  ),
137
  ),
138
  appBarTheme: const AppBarTheme(
139
+ backgroundColor: TikSlopColors.background,
140
  elevation: 0,
141
  ),
142
  textTheme: const TextTheme(
143
+ titleLarge: TextStyle(color: TikSlopColors.onBackground),
144
+ titleMedium: TextStyle(color: TikSlopColors.onBackground),
145
+ bodyLarge: TextStyle(color: TikSlopColors.onSurface),
146
+ bodyMedium: TextStyle(color: TikSlopColors.onSurfaceVariant),
147
  ),
148
  ),
149
  darkTheme: ThemeData.dark().copyWith(
150
  colorScheme: const ColorScheme.dark(
151
+ surface: TikSlopColors.surface,
152
+ surfaceContainerHighest: TikSlopColors.surfaceVariant,
153
+ primary: TikSlopColors.primary,
154
+ onSurface: TikSlopColors.onSurface,
155
+ onSurfaceVariant: TikSlopColors.onSurfaceVariant,
156
  ),
157
+ scaffoldBackgroundColor: TikSlopColors.background,
158
  cardTheme: CardThemeData(
159
+ color: TikSlopColors.surface,
160
  elevation: 0,
161
  shape: RoundedRectangleBorder(
162
  borderRadius: BorderRadius.circular(12),
163
  ),
164
  ),
165
  appBarTheme: const AppBarTheme(
166
+ backgroundColor: TikSlopColors.background,
167
  elevation: 0,
168
  ),
169
  textTheme: const TextTheme(
170
+ titleLarge: TextStyle(color: TikSlopColors.onBackground),
171
+ titleMedium: TextStyle(color: TikSlopColors.onBackground),
172
+ bodyLarge: TextStyle(color: TikSlopColors.onSurface),
173
+ bodyMedium: TextStyle(color: TikSlopColors.onSurfaceVariant),
174
  ),
175
  ),
176
  // Use custom route handling to support deep linking with URL parameters on web
lib/screens/home_screen.dart CHANGED
@@ -1,18 +1,18 @@
1
  // lib/screens/home_screen.dart
2
  import 'dart:async';
3
- import 'package:aitube2/config/config.dart';
4
- import 'package:aitube2/widgets/web_utils.dart';
5
  import 'package:flutter/foundation.dart';
6
  import 'package:flutter/material.dart';
7
  import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
8
- import 'package:aitube2/screens/video_screen.dart';
9
- import 'package:aitube2/screens/settings_screen.dart';
10
- import 'package:aitube2/models/video_result.dart';
11
- import 'package:aitube2/services/websocket_api_service.dart';
12
- import 'package:aitube2/services/settings_service.dart';
13
- import 'package:aitube2/widgets/video_card.dart';
14
- import 'package:aitube2/widgets/search_box.dart';
15
- import 'package:aitube2/theme/colors.dart';
16
 
17
  class HomeScreen extends StatefulWidget {
18
  final String? initialSearchQuery;
@@ -148,7 +148,7 @@ class _HomeScreenState extends State<HomeScreen> {
148
  title: const Text(
149
  'Connection Limit Reached',
150
  style: TextStyle(
151
- color: AiTubeColors.onBackground,
152
  fontSize: 20,
153
  fontWeight: FontWeight.bold,
154
  ),
@@ -161,12 +161,12 @@ class _HomeScreenState extends State<HomeScreen> {
161
  _websocketService.anonLimitMessage.isNotEmpty
162
  ? _websocketService.anonLimitMessage
163
  : 'Anonymous users can enjoy 1 stream per IP address. If you are on a shared IP please enter your HF token, thank you!',
164
- style: const TextStyle(color: AiTubeColors.onSurface),
165
  ),
166
  const SizedBox(height: 16),
167
  const Text(
168
  'Enter your HuggingFace API token to continue:',
169
- style: TextStyle(color: AiTubeColors.onSurface),
170
  ),
171
  const SizedBox(height: 8),
172
  TextField(
@@ -174,11 +174,11 @@ class _HomeScreenState extends State<HomeScreen> {
174
  obscureText: obscureText,
175
  decoration: InputDecoration(
176
  labelText: 'API Key',
177
- labelStyle: const TextStyle(color: AiTubeColors.onSurfaceVariant),
178
  suffixIcon: IconButton(
179
  icon: Icon(
180
  obscureText ? Icons.visibility : Icons.visibility_off,
181
- color: AiTubeColors.onSurfaceVariant,
182
  ),
183
  onPressed: () => setState(() => obscureText = !obscureText),
184
  ),
@@ -189,19 +189,19 @@ class _HomeScreenState extends State<HomeScreen> {
189
  ),
190
  ],
191
  ),
192
- backgroundColor: AiTubeColors.surface,
193
  actions: [
194
  TextButton(
195
  onPressed: () => Navigator.pop(dialogContext),
196
  child: const Text(
197
  'Cancel',
198
- style: TextStyle(color: AiTubeColors.onSurfaceVariant),
199
  ),
200
  ),
201
  FilledButton(
202
  onPressed: () => Navigator.pop(dialogContext, controller.text),
203
  style: FilledButton.styleFrom(
204
- backgroundColor: AiTubeColors.primary,
205
  ),
206
  child: const Text('Save'),
207
  ),
@@ -237,7 +237,7 @@ class _HomeScreenState extends State<HomeScreen> {
237
  title: const Text(
238
  'Too Many Connections',
239
  style: TextStyle(
240
- color: AiTubeColors.onBackground,
241
  fontSize: 20,
242
  fontWeight: FontWeight.bold,
243
  ),
@@ -248,16 +248,16 @@ class _HomeScreenState extends State<HomeScreen> {
248
  children: [
249
  Text(
250
  _websocketService.deviceLimitMessage,
251
- style: const TextStyle(color: AiTubeColors.onSurface),
252
  ),
253
  const SizedBox(height: 16),
254
  const Text(
255
- 'Please close some of your other browser tabs running AiTube to continue.',
256
- style: TextStyle(color: AiTubeColors.onSurface),
257
  ),
258
  ],
259
  ),
260
- backgroundColor: AiTubeColors.surface,
261
  actions: [
262
  FilledButton(
263
  onPressed: () {
@@ -271,7 +271,7 @@ class _HomeScreenState extends State<HomeScreen> {
271
  }
272
  },
273
  style: FilledButton.styleFrom(
274
- backgroundColor: AiTubeColors.primary,
275
  ),
276
  child: const Text('Try Again'),
277
  ),
@@ -411,7 +411,7 @@ class _HomeScreenState extends State<HomeScreen> {
411
  return Scaffold(
412
  appBar: AppBar(
413
  title: Text(Configuration.instance.uiProductName),
414
- backgroundColor: AiTubeColors.background,
415
  actions: [
416
  Padding(
417
  padding: const EdgeInsets.only(right: 8),
@@ -452,7 +452,7 @@ class _HomeScreenState extends State<HomeScreen> {
452
  ? 'Hallucinating search results using AI...'
453
  : 'Results are generated on demand, videos rendered on the fly.',
454
  style: const TextStyle(
455
- color: AiTubeColors.onSurfaceVariant,
456
  fontSize: 20
457
  ),
458
  textAlign: TextAlign.center,
 
1
  // lib/screens/home_screen.dart
2
  import 'dart:async';
3
+ import 'package:tikslop/config/config.dart';
4
+ import 'package:tikslop/widgets/web_utils.dart';
5
  import 'package:flutter/foundation.dart';
6
  import 'package:flutter/material.dart';
7
  import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
8
+ import 'package:tikslop/screens/video_screen.dart';
9
+ import 'package:tikslop/screens/settings_screen.dart';
10
+ import 'package:tikslop/models/video_result.dart';
11
+ import 'package:tikslop/services/websocket_api_service.dart';
12
+ import 'package:tikslop/services/settings_service.dart';
13
+ import 'package:tikslop/widgets/video_card.dart';
14
+ import 'package:tikslop/widgets/search_box.dart';
15
+ import 'package:tikslop/theme/colors.dart';
16
 
17
  class HomeScreen extends StatefulWidget {
18
  final String? initialSearchQuery;
 
148
  title: const Text(
149
  'Connection Limit Reached',
150
  style: TextStyle(
151
+ color: TikSlopColors.onBackground,
152
  fontSize: 20,
153
  fontWeight: FontWeight.bold,
154
  ),
 
161
  _websocketService.anonLimitMessage.isNotEmpty
162
  ? _websocketService.anonLimitMessage
163
  : 'Anonymous users can enjoy 1 stream per IP address. If you are on a shared IP please enter your HF token, thank you!',
164
+ style: const TextStyle(color: TikSlopColors.onSurface),
165
  ),
166
  const SizedBox(height: 16),
167
  const Text(
168
  'Enter your HuggingFace API token to continue:',
169
+ style: TextStyle(color: TikSlopColors.onSurface),
170
  ),
171
  const SizedBox(height: 8),
172
  TextField(
 
174
  obscureText: obscureText,
175
  decoration: InputDecoration(
176
  labelText: 'API Key',
177
+ labelStyle: const TextStyle(color: TikSlopColors.onSurfaceVariant),
178
  suffixIcon: IconButton(
179
  icon: Icon(
180
  obscureText ? Icons.visibility : Icons.visibility_off,
181
+ color: TikSlopColors.onSurfaceVariant,
182
  ),
183
  onPressed: () => setState(() => obscureText = !obscureText),
184
  ),
 
189
  ),
190
  ],
191
  ),
192
+ backgroundColor: TikSlopColors.surface,
193
  actions: [
194
  TextButton(
195
  onPressed: () => Navigator.pop(dialogContext),
196
  child: const Text(
197
  'Cancel',
198
+ style: TextStyle(color: TikSlopColors.onSurfaceVariant),
199
  ),
200
  ),
201
  FilledButton(
202
  onPressed: () => Navigator.pop(dialogContext, controller.text),
203
  style: FilledButton.styleFrom(
204
+ backgroundColor: TikSlopColors.primary,
205
  ),
206
  child: const Text('Save'),
207
  ),
 
237
  title: const Text(
238
  'Too Many Connections',
239
  style: TextStyle(
240
+ color: TikSlopColors.onBackground,
241
  fontSize: 20,
242
  fontWeight: FontWeight.bold,
243
  ),
 
248
  children: [
249
  Text(
250
  _websocketService.deviceLimitMessage,
251
+ style: const TextStyle(color: TikSlopColors.onSurface),
252
  ),
253
  const SizedBox(height: 16),
254
  const Text(
255
+ 'Please close some of your other browser tabs running TikSlop to continue.',
256
+ style: TextStyle(color: TikSlopColors.onSurface),
257
  ),
258
  ],
259
  ),
260
+ backgroundColor: TikSlopColors.surface,
261
  actions: [
262
  FilledButton(
263
  onPressed: () {
 
271
  }
272
  },
273
  style: FilledButton.styleFrom(
274
+ backgroundColor: TikSlopColors.primary,
275
  ),
276
  child: const Text('Try Again'),
277
  ),
 
411
  return Scaffold(
412
  appBar: AppBar(
413
  title: Text(Configuration.instance.uiProductName),
414
+ backgroundColor: TikSlopColors.background,
415
  actions: [
416
  Padding(
417
  padding: const EdgeInsets.only(right: 8),
 
452
  ? 'Hallucinating search results using AI...'
453
  : 'Results are generated on demand, videos rendered on the fly.',
454
  style: const TextStyle(
455
+ color: TikSlopColors.onSurfaceVariant,
456
  fontSize: 20
457
  ),
458
  textAlign: TextAlign.center,
lib/screens/settings_screen.dart CHANGED
@@ -51,7 +51,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
51
  const Text(
52
  'API Configuration',
53
  style: TextStyle(
54
- color: AiTubeColors.onBackground,
55
  fontSize: 20,
56
  fontWeight: FontWeight.bold,
57
  ),
@@ -127,7 +127,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
127
  const Text(
128
  'Video Generation',
129
  style: TextStyle(
130
- color: AiTubeColors.onBackground,
131
  fontSize: 20,
132
  fontWeight: FontWeight.bold,
133
  ),
@@ -171,7 +171,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
171
  const Text(
172
  'Custom Video Model',
173
  style: TextStyle(
174
- color: AiTubeColors.onBackground,
175
  fontSize: 20,
176
  fontWeight: FontWeight.bold,
177
  ),
@@ -192,7 +192,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
192
  ),
193
  const SizedBox(height: 8),
194
  const Text(
195
- 'Interested in using custom Hugging Face models? If you trained a public and distilled LoRA model based on LTX-Video 0.9.6 (remember, it has to be distilled), it can be integrated into AiTube2. Please open a thread in the Community forum and I\'ll see for a way to allow for custom models.',
196
  style: TextStyle(
197
  fontSize: 12,
198
  color: Colors.grey,
 
51
  const Text(
52
  'API Configuration',
53
  style: TextStyle(
54
+ color: TikSlopColors.onBackground,
55
  fontSize: 20,
56
  fontWeight: FontWeight.bold,
57
  ),
 
127
  const Text(
128
  'Video Generation',
129
  style: TextStyle(
130
+ color: TikSlopColors.onBackground,
131
  fontSize: 20,
132
  fontWeight: FontWeight.bold,
133
  ),
 
171
  const Text(
172
  'Custom Video Model',
173
  style: TextStyle(
174
+ color: TikSlopColors.onBackground,
175
  fontSize: 20,
176
  fontWeight: FontWeight.bold,
177
  ),
 
192
  ),
193
  const SizedBox(height: 8),
194
  const Text(
195
+ 'Interested in using custom Hugging Face models? If you trained a public and distilled LoRA model based on LTX-Video 0.9.6 (remember, it has to be distilled), it can be integrated into TikSlop. Please open a thread in the Community forum and I\'ll see for a way to allow for custom models.',
196
  style: TextStyle(
197
  fontSize: 12,
198
  color: Colors.grey,
lib/screens/video_screen.dart CHANGED
@@ -1,14 +1,14 @@
1
  // lib/screens/video_screen.dart
2
  import 'dart:async';
3
 
4
- import 'package:aitube2/screens/home_screen.dart';
5
- import 'package:aitube2/widgets/chat_widget.dart';
6
- import 'package:aitube2/widgets/search_box.dart';
7
- import 'package:aitube2/widgets/web_utils.dart';
8
  import 'package:flutter/foundation.dart';
9
  import 'package:flutter/material.dart';
10
  import 'package:flutter/services.dart';
11
- import 'package:universal_html/html.dart' if (dart.library.io) 'package:aitube2/services/html_stub.dart' as html;
12
  import '../config/config.dart';
13
  import '../models/video_result.dart';
14
  import '../services/websocket_api_service.dart';
@@ -114,7 +114,7 @@ class _VideoScreenState extends State<VideoScreen> {
114
  title: const Text(
115
  'Connection Limit Reached',
116
  style: TextStyle(
117
- color: AiTubeColors.onBackground,
118
  fontSize: 20,
119
  fontWeight: FontWeight.bold,
120
  ),
@@ -127,12 +127,12 @@ class _VideoScreenState extends State<VideoScreen> {
127
  _websocketService.anonLimitMessage.isNotEmpty
128
  ? _websocketService.anonLimitMessage
129
  : 'Anonymous users can enjoy 1 stream per IP address. If you are on a shared IP please enter your HF token, thank you!',
130
- style: const TextStyle(color: AiTubeColors.onSurface),
131
  ),
132
  const SizedBox(height: 16),
133
  const Text(
134
  'Enter your HuggingFace API token to continue:',
135
- style: TextStyle(color: AiTubeColors.onSurface),
136
  ),
137
  const SizedBox(height: 8),
138
  TextField(
@@ -140,11 +140,11 @@ class _VideoScreenState extends State<VideoScreen> {
140
  obscureText: obscureText,
141
  decoration: InputDecoration(
142
  labelText: 'API Key',
143
- labelStyle: const TextStyle(color: AiTubeColors.onSurfaceVariant),
144
  suffixIcon: IconButton(
145
  icon: Icon(
146
  obscureText ? Icons.visibility : Icons.visibility_off,
147
- color: AiTubeColors.onSurfaceVariant,
148
  ),
149
  onPressed: () => setState(() => obscureText = !obscureText),
150
  ),
@@ -155,19 +155,19 @@ class _VideoScreenState extends State<VideoScreen> {
155
  ),
156
  ],
157
  ),
158
- backgroundColor: AiTubeColors.surface,
159
  actions: [
160
  TextButton(
161
  onPressed: () => Navigator.pop(dialogContext),
162
  child: const Text(
163
  'Cancel',
164
- style: TextStyle(color: AiTubeColors.onSurfaceVariant),
165
  ),
166
  ),
167
  FilledButton(
168
  onPressed: () => Navigator.pop(dialogContext, controller.text),
169
  style: FilledButton.styleFrom(
170
- backgroundColor: AiTubeColors.primary,
171
  ),
172
  child: const Text('Save'),
173
  ),
@@ -203,7 +203,7 @@ class _VideoScreenState extends State<VideoScreen> {
203
  title: const Text(
204
  'Too Many Connections',
205
  style: TextStyle(
206
- color: AiTubeColors.onBackground,
207
  fontSize: 20,
208
  fontWeight: FontWeight.bold,
209
  ),
@@ -214,16 +214,16 @@ class _VideoScreenState extends State<VideoScreen> {
214
  children: [
215
  Text(
216
  _websocketService.deviceLimitMessage,
217
- style: const TextStyle(color: AiTubeColors.onSurface),
218
  ),
219
  const SizedBox(height: 16),
220
  const Text(
221
- 'Please close some of your other browser tabs running AiTube to continue.',
222
- style: TextStyle(color: AiTubeColors.onSurface),
223
  ),
224
  ],
225
  ),
226
- backgroundColor: AiTubeColors.surface,
227
  actions: [
228
  FilledButton(
229
  onPressed: () {
@@ -237,7 +237,7 @@ class _VideoScreenState extends State<VideoScreen> {
237
  }
238
  },
239
  style: FilledButton.styleFrom(
240
- backgroundColor: AiTubeColors.primary,
241
  ),
242
  child: const Text('Try Again'),
243
  ),
@@ -265,7 +265,7 @@ class _VideoScreenState extends State<VideoScreen> {
265
  void _shareVideo() async {
266
 
267
  // For non-web platforms
268
- final uri = Uri.parse("https://aitube.at");
269
  final params = Map<String, String>.from(uri.queryParameters);
270
 
271
  // Ensure title and description are in the URL parameters
@@ -279,7 +279,7 @@ class _VideoScreenState extends State<VideoScreen> {
279
 
280
  try {
281
  // this is a text to share on social media
282
- // final textToCopy = 'Messing around with #aitube2 👀 $shareUrl';
283
 
284
  // but for now let's just use the url
285
  final textToCopy = shareUrl;
@@ -372,8 +372,8 @@ class _VideoScreenState extends State<VideoScreen> {
372
  child: AppBar(
373
  leading: IconButton(
374
  icon: Navigator.canPop(context)
375
- ? const Icon(Icons.arrow_back, color: AiTubeColors.onBackground)
376
- : const Icon(Icons.home, color: AiTubeColors.onBackground),
377
  onPressed: () {
378
  // Restore the search parameter in URL when navigating back
379
  if (kIsWeb) {
@@ -505,21 +505,21 @@ class _VideoScreenState extends State<VideoScreen> {
505
  child: Text(
506
  _videoData.title,
507
  style: Theme.of(context).textTheme.headlineSmall?.copyWith(
508
- color: AiTubeColors.onBackground,
509
  fontWeight: FontWeight.bold,
510
  fontSize: 18
511
  ),
512
  ),
513
  ),
514
  IconButton(
515
- icon: const Icon(Icons.share, color: AiTubeColors.primary),
516
  onPressed: _shareVideo,
517
  tooltip: 'Share this creation',
518
  ),
519
  ],
520
  ),
521
- iconColor: AiTubeColors.primary,
522
- collapsedIconColor: AiTubeColors.primary,
523
  backgroundColor: Colors.transparent,
524
  collapsedBackgroundColor: Colors.transparent,
525
  children: [
@@ -531,7 +531,7 @@ class _VideoScreenState extends State<VideoScreen> {
531
  Text(
532
  _videoData.description,
533
  style: const TextStyle(
534
- color: AiTubeColors.onSurface,
535
  height: 1.5,
536
  ),
537
  ),
 
1
  // lib/screens/video_screen.dart
2
  import 'dart:async';
3
 
4
+ import 'package:tikslop/screens/home_screen.dart';
5
+ import 'package:tikslop/widgets/chat_widget.dart';
6
+ import 'package:tikslop/widgets/search_box.dart';
7
+ import 'package:tikslop/widgets/web_utils.dart';
8
  import 'package:flutter/foundation.dart';
9
  import 'package:flutter/material.dart';
10
  import 'package:flutter/services.dart';
11
+ import 'package:universal_html/html.dart' if (dart.library.io) 'package:tikslop/services/html_stub.dart' as html;
12
  import '../config/config.dart';
13
  import '../models/video_result.dart';
14
  import '../services/websocket_api_service.dart';
 
114
  title: const Text(
115
  'Connection Limit Reached',
116
  style: TextStyle(
117
+ color: TikSlopColors.onBackground,
118
  fontSize: 20,
119
  fontWeight: FontWeight.bold,
120
  ),
 
127
  _websocketService.anonLimitMessage.isNotEmpty
128
  ? _websocketService.anonLimitMessage
129
  : 'Anonymous users can enjoy 1 stream per IP address. If you are on a shared IP please enter your HF token, thank you!',
130
+ style: const TextStyle(color: TikSlopColors.onSurface),
131
  ),
132
  const SizedBox(height: 16),
133
  const Text(
134
  'Enter your HuggingFace API token to continue:',
135
+ style: TextStyle(color: TikSlopColors.onSurface),
136
  ),
137
  const SizedBox(height: 8),
138
  TextField(
 
140
  obscureText: obscureText,
141
  decoration: InputDecoration(
142
  labelText: 'API Key',
143
+ labelStyle: const TextStyle(color: TikSlopColors.onSurfaceVariant),
144
  suffixIcon: IconButton(
145
  icon: Icon(
146
  obscureText ? Icons.visibility : Icons.visibility_off,
147
+ color: TikSlopColors.onSurfaceVariant,
148
  ),
149
  onPressed: () => setState(() => obscureText = !obscureText),
150
  ),
 
155
  ),
156
  ],
157
  ),
158
+ backgroundColor: TikSlopColors.surface,
159
  actions: [
160
  TextButton(
161
  onPressed: () => Navigator.pop(dialogContext),
162
  child: const Text(
163
  'Cancel',
164
+ style: TextStyle(color: TikSlopColors.onSurfaceVariant),
165
  ),
166
  ),
167
  FilledButton(
168
  onPressed: () => Navigator.pop(dialogContext, controller.text),
169
  style: FilledButton.styleFrom(
170
+ backgroundColor: TikSlopColors.primary,
171
  ),
172
  child: const Text('Save'),
173
  ),
 
203
  title: const Text(
204
  'Too Many Connections',
205
  style: TextStyle(
206
+ color: TikSlopColors.onBackground,
207
  fontSize: 20,
208
  fontWeight: FontWeight.bold,
209
  ),
 
214
  children: [
215
  Text(
216
  _websocketService.deviceLimitMessage,
217
+ style: const TextStyle(color: TikSlopColors.onSurface),
218
  ),
219
  const SizedBox(height: 16),
220
  const Text(
221
+ 'Please close some of your other browser tabs running TikSlop to continue.',
222
+ style: TextStyle(color: TikSlopColors.onSurface),
223
  ),
224
  ],
225
  ),
226
+ backgroundColor: TikSlopColors.surface,
227
  actions: [
228
  FilledButton(
229
  onPressed: () {
 
237
  }
238
  },
239
  style: FilledButton.styleFrom(
240
+ backgroundColor: TikSlopColors.primary,
241
  ),
242
  child: const Text('Try Again'),
243
  ),
 
265
  void _shareVideo() async {
266
 
267
  // For non-web platforms
268
+ final uri = Uri.parse("https://tikslop.at");
269
  final params = Map<String, String>.from(uri.queryParameters);
270
 
271
  // Ensure title and description are in the URL parameters
 
279
 
280
  try {
281
  // this is a text to share on social media
282
+ // final textToCopy = 'Messing around with #tikslop 👀 $shareUrl';
283
 
284
  // but for now let's just use the url
285
  final textToCopy = shareUrl;
 
372
  child: AppBar(
373
  leading: IconButton(
374
  icon: Navigator.canPop(context)
375
+ ? const Icon(Icons.arrow_back, color: TikSlopColors.onBackground)
376
+ : const Icon(Icons.home, color: TikSlopColors.onBackground),
377
  onPressed: () {
378
  // Restore the search parameter in URL when navigating back
379
  if (kIsWeb) {
 
505
  child: Text(
506
  _videoData.title,
507
  style: Theme.of(context).textTheme.headlineSmall?.copyWith(
508
+ color: TikSlopColors.onBackground,
509
  fontWeight: FontWeight.bold,
510
  fontSize: 18
511
  ),
512
  ),
513
  ),
514
  IconButton(
515
+ icon: const Icon(Icons.share, color: TikSlopColors.primary),
516
  onPressed: _shareVideo,
517
  tooltip: 'Share this creation',
518
  ),
519
  ],
520
  ),
521
+ iconColor: TikSlopColors.primary,
522
+ collapsedIconColor: TikSlopColors.primary,
523
  backgroundColor: Colors.transparent,
524
  collapsedBackgroundColor: Colors.transparent,
525
  children: [
 
531
  Text(
532
  _videoData.description,
533
  style: const TextStyle(
534
+ color: TikSlopColors.onSurface,
535
  height: 1.5,
536
  ),
537
  ),
lib/services/chat_service.dart CHANGED
@@ -2,7 +2,7 @@
2
  // lib/services/chat_service.dart
3
  import 'dart:async';
4
  import 'dart:math';
5
- import 'package:aitube2/services/websocket_api_service.dart';
6
  import 'package:flutter/material.dart';
7
  import 'package:shared_preferences/shared_preferences.dart';
8
  import 'package:uuid/uuid.dart';
 
2
  // lib/services/chat_service.dart
3
  import 'dart:async';
4
  import 'dart:math';
5
+ import 'package:tikslop/services/websocket_api_service.dart';
6
  import 'package:flutter/material.dart';
7
  import 'package:shared_preferences/shared_preferences.dart';
8
  import 'package:uuid/uuid.dart';
lib/services/clip_queue/clip_generation_handler.dart CHANGED
@@ -2,7 +2,7 @@
2
 
3
  import 'dart:async';
4
  import 'package:flutter/foundation.dart';
5
- import 'package:aitube2/config/config.dart';
6
  import '../websocket_api_service.dart';
7
  import '../../models/video_result.dart';
8
  import 'clip_states.dart';
 
2
 
3
  import 'dart:async';
4
  import 'package:flutter/foundation.dart';
5
+ import 'package:tikslop/config/config.dart';
6
  import '../websocket_api_service.dart';
7
  import '../../models/video_result.dart';
8
  import 'clip_states.dart';
lib/services/clip_queue/clip_queue_manager.dart CHANGED
@@ -2,7 +2,7 @@
2
 
3
  import 'dart:async';
4
  import 'dart:math';
5
- import 'package:aitube2/config/config.dart';
6
  import 'package:flutter/foundation.dart';
7
  import 'package:collection/collection.dart';
8
  import '../../models/video_result.dart';
 
2
 
3
  import 'dart:async';
4
  import 'dart:math';
5
+ import 'package:tikslop/config/config.dart';
6
  import 'package:flutter/foundation.dart';
7
  import 'package:collection/collection.dart';
8
  import '../../models/video_result.dart';
lib/services/settings_service.dart CHANGED
@@ -1,7 +1,7 @@
1
  import 'dart:async';
2
 
3
  import 'package:shared_preferences/shared_preferences.dart';
4
- import 'package:aitube2/config/config.dart';
5
 
6
  class SettingsService {
7
  static const String _promptPrefixKey = 'video_prompt_prefix';
 
1
  import 'dart:async';
2
 
3
  import 'package:shared_preferences/shared_preferences.dart';
4
+ import 'package:tikslop/config/config.dart';
5
 
6
  class SettingsService {
7
  static const String _promptPrefixKey = 'video_prompt_prefix';
lib/services/websocket_api_service.dart CHANGED
@@ -2,13 +2,13 @@ import 'dart:async';
2
  import 'dart:io' as io;
3
  // For web platform, conditionally import http instead of HttpClient
4
  import 'package:http/http.dart' as http;
5
- import 'package:aitube2/services/settings_service.dart';
6
  import 'package:synchronized/synchronized.dart';
7
  import 'dart:convert';
8
  // Conditionally import html for web platform with proper handling
9
  import 'html_stub.dart' if (dart.library.html) 'dart:html' as html;
10
- import 'package:aitube2/config/config.dart';
11
- import 'package:aitube2/models/chat_message.dart';
12
  import 'package:flutter/foundation.dart';
13
  import 'package:uuid/uuid.dart';
14
  import 'package:web_socket_channel/web_socket_channel.dart';
@@ -82,8 +82,8 @@ class WebSocketApiService {
82
  const isProduction = bool.fromEnvironment('PRODUCTION_MODE', defaultValue: false);
83
 
84
  if (isProduction) {
85
- // Production default is aitube.at
86
- const productionUrl = 'wss://aitube.at/ws';
87
  debugPrint('WebSocketApiService: Using production WebSocket URL: $productionUrl');
88
  return productionUrl;
89
  } else {
@@ -219,7 +219,7 @@ class WebSocketApiService {
219
  String get anonLimitMessage => _anonLimitMessage;
220
 
221
  // Message to display when device limit is exceeded
222
- String _deviceLimitMessage = 'Too many connections from this device. Please close other tabs running AiTube.';
223
  String get deviceLimitMessage => _deviceLimitMessage;
224
 
225
  // Stream to notify listeners when anonymous limit status changes
@@ -231,8 +231,8 @@ class WebSocketApiService {
231
  Stream<bool> get deviceLimitStream => _deviceLimitController.stream;
232
 
233
  // Constants for device connection limits
234
- static const String _connectionCountKey = 'aitube_connection_count';
235
- static const String _connectionIdKey = 'aitube_connection_id';
236
  static const int _maxDeviceConnections = 3; // Maximum number of tabs/connections per device
237
  static const Duration _connectionHeartbeatInterval = Duration(seconds: 10);
238
  Timer? _connectionHeartbeatTimer;
 
2
  import 'dart:io' as io;
3
  // For web platform, conditionally import http instead of HttpClient
4
  import 'package:http/http.dart' as http;
5
+ import 'package:tikslop/services/settings_service.dart';
6
  import 'package:synchronized/synchronized.dart';
7
  import 'dart:convert';
8
  // Conditionally import html for web platform with proper handling
9
  import 'html_stub.dart' if (dart.library.html) 'dart:html' as html;
10
+ import 'package:tikslop/config/config.dart';
11
+ import 'package:tikslop/models/chat_message.dart';
12
  import 'package:flutter/foundation.dart';
13
  import 'package:uuid/uuid.dart';
14
  import 'package:web_socket_channel/web_socket_channel.dart';
 
82
  const isProduction = bool.fromEnvironment('PRODUCTION_MODE', defaultValue: false);
83
 
84
  if (isProduction) {
85
+ // Production default is tikslop.at
86
+ const productionUrl = 'wss://tikslop.at/ws';
87
  debugPrint('WebSocketApiService: Using production WebSocket URL: $productionUrl');
88
  return productionUrl;
89
  } else {
 
219
  String get anonLimitMessage => _anonLimitMessage;
220
 
221
  // Message to display when device limit is exceeded
222
+ String _deviceLimitMessage = 'Too many connections from this device. Please close other tabs running TikSlop.';
223
  String get deviceLimitMessage => _deviceLimitMessage;
224
 
225
  // Stream to notify listeners when anonymous limit status changes
 
231
  Stream<bool> get deviceLimitStream => _deviceLimitController.stream;
232
 
233
  // Constants for device connection limits
234
+ static const String _connectionCountKey = 'tikslop_connection_count';
235
+ static const String _connectionIdKey = 'tikslop_connection_id';
236
  static const int _maxDeviceConnections = 3; // Maximum number of tabs/connections per device
237
  static const Duration _connectionHeartbeatInterval = Duration(seconds: 10);
238
  Timer? _connectionHeartbeatTimer;
lib/theme/colors.dart CHANGED
@@ -1,7 +1,7 @@
1
  // lib/theme/Colors.dart
2
  import 'package:flutter/material.dart';
3
 
4
- class AiTubeColors {
5
  static const transparent = Color(0x00000000);
6
  static const background = Color(0xFF171717);
7
  static const surface = Color(0xFF272727);
 
1
  // lib/theme/Colors.dart
2
  import 'package:flutter/material.dart';
3
 
4
+ class TikSlopColors {
5
  static const transparent = Color(0x00000000);
6
  static const background = Color(0xFF171717);
7
  static const surface = Color(0xFF272727);
lib/widgets/api_key_dialog.dart CHANGED
@@ -19,7 +19,7 @@ class _ApiKeyDialogState extends State<ApiKeyDialog> {
19
  title: const Text(
20
  'Enter HuggingFace API Key',
21
  style: TextStyle(
22
- color: AiTubeColors.onBackground,
23
  fontSize: 20,
24
  fontWeight: FontWeight.bold,
25
  ),
@@ -29,29 +29,29 @@ class _ApiKeyDialogState extends State<ApiKeyDialog> {
29
  obscureText: _obscureText,
30
  decoration: InputDecoration(
31
  labelText: 'API Key',
32
- labelStyle: const TextStyle(color: AiTubeColors.onSurfaceVariant),
33
  suffixIcon: IconButton(
34
  icon: Icon(
35
  _obscureText ? Icons.visibility : Icons.visibility_off,
36
- color: AiTubeColors.onSurfaceVariant,
37
  ),
38
  onPressed: () => setState(() => _obscureText = !_obscureText),
39
  ),
40
  ),
41
  ),
42
- backgroundColor: AiTubeColors.surface,
43
  actions: [
44
  TextButton(
45
  onPressed: () => Navigator.pop(context),
46
  child: const Text(
47
  'Cancel',
48
- style: TextStyle(color: AiTubeColors.onSurfaceVariant),
49
  ),
50
  ),
51
  FilledButton(
52
  onPressed: () => Navigator.pop(context, _controller.text),
53
  style: FilledButton.styleFrom(
54
- backgroundColor: AiTubeColors.primary,
55
  ),
56
  child: const Text('Save'),
57
  ),
 
19
  title: const Text(
20
  'Enter HuggingFace API Key',
21
  style: TextStyle(
22
+ color: TikSlopColors.onBackground,
23
  fontSize: 20,
24
  fontWeight: FontWeight.bold,
25
  ),
 
29
  obscureText: _obscureText,
30
  decoration: InputDecoration(
31
  labelText: 'API Key',
32
+ labelStyle: const TextStyle(color: TikSlopColors.onSurfaceVariant),
33
  suffixIcon: IconButton(
34
  icon: Icon(
35
  _obscureText ? Icons.visibility : Icons.visibility_off,
36
+ color: TikSlopColors.onSurfaceVariant,
37
  ),
38
  onPressed: () => setState(() => _obscureText = !_obscureText),
39
  ),
40
  ),
41
  ),
42
+ backgroundColor: TikSlopColors.surface,
43
  actions: [
44
  TextButton(
45
  onPressed: () => Navigator.pop(context),
46
  child: const Text(
47
  'Cancel',
48
+ style: TextStyle(color: TikSlopColors.onSurfaceVariant),
49
  ),
50
  ),
51
  FilledButton(
52
  onPressed: () => Navigator.pop(context, _controller.text),
53
  style: FilledButton.styleFrom(
54
+ backgroundColor: TikSlopColors.primary,
55
  ),
56
  child: const Text('Save'),
57
  ),
lib/widgets/chat_widget.dart CHANGED
@@ -156,7 +156,7 @@ class _ChatWidgetState extends State<ChatWidget> {
156
  child: Text(
157
  'No messages yet',
158
  style: TextStyle(
159
- color: AiTubeColors.onSurfaceVariant,
160
  fontSize: 14,
161
  ),
162
  ),
@@ -204,7 +204,7 @@ class _ChatWidgetState extends State<ChatWidget> {
204
  Text(
205
  message.username,
206
  style: const TextStyle(
207
- color: AiTubeColors.onBackground,
208
  fontWeight: FontWeight.bold,
209
  ),
210
  ),
@@ -212,7 +212,7 @@ class _ChatWidgetState extends State<ChatWidget> {
212
  Text(
213
  _formatTime(message.timestamp),
214
  style: const TextStyle(
215
- color: AiTubeColors.onSurfaceVariant,
216
  fontSize: 12,
217
  ),
218
  ),
@@ -221,7 +221,7 @@ class _ChatWidgetState extends State<ChatWidget> {
221
  const SizedBox(height: 4),
222
  Text(
223
  message.content,
224
- style: const TextStyle(color: AiTubeColors.onSurface),
225
  ),
226
  ],
227
  ),
@@ -235,10 +235,10 @@ class _ChatWidgetState extends State<ChatWidget> {
235
  return Container(
236
  padding: const EdgeInsets.all(8),
237
  decoration: const BoxDecoration(
238
- color: AiTubeColors.transparent,
239
  border: Border(
240
  top: BorderSide(
241
- color: AiTubeColors.surfaceVariant,
242
  width: 1,
243
  ),
244
  ),
@@ -248,7 +248,7 @@ class _ChatWidgetState extends State<ChatWidget> {
248
  Expanded(
249
  child: TextField(
250
  controller: _messageController,
251
- style: const TextStyle(color: AiTubeColors.onSurface),
252
  maxLength: 255,
253
  maxLines: 1,
254
  onChanged: (value) {
@@ -261,8 +261,8 @@ class _ChatWidgetState extends State<ChatWidget> {
261
  }
262
  },
263
  decoration: InputDecoration(
264
- hintText: 'Chat with this aituber..',
265
- hintStyle: const TextStyle(color: AiTubeColors.onSurfaceVariant, fontSize: 16),
266
  border: OutlineInputBorder(
267
  borderRadius: BorderRadius.circular(12),
268
  borderSide: const BorderSide(
@@ -280,7 +280,7 @@ class _ChatWidgetState extends State<ChatWidget> {
280
  focusedBorder: OutlineInputBorder(
281
  borderRadius: BorderRadius.circular(12),
282
  borderSide: const BorderSide(
283
- color: AiTubeColors.primary,
284
  width: 1,
285
  ),
286
  ),
@@ -303,7 +303,7 @@ class _ChatWidgetState extends State<ChatWidget> {
303
  child: CircularProgressIndicator(strokeWidth: 2),
304
  )
305
  : const Icon(Icons.reply),
306
- color: AiTubeColors.primary,
307
  onPressed: _isSending ? null : _sendMessage,
308
  ),
309
  ],
@@ -381,7 +381,7 @@ class _ChatWidgetState extends State<ChatWidget> {
381
  child: Column(
382
  mainAxisSize: MainAxisSize.min,
383
  children: [
384
- Text(_error!, style: const TextStyle(color: AiTubeColors.onBackground)),
385
  const SizedBox(height: 8),
386
  ElevatedButton(
387
  onPressed: () {
@@ -401,10 +401,10 @@ class _ChatWidgetState extends State<ChatWidget> {
401
  return Container(
402
  width: widget.isCompact ? double.infinity : 320,
403
  decoration: BoxDecoration(
404
- color: AiTubeColors.surface,
405
  borderRadius: BorderRadius.circular(12),
406
  border: Border.all(
407
- color: AiTubeColors.surfaceVariant,
408
  width: 1,
409
  ),
410
  ),
@@ -414,12 +414,12 @@ class _ChatWidgetState extends State<ChatWidget> {
414
  padding: EdgeInsets.all(16),
415
  child: Row(
416
  children: [
417
- Icon(Icons.chat, color: AiTubeColors.onBackground),
418
  SizedBox(width: 8),
419
  Text(
420
  'Simulation log',
421
  style: TextStyle(
422
- color: AiTubeColors.onBackground,
423
  fontSize: 16,
424
  fontWeight: FontWeight.bold,
425
  ),
 
156
  child: Text(
157
  'No messages yet',
158
  style: TextStyle(
159
+ color: TikSlopColors.onSurfaceVariant,
160
  fontSize: 14,
161
  ),
162
  ),
 
204
  Text(
205
  message.username,
206
  style: const TextStyle(
207
+ color: TikSlopColors.onBackground,
208
  fontWeight: FontWeight.bold,
209
  ),
210
  ),
 
212
  Text(
213
  _formatTime(message.timestamp),
214
  style: const TextStyle(
215
+ color: TikSlopColors.onSurfaceVariant,
216
  fontSize: 12,
217
  ),
218
  ),
 
221
  const SizedBox(height: 4),
222
  Text(
223
  message.content,
224
+ style: const TextStyle(color: TikSlopColors.onSurface),
225
  ),
226
  ],
227
  ),
 
235
  return Container(
236
  padding: const EdgeInsets.all(8),
237
  decoration: const BoxDecoration(
238
+ color: TikSlopColors.transparent,
239
  border: Border(
240
  top: BorderSide(
241
+ color: TikSlopColors.surfaceVariant,
242
  width: 1,
243
  ),
244
  ),
 
248
  Expanded(
249
  child: TextField(
250
  controller: _messageController,
251
+ style: const TextStyle(color: TikSlopColors.onSurface),
252
  maxLength: 255,
253
  maxLines: 1,
254
  onChanged: (value) {
 
261
  }
262
  },
263
  decoration: InputDecoration(
264
+ hintText: 'Chat with this tikslopr..',
265
+ hintStyle: const TextStyle(color: TikSlopColors.onSurfaceVariant, fontSize: 16),
266
  border: OutlineInputBorder(
267
  borderRadius: BorderRadius.circular(12),
268
  borderSide: const BorderSide(
 
280
  focusedBorder: OutlineInputBorder(
281
  borderRadius: BorderRadius.circular(12),
282
  borderSide: const BorderSide(
283
+ color: TikSlopColors.primary,
284
  width: 1,
285
  ),
286
  ),
 
303
  child: CircularProgressIndicator(strokeWidth: 2),
304
  )
305
  : const Icon(Icons.reply),
306
+ color: TikSlopColors.primary,
307
  onPressed: _isSending ? null : _sendMessage,
308
  ),
309
  ],
 
381
  child: Column(
382
  mainAxisSize: MainAxisSize.min,
383
  children: [
384
+ Text(_error!, style: const TextStyle(color: TikSlopColors.onBackground)),
385
  const SizedBox(height: 8),
386
  ElevatedButton(
387
  onPressed: () {
 
401
  return Container(
402
  width: widget.isCompact ? double.infinity : 320,
403
  decoration: BoxDecoration(
404
+ color: TikSlopColors.surface,
405
  borderRadius: BorderRadius.circular(12),
406
  border: Border.all(
407
+ color: TikSlopColors.surfaceVariant,
408
  width: 1,
409
  ),
410
  ),
 
414
  padding: EdgeInsets.all(16),
415
  child: Row(
416
  children: [
417
+ Icon(Icons.chat, color: TikSlopColors.onBackground),
418
  SizedBox(width: 8),
419
  Text(
420
  'Simulation log',
421
  style: TextStyle(
422
+ color: TikSlopColors.onBackground,
423
  fontSize: 16,
424
  fontWeight: FontWeight.bold,
425
  ),
lib/widgets/maintenance_screen.dart CHANGED
@@ -1,6 +1,6 @@
1
  // lib/widgets/maintenance_screen.dart
2
  import 'package:flutter/material.dart';
3
- import 'package:aitube2/theme/colors.dart';
4
 
5
  class MaintenanceScreen extends StatelessWidget {
6
  final Exception? error;
@@ -25,7 +25,7 @@ class MaintenanceScreen extends StatelessWidget {
25
  ),
26
  const SizedBox(height: 24),
27
  const Text(
28
- '#aitube2 is currently in maintenance',
29
  textAlign: TextAlign.center,
30
  style: TextStyle(
31
  color: Colors.grey,
 
1
  // lib/widgets/maintenance_screen.dart
2
  import 'package:flutter/material.dart';
3
+ import 'package:tikslop/theme/colors.dart';
4
 
5
  class MaintenanceScreen extends StatelessWidget {
6
  final Exception? error;
 
25
  ),
26
  const SizedBox(height: 24),
27
  const Text(
28
+ '#tikslop is currently in maintenance',
29
  textAlign: TextAlign.center,
30
  style: TextStyle(
31
  color: Colors.grey,
lib/widgets/search_box.dart CHANGED
@@ -59,7 +59,7 @@ class _SearchBoxState extends State<SearchBox> {
59
  child: TextFormField(
60
  controller: widget.controller,
61
  focusNode: _focusNode,
62
- style: const TextStyle(color: AiTubeColors.onBackground),
63
  enabled: widget.enabled,
64
  textInputAction: TextInputAction.search,
65
  onFieldSubmitted: _handleSubmitted,
@@ -68,9 +68,9 @@ class _SearchBoxState extends State<SearchBox> {
68
  },
69
  decoration: InputDecoration(
70
  hintText: 'Explore the interdimensional TV! eg. "Elephants on Mars"',
71
- hintStyle: const TextStyle(color: AiTubeColors.onSurfaceVariant),
72
  filled: true,
73
- fillColor: AiTubeColors.surface,
74
  border: OutlineInputBorder(
75
  borderRadius: BorderRadius.circular(24),
76
  borderSide: BorderSide.none,
@@ -91,7 +91,7 @@ class _SearchBoxState extends State<SearchBox> {
91
  : IconButton(
92
  icon: const Icon(
93
  Icons.search,
94
- color: AiTubeColors.onSurfaceVariant,
95
  ),
96
  onPressed: () => _handleSubmitted(widget.controller.text),
97
  ),
 
59
  child: TextFormField(
60
  controller: widget.controller,
61
  focusNode: _focusNode,
62
+ style: const TextStyle(color: TikSlopColors.onBackground),
63
  enabled: widget.enabled,
64
  textInputAction: TextInputAction.search,
65
  onFieldSubmitted: _handleSubmitted,
 
68
  },
69
  decoration: InputDecoration(
70
  hintText: 'Explore the interdimensional TV! eg. "Elephants on Mars"',
71
+ hintStyle: const TextStyle(color: TikSlopColors.onSurfaceVariant),
72
  filled: true,
73
+ fillColor: TikSlopColors.surface,
74
  border: OutlineInputBorder(
75
  borderRadius: BorderRadius.circular(24),
76
  borderSide: BorderSide.none,
 
91
  : IconButton(
92
  icon: const Icon(
93
  Icons.search,
94
+ color: TikSlopColors.onSurfaceVariant,
95
  ),
96
  onPressed: () => _handleSubmitted(widget.controller.text),
97
  ),
lib/widgets/video_card.dart CHANGED
@@ -15,21 +15,21 @@ class VideoCard extends StatelessWidget {
15
  Widget _buildThumbnail() {
16
  if (video.thumbnailUrl.isEmpty) {
17
  return Container(
18
- color: AiTubeColors.surfaceVariant,
19
  child: const Center(
20
  child: Column(
21
  mainAxisAlignment: MainAxisAlignment.center,
22
  children: [
23
  Icon(
24
  Icons.movie_creation,
25
- color: AiTubeColors.onSurfaceVariant,
26
  size: 32,
27
  ),
28
  SizedBox(height: 8),
29
  Text(
30
  '(TODO: thumbnails)',
31
  style: TextStyle(
32
- color: AiTubeColors.onSurfaceVariant,
33
  fontSize: 12,
34
  ),
35
  ),
@@ -92,21 +92,21 @@ class VideoCard extends StatelessWidget {
92
 
93
  Widget _buildErrorThumbnail() {
94
  return Container(
95
- color: AiTubeColors.surfaceVariant,
96
  child: const Center(
97
  child: Column(
98
  mainAxisAlignment: MainAxisAlignment.center,
99
  children: [
100
  Icon(
101
  Icons.broken_image,
102
- color: AiTubeColors.onSurfaceVariant,
103
  size: 32,
104
  ),
105
  SizedBox(height: 8),
106
  Text(
107
  'Preview unavailable',
108
  style: TextStyle(
109
- color: AiTubeColors.onSurfaceVariant,
110
  fontSize: 12,
111
  ),
112
  ),
@@ -151,7 +151,7 @@ class VideoCard extends StatelessWidget {
151
  Text(
152
  'LTX Video',
153
  style: TextStyle(
154
- color: AiTubeColors.onBackground,
155
  fontSize: 12,
156
  ),
157
  ),
@@ -165,16 +165,16 @@ class VideoCard extends StatelessWidget {
165
  ),
166
  Container(
167
  padding: const EdgeInsets.all(12),
168
- color: AiTubeColors.surface,
169
  child: Row(
170
  crossAxisAlignment: CrossAxisAlignment.start,
171
  children: [
172
  const CircleAvatar(
173
  radius: 16,
174
- backgroundColor: AiTubeColors.surfaceVariant,
175
  child: Icon(
176
  Icons.play_arrow,
177
- color: AiTubeColors.onSurfaceVariant,
178
  size: 20,
179
  ),
180
  ),
@@ -187,7 +187,7 @@ class VideoCard extends StatelessWidget {
187
  Text(
188
  video.title,
189
  style: const TextStyle(
190
- color: AiTubeColors.onBackground,
191
  fontWeight: FontWeight.w500,
192
  fontSize: 14,
193
  ),
@@ -200,7 +200,7 @@ class VideoCard extends StatelessWidget {
200
  child: Text(
201
  video.description,
202
  style: const TextStyle(
203
- color: AiTubeColors.onSurfaceVariant,
204
  fontSize: 12,
205
  ),
206
  maxLines: 3,
 
15
  Widget _buildThumbnail() {
16
  if (video.thumbnailUrl.isEmpty) {
17
  return Container(
18
+ color: TikSlopColors.surfaceVariant,
19
  child: const Center(
20
  child: Column(
21
  mainAxisAlignment: MainAxisAlignment.center,
22
  children: [
23
  Icon(
24
  Icons.movie_creation,
25
+ color: TikSlopColors.onSurfaceVariant,
26
  size: 32,
27
  ),
28
  SizedBox(height: 8),
29
  Text(
30
  '(TODO: thumbnails)',
31
  style: TextStyle(
32
+ color: TikSlopColors.onSurfaceVariant,
33
  fontSize: 12,
34
  ),
35
  ),
 
92
 
93
  Widget _buildErrorThumbnail() {
94
  return Container(
95
+ color: TikSlopColors.surfaceVariant,
96
  child: const Center(
97
  child: Column(
98
  mainAxisAlignment: MainAxisAlignment.center,
99
  children: [
100
  Icon(
101
  Icons.broken_image,
102
+ color: TikSlopColors.onSurfaceVariant,
103
  size: 32,
104
  ),
105
  SizedBox(height: 8),
106
  Text(
107
  'Preview unavailable',
108
  style: TextStyle(
109
+ color: TikSlopColors.onSurfaceVariant,
110
  fontSize: 12,
111
  ),
112
  ),
 
151
  Text(
152
  'LTX Video',
153
  style: TextStyle(
154
+ color: TikSlopColors.onBackground,
155
  fontSize: 12,
156
  ),
157
  ),
 
165
  ),
166
  Container(
167
  padding: const EdgeInsets.all(12),
168
+ color: TikSlopColors.surface,
169
  child: Row(
170
  crossAxisAlignment: CrossAxisAlignment.start,
171
  children: [
172
  const CircleAvatar(
173
  radius: 16,
174
+ backgroundColor: TikSlopColors.surfaceVariant,
175
  child: Icon(
176
  Icons.play_arrow,
177
+ color: TikSlopColors.onSurfaceVariant,
178
  size: 20,
179
  ),
180
  ),
 
187
  Text(
188
  video.title,
189
  style: const TextStyle(
190
+ color: TikSlopColors.onBackground,
191
  fontWeight: FontWeight.w500,
192
  fontSize: 14,
193
  ),
 
200
  child: Text(
201
  video.description,
202
  style: const TextStyle(
203
+ color: TikSlopColors.onSurfaceVariant,
204
  fontSize: 12,
205
  ),
206
  maxLines: 3,
lib/widgets/video_player/buffer_manager.dart CHANGED
@@ -2,12 +2,12 @@
2
 
3
  import 'dart:async';
4
  import 'package:flutter/foundation.dart';
5
- import 'package:aitube2/config/config.dart';
6
- import 'package:aitube2/services/clip_queue/video_clip.dart';
7
- import 'package:aitube2/services/clip_queue/clip_queue_manager.dart';
8
  import 'package:video_player/video_player.dart';
9
- import 'package:aitube2/models/video_result.dart';
10
- import 'package:aitube2/models/video_orientation.dart';
11
 
12
  /// Manages buffering and clip preloading for video player
13
  class BufferManager {
 
2
 
3
  import 'dart:async';
4
  import 'package:flutter/foundation.dart';
5
+ import 'package:tikslop/config/config.dart';
6
+ import 'package:tikslop/services/clip_queue/video_clip.dart';
7
+ import 'package:tikslop/services/clip_queue/clip_queue_manager.dart';
8
  import 'package:video_player/video_player.dart';
9
+ import 'package:tikslop/models/video_result.dart';
10
+ import 'package:tikslop/models/video_orientation.dart';
11
 
12
  /// Manages buffering and clip preloading for video player
13
  class BufferManager {
lib/widgets/video_player/nano_clip_manager.dart CHANGED
@@ -3,11 +3,11 @@
3
  import 'dart:async';
4
  import 'dart:convert';
5
  import 'package:flutter/foundation.dart';
6
- import 'package:aitube2/models/video_result.dart';
7
- import 'package:aitube2/services/clip_queue/video_clip.dart';
8
- import 'package:aitube2/services/clip_queue/clip_states.dart';
9
- import 'package:aitube2/services/websocket_api_service.dart';
10
- import 'package:aitube2/utils/seed.dart';
11
  import 'package:uuid/uuid.dart';
12
 
13
  /// Manages a single video clip generation for thumbnail playback
 
3
  import 'dart:async';
4
  import 'dart:convert';
5
  import 'package:flutter/foundation.dart';
6
+ import 'package:tikslop/models/video_result.dart';
7
+ import 'package:tikslop/services/clip_queue/video_clip.dart';
8
+ import 'package:tikslop/services/clip_queue/clip_states.dart';
9
+ import 'package:tikslop/services/websocket_api_service.dart';
10
+ import 'package:tikslop/utils/seed.dart';
11
  import 'package:uuid/uuid.dart';
12
 
13
  /// Manages a single video clip generation for thumbnail playback
lib/widgets/video_player/nano_video_player.dart CHANGED
@@ -4,11 +4,11 @@ import 'dart:async';
4
  import 'package:flutter/material.dart';
5
  import 'package:flutter/foundation.dart' show kIsWeb;
6
  import 'package:video_player/video_player.dart';
7
- import 'package:aitube2/models/video_result.dart';
8
- import 'package:aitube2/theme/colors.dart';
9
- import 'package:aitube2/widgets/video_player/nano_clip_manager.dart';
10
- import 'package:aitube2/widgets/video_player/lifecycle_manager.dart';
11
- import 'package:aitube2/widgets/ai_content_disclaimer.dart';
12
 
13
  // Conditionally import dart:html for web platform
14
  import '../web_utils.dart' if (dart.library.html) 'dart:html' as html;
@@ -247,7 +247,7 @@ class _NanoVideoPlayerState extends State<NanoVideoPlayer> with WidgetsBindingOb
247
  children: [
248
  // Base layer: Video or placeholder
249
  Container(
250
- color: AiTubeColors.surfaceVariant,
251
  child: _controller?.value.isInitialized == true
252
  ? AspectRatio(
253
  aspectRatio: _controller!.value.aspectRatio,
 
4
  import 'package:flutter/material.dart';
5
  import 'package:flutter/foundation.dart' show kIsWeb;
6
  import 'package:video_player/video_player.dart';
7
+ import 'package:tikslop/models/video_result.dart';
8
+ import 'package:tikslop/theme/colors.dart';
9
+ import 'package:tikslop/widgets/video_player/nano_clip_manager.dart';
10
+ import 'package:tikslop/widgets/video_player/lifecycle_manager.dart';
11
+ import 'package:tikslop/widgets/ai_content_disclaimer.dart';
12
 
13
  // Conditionally import dart:html for web platform
14
  import '../web_utils.dart' if (dart.library.html) 'dart:html' as html;
 
247
  children: [
248
  // Base layer: Video or placeholder
249
  Container(
250
+ color: TikSlopColors.surfaceVariant,
251
  child: _controller?.value.isInitialized == true
252
  ? AspectRatio(
253
  aspectRatio: _controller!.value.aspectRatio,
lib/widgets/video_player/playback_controller.dart CHANGED
@@ -4,8 +4,8 @@ import 'dart:async';
4
  import 'package:flutter/foundation.dart';
5
  import 'package:flutter/material.dart';
6
  import 'package:video_player/video_player.dart';
7
- import 'package:aitube2/config/config.dart';
8
- import 'package:aitube2/services/clip_queue/video_clip.dart';
9
 
10
  /// Manages video playback logic for the video player
11
  class PlaybackController {
 
4
  import 'package:flutter/foundation.dart';
5
  import 'package:flutter/material.dart';
6
  import 'package:video_player/video_player.dart';
7
+ import 'package:tikslop/config/config.dart';
8
+ import 'package:tikslop/services/clip_queue/video_clip.dart';
9
 
10
  /// Manages video playback logic for the video player
11
  class PlaybackController {
lib/widgets/video_player/ui_components.dart CHANGED
@@ -1,9 +1,9 @@
1
  // lib/widgets/video_player/ui_components.dart
2
 
3
  import 'package:flutter/material.dart';
4
- import 'package:aitube2/theme/colors.dart';
5
- import 'package:aitube2/widgets/ai_content_disclaimer.dart';
6
- import 'package:aitube2/config/config.dart';
7
 
8
  /// Builds a placeholder widget for when video is not loaded
9
  Widget buildPlaceholder(String? initialThumbnailUrl) {
@@ -45,7 +45,7 @@ Widget buildErrorPlaceholder() {
45
  child: Icon(
46
  Icons.broken_image,
47
  size: 64,
48
- color: AiTubeColors.onSurfaceVariant,
49
  ),
50
  );
51
  }
 
1
  // lib/widgets/video_player/ui_components.dart
2
 
3
  import 'package:flutter/material.dart';
4
+ import 'package:tikslop/theme/colors.dart';
5
+ import 'package:tikslop/widgets/ai_content_disclaimer.dart';
6
+ import 'package:tikslop/config/config.dart';
7
 
8
  /// Builds a placeholder widget for when video is not loaded
9
  Widget buildPlaceholder(String? initialThumbnailUrl) {
 
45
  child: Icon(
46
  Icons.broken_image,
47
  size: 64,
48
+ color: TikSlopColors.onSurfaceVariant,
49
  ),
50
  );
51
  }
lib/widgets/video_player/video_player_widget.dart CHANGED
@@ -3,14 +3,14 @@
3
  import 'dart:async';
4
  import 'dart:math' as math;
5
  import 'dart:io' show Platform;
6
- import 'package:aitube2/config/config.dart';
7
  import 'package:flutter/material.dart';
8
  import 'package:flutter/foundation.dart' show kDebugMode, kIsWeb;
9
  import 'package:flutter/foundation.dart';
10
  import 'package:video_player/video_player.dart';
11
- import 'package:aitube2/models/video_result.dart';
12
- import 'package:aitube2/models/video_orientation.dart';
13
- import 'package:aitube2/theme/colors.dart';
14
 
15
  // Import components
16
  import 'playback_controller.dart';
@@ -557,7 +557,7 @@ class _VideoPlayerWidgetState extends State<VideoPlayerWidget> with WidgetsBindi
557
  ClipRRect(
558
  borderRadius: BorderRadius.circular(widget.borderRadius),
559
  child: Container(
560
- color: AiTubeColors.surfaceVariant,
561
  child: controller?.value.isInitialized ?? false
562
  ? VideoPlayer(controller!)
563
  : ui.buildPlaceholder(widget.initialThumbnailUrl),
 
3
  import 'dart:async';
4
  import 'dart:math' as math;
5
  import 'dart:io' show Platform;
6
+ import 'package:tikslop/config/config.dart';
7
  import 'package:flutter/material.dart';
8
  import 'package:flutter/foundation.dart' show kDebugMode, kIsWeb;
9
  import 'package:flutter/foundation.dart';
10
  import 'package:video_player/video_player.dart';
11
+ import 'package:tikslop/models/video_result.dart';
12
+ import 'package:tikslop/models/video_orientation.dart';
13
+ import 'package:tikslop/theme/colors.dart';
14
 
15
  // Import components
16
  import 'playback_controller.dart';
 
557
  ClipRRect(
558
  borderRadius: BorderRadius.circular(widget.borderRadius),
559
  child: Container(
560
+ color: TikSlopColors.surfaceVariant,
561
  child: controller?.value.isInitialized ?? false
562
  ? VideoPlayer(controller!)
563
  : ui.buildPlaceholder(widget.initialThumbnailUrl),
lib/widgets/web_utils.dart CHANGED
@@ -2,7 +2,7 @@ import 'dart:async';
2
  import 'package:flutter/foundation.dart';
3
 
4
  // Platform-specific imports handling
5
- import 'package:universal_html/html.dart' if (dart.library.io) 'package:aitube2/services/html_stub.dart' as html;
6
 
7
  /// Get URL parameters from the current URL (web only)
8
  Map<String, String> getUrlParameters() {
 
2
  import 'package:flutter/foundation.dart';
3
 
4
  // Platform-specific imports handling
5
+ import 'package:universal_html/html.dart' if (dart.library.io) 'package:tikslop/services/html_stub.dart' as html;
6
 
7
  /// Get URL parameters from the current URL (web only)
8
  Map<String, String> getUrlParameters() {
linux/CMakeLists.txt CHANGED
@@ -4,10 +4,10 @@ project(runner LANGUAGES CXX)
4
 
5
  # The name of the executable created for the application. Change this to change
6
  # the on-disk name of your application.
7
- set(BINARY_NAME "aitube2")
8
  # The unique GTK application identifier for this application. See:
9
  # https://wiki.gnome.org/HowDoI/ChooseApplicationID
10
- set(APPLICATION_ID "com.example.aitube2")
11
 
12
  # Explicitly opt in to modern CMake behaviors to avoid warnings with recent
13
  # versions of CMake.
 
4
 
5
  # The name of the executable created for the application. Change this to change
6
  # the on-disk name of your application.
7
+ set(BINARY_NAME "tikslop")
8
  # The unique GTK application identifier for this application. See:
9
  # https://wiki.gnome.org/HowDoI/ChooseApplicationID
10
+ set(APPLICATION_ID "com.example.tikslop")
11
 
12
  # Explicitly opt in to modern CMake behaviors to avoid warnings with recent
13
  # versions of CMake.
linux/my_application.cc CHANGED
@@ -40,11 +40,11 @@ static void my_application_activate(GApplication* application) {
40
  if (use_header_bar) {
41
  GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
42
  gtk_widget_show(GTK_WIDGET(header_bar));
43
- gtk_header_bar_set_title(header_bar, "aitube2");
44
  gtk_header_bar_set_show_close_button(header_bar, TRUE);
45
  gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
46
  } else {
47
- gtk_window_set_title(window, "aitube2");
48
  }
49
 
50
  gtk_window_set_default_size(window, 1280, 720);
 
40
  if (use_header_bar) {
41
  GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
42
  gtk_widget_show(GTK_WIDGET(header_bar));
43
+ gtk_header_bar_set_title(header_bar, "tikslop");
44
  gtk_header_bar_set_show_close_button(header_bar, TRUE);
45
  gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
46
  } else {
47
+ gtk_window_set_title(window, "tikslop");
48
  }
49
 
50
  gtk_window_set_default_size(window, 1280, 720);