@@ -8,21 +8,18 @@ const findOrCreateScreenityFolder = async (token) => {
88 "Content-Type" : "application/json" ,
99 } ) ;
1010
11- // Try to find existing folder
1211 const query = encodeURIComponent (
1312 `name='Screenity' and mimeType='application/vnd.google-apps.folder' and trashed=false`
1413 ) ;
14+
1515 const searchRes = await fetch (
1616 `https://www.googleapis.com/drive/v3/files?q=${ query } &fields=files(id,name)` ,
1717 { headers }
1818 ) ;
1919
2020 const result = await searchRes . json ( ) ;
21- if ( result . files ?. length ) {
22- return result . files [ 0 ] . id ; // Folder already exists
23- }
21+ if ( result . files ?. length ) return result . files [ 0 ] . id ;
2422
25- // Otherwise, create the folder
2623 const createRes = await fetch ( `https://www.googleapis.com/drive/v3/files` , {
2724 method : "POST" ,
2825 headers,
@@ -36,191 +33,138 @@ const findOrCreateScreenityFolder = async (token) => {
3633 return newFolder . id ;
3734} ;
3835
39- const saveToDrive = async ( videoBlob , fileName , sendResponse ) => {
40- async function getAuthTokenFromStorage ( ) {
41- return new Promise ( ( resolve , reject ) => {
42- chrome . storage . local . get ( [ "token" ] , async ( result ) => {
43- if ( chrome . runtime . lastError ) {
44- reject ( new Error ( chrome . runtime . lastError ) ) ;
45- } else {
46- const token = result . token ;
47- if ( ! token || token === null ) {
48- // Token is not set, trigger sign-in
49- const newToken = await signIn ( ) ;
50- if ( ! newToken || newToken === null ) {
51- // Sign-in failed, throw an error
52- reject ( new Error ( "Sign-in failed" ) ) ;
53- }
54- resolve ( newToken ) ;
55- } else {
56- // Token is set, check if it has expired
57- let payload ;
58- try {
59- payload = JSON . parse ( atob ( token . split ( "." ) [ 1 ] ) ) ;
60- } catch ( err ) {
61- // Token is invalid, refresh it
62- chrome . identity . getAuthToken (
63- { interactive : true } ,
64- ( newToken ) => {
65- if ( chrome . runtime . lastError ) {
66- reject ( new Error ( chrome . runtime . lastError ) ) ;
67- } else {
68- resolve ( newToken ) ;
69- }
70- }
71- ) ;
72- return ;
73- }
74-
75- const expirationTime = payload . exp * 1000 ; // Convert to milliseconds
76- const currentTime = Date . now ( ) ;
77- if ( currentTime >= expirationTime ) {
78- // Token has expired, refresh it
79- chrome . identity . getAuthToken (
80- { interactive : true } ,
81- ( newToken ) => {
82- if ( chrome . runtime . lastError ) {
83- reject ( new Error ( chrome . runtime . lastError ) ) ;
84- } else {
85- resolve ( newToken ) ;
86- }
87- }
88- ) ;
89- } else {
90- // Token is still valid
91- resolve ( token ) ;
92- }
93- }
94- }
95- } ) ;
96- } ) ;
97- }
98-
99- return new Promise ( async ( resolve , reject ) => {
100- try {
101- // Get the access token from Chrome storage
102- let token = await getAuthTokenFromStorage ( ) ;
103-
104- if ( ! token || token === null ) {
105- throw new Error ( "Sign-in failed" ) ;
36+ const getAuthTokenFromStorage = async ( ) => {
37+ return new Promise ( ( resolve , reject ) => {
38+ chrome . storage . local . get ( [ "token" ] , async ( result ) => {
39+ if ( chrome . runtime . lastError ) {
40+ reject ( new Error ( chrome . runtime . lastError ) ) ;
41+ return ;
10642 }
10743
108- // Upload the video to Google Drive
109- const headers = new Headers ( {
110- Authorization : `Bearer ${ token } ` ,
111- "Content-Type" : videoBlob . type ,
112- } ) ;
113-
114- const uploadResponse = await fetch (
115- "https://www.googleapis.com/upload/drive/v3/files?uploadType=media" ,
116- {
117- method : "POST" ,
118- headers,
119- body : videoBlob ,
120- }
121- ) ;
122-
123- if ( ! uploadResponse . ok ) {
124- throw new Error (
125- `Error uploading to Google Drive: ${ uploadResponse . status } `
126- ) ;
44+ const token = result . token ;
45+ if ( ! token ) {
46+ const newToken = await signIn ( ) ;
47+ if ( ! newToken ) reject ( new Error ( "Sign-in failed" ) ) ;
48+ else resolve ( newToken ) ;
49+ return ;
12750 }
12851
129- const responseData = await uploadResponse . json ( ) ;
130- const fileId = responseData . id ;
131-
132- if ( ! fileId ) {
133- throw new Error ( "File ID is undefined" ) ;
52+ let payload ;
53+ try {
54+ payload = JSON . parse ( atob ( token . split ( "." ) [ 1 ] ) ) ;
55+ } catch {
56+ chrome . identity . getAuthToken ( { interactive : true } , ( newToken ) => {
57+ if ( chrome . runtime . lastError )
58+ reject ( new Error ( chrome . runtime . lastError ) ) ;
59+ else resolve ( newToken ) ;
60+ } ) ;
61+ return ;
13462 }
13563
136- // Create the metadata for the file
137- const folderId = await findOrCreateScreenityFolder ( token ) ;
138- const fileMetadata = {
139- name : fileName ,
140- parents : [ folderId ] ,
141- } ;
142-
143- // Update the file metadata with the name
144- const metadataResponse = await fetch (
145- `https://www.googleapis.com/drive/v3/files/${ fileId } ` ,
146- {
147- method : "PATCH" ,
148- headers : new Headers ( {
149- Authorization : `Bearer ${ token } ` ,
150- "Content-Type" : "application/json; charset=UTF-8" ,
151- } ) ,
152- body : JSON . stringify ( fileMetadata ) ,
153- }
154- ) ;
155-
156- if ( ! metadataResponse . ok ) {
157- const errorResponse = await metadataResponse . json ( ) ;
158- console . error (
159- "Error updating file metadata:" ,
160- metadataResponse . status ,
161- errorResponse . error . message
162- ) ;
163- throw new Error (
164- `Error updating file metadata: ${ metadataResponse . status } `
165- ) ;
64+ const exp = payload . exp * 1000 ;
65+ if ( Date . now ( ) >= exp ) {
66+ chrome . identity . getAuthToken ( { interactive : true } , ( newToken ) => {
67+ if ( chrome . runtime . lastError )
68+ reject ( new Error ( chrome . runtime . lastError ) ) ;
69+ else resolve ( newToken ) ;
70+ } ) ;
71+ } else {
72+ resolve ( token ) ;
16673 }
167- sendResponse ( { status : "ok" , url : fileId } ) ;
168-
169- // Open the Google Drive file in a new tab
170- chrome . tabs . create ( {
171- url : `https://drive.google.com/file/d/${ fileId } /view` ,
172- } ) ;
173-
174- resolve ( `https://drive.google.com/file/d/${ fileId } /view` ) ; // Return the file ID if needed
175- } catch ( error ) {
176- console . error ( "Error uploading to Google Drive:" , error . message ) ;
177- sendResponse ( { status : "ew" , url : null } ) ;
178- reject ( error ) ;
179- }
74+ } ) ;
18075 } ) ;
18176} ;
18277
78+ const saveToDrive = async ( videoBlob , fileName ) => {
79+ try {
80+ const token = await getAuthTokenFromStorage ( ) ;
81+ if ( ! token ) throw new Error ( "Sign-in failed" ) ;
82+
83+ // Upload the raw media
84+ const uploadResponse = await fetch (
85+ "https://www.googleapis.com/upload/drive/v3/files?uploadType=media" ,
86+ {
87+ method : "POST" ,
88+ headers : {
89+ Authorization : `Bearer ${ token } ` ,
90+ "Content-Type" : videoBlob . type ,
91+ } ,
92+ body : videoBlob ,
93+ }
94+ ) ;
95+
96+ if ( ! uploadResponse . ok )
97+ throw new Error ( `Upload failed: ${ uploadResponse . status } ` ) ;
98+
99+ const { id : fileId } = await uploadResponse . json ( ) ;
100+ if ( ! fileId ) throw new Error ( "File ID is undefined" ) ;
101+
102+ // Add metadata and move to folder
103+ const folderId = await findOrCreateScreenityFolder ( token ) ;
104+ const metadataResponse = await fetch (
105+ `https://www.googleapis.com/drive/v3/files/${ fileId } ` ,
106+ {
107+ method : "PATCH" ,
108+ headers : {
109+ Authorization : `Bearer ${ token } ` ,
110+ "Content-Type" : "application/json; charset=UTF-8" ,
111+ } ,
112+ body : JSON . stringify ( {
113+ name : fileName ,
114+ parents : [ folderId ] ,
115+ } ) ,
116+ }
117+ ) ;
118+
119+ if ( ! metadataResponse . ok )
120+ throw new Error ( `Metadata update failed: ${ metadataResponse . status } ` ) ;
121+
122+ // Open the file in Drive
123+ chrome . tabs . create ( {
124+ url : `https://drive.google.com/file/d/${ fileId } /view` ,
125+ } ) ;
126+
127+ return { status : "ok" , url : fileId } ;
128+ } catch ( error ) {
129+ console . error ( "Error uploading to Google Drive:" , error . message ) ;
130+ return { status : "ew" , url : null } ;
131+ }
132+ } ;
133+
183134const savedToDrive = async ( ) => {
184135 const { sandboxTab } = await chrome . storage . local . get ( [ "sandboxTab" ] ) ;
185136 sendMessageTab ( sandboxTab , { type : "saved-to-drive" } ) ;
186137} ;
187138
188- export const handleSaveToDrive = async (
189- sendResponse ,
190- request ,
191- fallback = false
192- ) => {
193- if ( ! fallback ) {
194- const blob = base64ToUint8Array ( request . base64 ) ;
195-
196- const fileName = request . title + ".mp4" ;
197-
198- saveToDrive ( blob , fileName , sendResponse ) . then ( ( ) => {
199- savedToDrive ( ) ;
200- } ) ;
201- } else {
202- const chunks = [ ] ;
203- await chunksStore . iterate ( ( value , key ) => {
204- chunks . push ( value ) ;
205- } ) ;
206-
207- // Build the video from chunks
208- let array = [ ] ;
209- let lastTimestamp = 0 ;
210- for ( const chunk of chunks ) {
211- // Check if chunk timestamp is smaller than last timestamp, if so, skip
212- if ( chunk . timestamp < lastTimestamp ) {
213- continue ;
139+ export const handleSaveToDrive = async ( request , fallback = false ) => {
140+ try {
141+ let response ;
142+
143+ if ( ! fallback ) {
144+ const blob = base64ToUint8Array ( request . base64 ) ;
145+ const fileName = request . title + ".mp4" ;
146+ response = await saveToDrive ( blob , fileName ) ;
147+ } else {
148+ const chunks = [ ] ;
149+ await chunksStore . iterate ( ( value ) => chunks . push ( value ) ) ;
150+
151+ let array = [ ] ;
152+ let lastTimestamp = 0 ;
153+ for ( const chunk of chunks ) {
154+ if ( chunk . timestamp < lastTimestamp ) continue ;
155+ lastTimestamp = chunk . timestamp ;
156+ array . push ( chunk . chunk ) ;
214157 }
215- lastTimestamp = chunk . timestamp ;
216- array . push ( chunk . chunk ) ;
217- }
218- const blob = new Blob ( array , { type : "video/webm" } ) ;
219158
220- const filename = request . title + ".webm" ;
159+ const blob = new Blob ( array , { type : "video/webm" } ) ;
160+ const fileName = request . title + ".webm" ;
161+ response = await saveToDrive ( blob , fileName ) ;
162+ }
221163
222- saveToDrive ( blob , filename , sendResponse ) . then ( ( ) => {
223- savedToDrive ( ) ;
224- } ) ;
164+ await savedToDrive ( ) ;
165+ return response ;
166+ } catch ( err ) {
167+ console . error ( "handleSaveToDrive failed:" , err ) ;
168+ return { status : "ew" , url : null } ;
225169 }
226170} ;
0 commit comments