jbilcke-hf HF Staff commited on
Commit
aa0155d
·
1 Parent(s): 2f88b0d

fix for the flutter build cache invalidation issue

Browse files
build.sh ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ # Script to build Flutter web app with cache busting
3
+
4
+ echo "🔨 Building Flutter web app..."
5
+ flutter build web --release
6
+
7
+ # for debugging, use:
8
+ #flutter build web --profile
9
+
10
+ # Check if the build was successful
11
+ if [ $? -ne 0 ]; then
12
+ echo "❌ Flutter build failed!"
13
+ exit 1
14
+ fi
15
+
16
+ # Generate timestamp
17
+ TIMESTAMP=$(date +%s)
18
+
19
+ # Replace BUILD_TIMESTAMP in index.html with the current timestamp
20
+ echo "📝 Adding build timestamp ($TIMESTAMP) for cache busting..."
21
+ sed -i.bak "s/BUILD_TIMESTAMP/$TIMESTAMP/g" build/web/index.html
22
+ rm build/web/index.html.bak
23
+
24
+ echo "✅ Flutter build complete!"
25
+ echo "🚀 Next step: commit build/web and push to Hugging Face!"
build/web/flutter_bootstrap.js CHANGED
@@ -39,6 +39,6 @@ _flutter.buildConfig = {"engineRevision":"382be0028d370607f76215a9be322e5514b263
39
 
40
  _flutter.loader.load({
41
  serviceWorkerSettings: {
42
- serviceWorkerVersion: "1819633575"
43
  }
44
  });
 
39
 
40
  _flutter.loader.load({
41
  serviceWorkerSettings: {
42
+ serviceWorkerVersion: "3290901739"
43
  }
44
  });
build/web/flutter_service_worker.js CHANGED
@@ -3,10 +3,10 @@ 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": "f0b6c27a0f6bac054555f105232f0c00",
7
  "version.json": "b5eaae4fc120710a3c35125322173615",
8
- "index.html": "f34c56fffc6b38f62412a5db2315dec8",
9
- "/": "f34c56fffc6b38f62412a5db2315dec8",
10
  "main.dart.js": "4e26b37ccf9ca902db38fe5292263609",
11
  "flutter.js": "83d881c1dbb6d6bcd6b42e274605b69c",
12
  "aitube.svg": "26140ba0d153b213b122bc6ebcc17f6c",
 
3
  const TEMP = 'flutter-temp-cache';
4
  const CACHE_NAME = 'flutter-app-cache';
5
 
6
+ const RESOURCES = {"flutter_bootstrap.js": "686bf9adc2191f4cc346994463a17a56",
7
  "version.json": "b5eaae4fc120710a3c35125322173615",
8
+ "index.html": "cd2094e3989e3eb0424e47d7d188c298",
9
+ "/": "cd2094e3989e3eb0424e47d7d188c298",
10
  "main.dart.js": "4e26b37ccf9ca902db38fe5292263609",
11
  "flutter.js": "83d881c1dbb6d6bcd6b42e274605b69c",
12
  "aitube.svg": "26140ba0d153b213b122bc6ebcc17f6c",
build/web/index.html CHANGED
@@ -18,21 +18,172 @@
18
 
19
  <meta charset="UTF-8">
20
  <meta content="IE=Edge" http-equiv="X-UA-Compatible">
21
- <meta name="description" content="A new Flutter project.">
22
 
23
  <!-- iOS meta tags & icons -->
24
  <meta name="apple-mobile-web-app-capable" content="yes">
25
  <meta name="apple-mobile-web-app-status-bar-style" content="black">
26
- <meta name="apple-mobile-web-app-title" content="aitube2">
27
  <link rel="apple-touch-icon" href="icons/Icon-192.png">
28
 
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
  </head>
35
  <body>
36
- <script src="flutter_bootstrap.js" async></script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  </body>
38
  </html>
 
18
 
19
  <meta charset="UTF-8">
20
  <meta content="IE=Edge" http-equiv="X-UA-Compatible">
21
+ <meta name="description" content="AI-powered video generation platform">
22
 
23
  <!-- iOS meta tags & icons -->
24
  <meta name="apple-mobile-web-app-capable" content="yes">
25
  <meta name="apple-mobile-web-app-status-bar-style" content="black">
26
+ <meta name="apple-mobile-web-app-title" content="AITube">
27
  <link rel="apple-touch-icon" href="icons/Icon-192.png">
28
 
29
  <!-- Favicon -->
30
  <link rel="icon" type="image/png" href="favicon.png"/>
31
 
32
+ <title>AITube</title>
33
  <link rel="manifest" href="manifest.json">
34
+
35
+ <style>
36
+ html, body {
37
+ background-color: #1a1a1a;
38
+ margin: 0;
39
+ padding: 0;
40
+ width: 100%;
41
+ height: 100%;
42
+ overflow: hidden;
43
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
44
+ }
45
+
46
+ body {
47
+ display: flex;
48
+ justify-content: center;
49
+ align-items: center;
50
+ position: relative;
51
+ }
52
+
53
+ .loading-container {
54
+ display: flex;
55
+ flex-direction: column;
56
+ align-items: center;
57
+ justify-content: center;
58
+ text-align: center;
59
+ position: fixed;
60
+ top: 0;
61
+ left: 0;
62
+ width: 100%;
63
+ height: 100%;
64
+ background-color: #1a1a1a;
65
+ z-index: 1000;
66
+ opacity: 1;
67
+ transition: opacity 0.5s ease;
68
+ }
69
+
70
+ .logo-container {
71
+ width: 80px;
72
+ height: 80px;
73
+ margin-bottom: 24px;
74
+ display: flex;
75
+ justify-content: center;
76
+ align-items: center;
77
+ }
78
+
79
+ .logo {
80
+ width: 100%;
81
+ height: 100%;
82
+ object-fit: contain;
83
+ animation: shake 1.2s infinite ease-in-out;
84
+ transform-origin: bottom center;
85
+ }
86
+
87
+ .loading-text {
88
+ color: #ffffff;
89
+ font-size: 20px;
90
+ margin-bottom: 16px;
91
+ font-weight: 500;
92
+ }
93
+
94
+ @keyframes shake {
95
+ 0%, 100% {
96
+ transform: translateX(0) rotate(0deg);
97
+ }
98
+ 10% {
99
+ transform: translateX(-5px) rotate(-10deg);
100
+ }
101
+ 20% {
102
+ transform: translateX(5px) rotate(10deg);
103
+ }
104
+ 30% {
105
+ transform: translateX(-5px) rotate(-10deg);
106
+ }
107
+ 40% {
108
+ transform: translateX(5px) rotate(10deg);
109
+ }
110
+ 50% {
111
+ transform: translateX(0) rotate(0deg);
112
+ }
113
+ /* Pause between 50% and 100% */
114
+ }
115
+
116
+ #flutter-target {
117
+ display: none;
118
+ width: 100%;
119
+ height: 100%;
120
+ position: absolute;
121
+ top: 0;
122
+ left: 0;
123
+ right: 0;
124
+ bottom: 0;
125
+ }
126
+ </style>
127
  </head>
128
  <body>
129
+ <div id="flutter-target"></div>
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 AITube...</div>
136
+ </div>
137
+
138
+ <script>
139
+ // Hide loading screen once Flutter app is ready
140
+ window.addEventListener('flutter-first-frame', function() {
141
+ var loading = document.getElementById('loading');
142
+ var flutterTarget = document.getElementById('flutter-target');
143
+
144
+ // Fade out loading screen
145
+ loading.style.opacity = '0';
146
+ loading.style.transition = 'opacity 0.5s ease';
147
+
148
+ // Show Flutter app
149
+ flutterTarget.style.display = 'block';
150
+
151
+ // Remove loading completely after transition
152
+ setTimeout(function() {
153
+ loading.style.display = 'none';
154
+ }, 500);
155
+ });
156
+ </script>
157
+
158
+ <!-- Add version parameter for cache busting -->
159
+ <script src="flutter_bootstrap.js?v=1746632609" async></script>
160
+
161
+ <!-- Add cache busting script -->
162
+ <script>
163
+ // Check for app updates on each load
164
+ if ('serviceWorker' in navigator) {
165
+ window.addEventListener('load', function() {
166
+ navigator.serviceWorker.ready.then(function(registration) {
167
+ // Check for updates every time the page loads
168
+ registration.update();
169
+
170
+ // Listen for updates
171
+ registration.addEventListener('updatefound', function() {
172
+ // New service worker found
173
+ const newWorker = registration.installing;
174
+
175
+ newWorker.addEventListener('statechange', function() {
176
+ if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
177
+ // New content is available, prompt user to refresh
178
+ if (confirm('A new version is available. Reload now?')) {
179
+ window.location.reload();
180
+ }
181
+ }
182
+ });
183
+ });
184
+ });
185
+ });
186
+ }
187
+ </script>
188
  </body>
189
  </html>
lib/models/video_orientation.dart ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // lib/models/video_orientation.dart
2
+
3
+ /// Enum representing the orientation of a video clip.
4
+ enum VideoOrientation {
5
+ /// Landscape orientation (horizontal, typically 16:9)
6
+ landscape,
7
+
8
+ /// Portrait orientation (vertical, typically 9:16)
9
+ portrait
10
+ }
11
+
12
+ /// Extension methods for VideoOrientation enum
13
+ extension VideoOrientationExtension on VideoOrientation {
14
+ /// Get the string representation of the orientation
15
+ String get name {
16
+ switch (this) {
17
+ case VideoOrientation.landscape:
18
+ return 'landscape';
19
+ case VideoOrientation.portrait:
20
+ return 'portrait';
21
+ }
22
+ }
23
+
24
+ /// Get the orientation from a string
25
+ static VideoOrientation fromString(String? str) {
26
+ if (str?.toLowerCase() == 'portrait') {
27
+ return VideoOrientation.portrait;
28
+ }
29
+ return VideoOrientation.landscape; // Default to landscape
30
+ }
31
+
32
+ /// Whether this orientation is portrait
33
+ bool get isPortrait => this == VideoOrientation.portrait;
34
+
35
+ /// Whether this orientation is landscape
36
+ bool get isLandscape => this == VideoOrientation.landscape;
37
+ }
web/index.html CHANGED
@@ -18,21 +18,172 @@
18
 
19
  <meta charset="UTF-8">
20
  <meta content="IE=Edge" http-equiv="X-UA-Compatible">
21
- <meta name="description" content="A new Flutter project.">
22
 
23
  <!-- iOS meta tags & icons -->
24
  <meta name="apple-mobile-web-app-capable" content="yes">
25
  <meta name="apple-mobile-web-app-status-bar-style" content="black">
26
- <meta name="apple-mobile-web-app-title" content="aitube2">
27
  <link rel="apple-touch-icon" href="icons/Icon-192.png">
28
 
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
  </head>
35
  <body>
36
- <script src="flutter_bootstrap.js" async></script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  </body>
38
  </html>
 
18
 
19
  <meta charset="UTF-8">
20
  <meta content="IE=Edge" http-equiv="X-UA-Compatible">
21
+ <meta name="description" content="AI-powered video generation platform">
22
 
23
  <!-- iOS meta tags & icons -->
24
  <meta name="apple-mobile-web-app-capable" content="yes">
25
  <meta name="apple-mobile-web-app-status-bar-style" content="black">
26
+ <meta name="apple-mobile-web-app-title" content="AITube">
27
  <link rel="apple-touch-icon" href="icons/Icon-192.png">
28
 
29
  <!-- Favicon -->
30
  <link rel="icon" type="image/png" href="favicon.png"/>
31
 
32
+ <title>AITube</title>
33
  <link rel="manifest" href="manifest.json">
34
+
35
+ <style>
36
+ html, body {
37
+ background-color: #1a1a1a;
38
+ margin: 0;
39
+ padding: 0;
40
+ width: 100%;
41
+ height: 100%;
42
+ overflow: hidden;
43
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
44
+ }
45
+
46
+ body {
47
+ display: flex;
48
+ justify-content: center;
49
+ align-items: center;
50
+ position: relative;
51
+ }
52
+
53
+ .loading-container {
54
+ display: flex;
55
+ flex-direction: column;
56
+ align-items: center;
57
+ justify-content: center;
58
+ text-align: center;
59
+ position: fixed;
60
+ top: 0;
61
+ left: 0;
62
+ width: 100%;
63
+ height: 100%;
64
+ background-color: #1a1a1a;
65
+ z-index: 1000;
66
+ opacity: 1;
67
+ transition: opacity 0.5s ease;
68
+ }
69
+
70
+ .logo-container {
71
+ width: 80px;
72
+ height: 80px;
73
+ margin-bottom: 24px;
74
+ display: flex;
75
+ justify-content: center;
76
+ align-items: center;
77
+ }
78
+
79
+ .logo {
80
+ width: 100%;
81
+ height: 100%;
82
+ object-fit: contain;
83
+ animation: shake 1.2s infinite ease-in-out;
84
+ transform-origin: bottom center;
85
+ }
86
+
87
+ .loading-text {
88
+ color: #ffffff;
89
+ font-size: 20px;
90
+ margin-bottom: 16px;
91
+ font-weight: 500;
92
+ }
93
+
94
+ @keyframes shake {
95
+ 0%, 100% {
96
+ transform: translateX(0) rotate(0deg);
97
+ }
98
+ 10% {
99
+ transform: translateX(-5px) rotate(-10deg);
100
+ }
101
+ 20% {
102
+ transform: translateX(5px) rotate(10deg);
103
+ }
104
+ 30% {
105
+ transform: translateX(-5px) rotate(-10deg);
106
+ }
107
+ 40% {
108
+ transform: translateX(5px) rotate(10deg);
109
+ }
110
+ 50% {
111
+ transform: translateX(0) rotate(0deg);
112
+ }
113
+ /* Pause between 50% and 100% */
114
+ }
115
+
116
+ #flutter-target {
117
+ display: none;
118
+ width: 100%;
119
+ height: 100%;
120
+ position: absolute;
121
+ top: 0;
122
+ left: 0;
123
+ right: 0;
124
+ bottom: 0;
125
+ }
126
+ </style>
127
  </head>
128
  <body>
129
+ <div id="flutter-target"></div>
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 AITube...</div>
136
+ </div>
137
+
138
+ <script>
139
+ // Hide loading screen once Flutter app is ready
140
+ window.addEventListener('flutter-first-frame', function() {
141
+ var loading = document.getElementById('loading');
142
+ var flutterTarget = document.getElementById('flutter-target');
143
+
144
+ // Fade out loading screen
145
+ loading.style.opacity = '0';
146
+ loading.style.transition = 'opacity 0.5s ease';
147
+
148
+ // Show Flutter app
149
+ flutterTarget.style.display = 'block';
150
+
151
+ // Remove loading completely after transition
152
+ setTimeout(function() {
153
+ loading.style.display = 'none';
154
+ }, 500);
155
+ });
156
+ </script>
157
+
158
+ <!-- Add version parameter for cache busting -->
159
+ <script src="flutter_bootstrap.js?v=BUILD_TIMESTAMP" async></script>
160
+
161
+ <!-- Add cache busting script -->
162
+ <script>
163
+ // Check for app updates on each load
164
+ if ('serviceWorker' in navigator) {
165
+ window.addEventListener('load', function() {
166
+ navigator.serviceWorker.ready.then(function(registration) {
167
+ // Check for updates every time the page loads
168
+ registration.update();
169
+
170
+ // Listen for updates
171
+ registration.addEventListener('updatefound', function() {
172
+ // New service worker found
173
+ const newWorker = registration.installing;
174
+
175
+ newWorker.addEventListener('statechange', function() {
176
+ if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
177
+ // New content is available, prompt user to refresh
178
+ if (confirm('A new version is available. Reload now?')) {
179
+ window.location.reload();
180
+ }
181
+ }
182
+ });
183
+ });
184
+ });
185
+ });
186
+ }
187
+ </script>
188
  </body>
189
  </html>