@@ -8,7 +8,12 @@ import { LECTURE_FILE_GET_URI, LECTURE_HOMEWORK_FILE_GET_URI } from "config";
8
8
9
9
import { InputText } from "shared/components/form" ;
10
10
import { Editor } from "shared/components/text-editor" ;
11
- import { RichTextEditorRef } from "shared/lib/mui-tiptap" ;
11
+ import {
12
+ blobUrlToFile ,
13
+ collectFileIds ,
14
+ findNodeByUrl ,
15
+ RichTextEditorRef ,
16
+ } from "shared/lib/mui-tiptap" ;
12
17
import { UserRole } from "api/graphql/generated/graphql" ;
13
18
import { PendingFile } from "shared/components/text-editor/types" ;
14
19
import { createUrlWithParams } from "shared/utils" ;
@@ -66,64 +71,98 @@ const EditLecture: FC<IEditLecture> = ({
66
71
67
72
const onSubmit : SubmitHandler < LectureInput > = async ( data ) => {
68
73
const { speakers, ...restData } = data ;
74
+ const emails = speakers ?. map ( ( s ) => s ?. email ) ;
75
+ if ( ! lectureId ) return ;
69
76
70
- const emails = speakers ?. map ( ( speaker ) => speaker ?. email ) ;
77
+ let content = rteRefContent . current ?. editor ?. getHTML ( ) . trim ( ) || "" ;
78
+ let contentHomework =
79
+ rteRefContentHomeWork . current ?. editor ?. getHTML ( ) . trim ( ) || "" ;
71
80
72
- let content = rteRefContent . current ?. editor ?. getHTML ( ) . trim ( ) ;
73
- let contentHomework = rteRefContentHomeWork . current ?. editor
74
- ?. getHTML ( )
75
- . trim ( ) ;
81
+ const editorContent = rteRefContent . current ?. editor ! ;
82
+ const editorHomework = rteRefContentHomeWork . current ?. editor ! ;
76
83
77
- if ( ! lectureId ) {
78
- return ;
79
- }
84
+ const contentBlobUrls = Array . from (
85
+ content . matchAll ( / ( b l o b : [ ^ " ' \s > ] + ) / g)
86
+ ) . map ( ( m ) => m [ 1 ] ) ;
87
+ const homeworkBlobUrls = Array . from (
88
+ contentHomework . matchAll ( / ( b l o b : [ ^ " ' \s > ] + ) / g)
89
+ ) . map ( ( m ) => m [ 1 ] ) ;
80
90
81
- const lectureFiles = pendingFiles . filter (
82
- ( file ) => file . source === "lecture"
91
+ const recoveredLecture = await Promise . all (
92
+ contentBlobUrls
93
+ . filter ( ( url ) => ! pendingFiles . find ( ( f ) => f . localUrl === url ) )
94
+ . map ( async ( url ) => {
95
+ const node = findNodeByUrl ( editorContent . state . doc , url ) ;
96
+ const fileName = node ?. fileName || "recovered_file" ;
97
+ const file = await blobUrlToFile ( url , fileName ) ;
98
+ return { file, localUrl : url , source : "lecture" as const } ;
99
+ } )
83
100
) ;
84
- const homeworkFiles = pendingFiles . filter (
85
- ( file ) => file . source === "lectureHomework"
101
+
102
+ const recoveredHomework = await Promise . all (
103
+ homeworkBlobUrls
104
+ . filter ( ( url ) => ! pendingFiles . find ( ( f ) => f . localUrl === url ) )
105
+ . map ( async ( url ) => {
106
+ const node = findNodeByUrl ( editorHomework . state . doc , url ) ;
107
+ const fileName = node ?. fileName || "recovered_file" ;
108
+ const file = await blobUrlToFile ( url , fileName ) ;
109
+ return { file, localUrl : url , source : "lectureHomework" as const } ;
110
+ } )
86
111
) ;
87
112
88
- const lectureUploadPromises = lectureFiles . map (
89
- async ( { file, localUrl } ) => {
90
- const uploadedFile = await uploadLectureFile ( file , lectureId ) ;
113
+ const allFiles = [
114
+ ...pendingFiles ,
115
+ ...recoveredLecture ,
116
+ ...recoveredHomework ,
117
+ ] ;
118
+ const lectureFiles = allFiles . filter ( ( f ) => f . source === "lecture" ) ;
119
+ const homeworkFiles = allFiles . filter (
120
+ ( f ) => f . source === "lectureHomework"
121
+ ) ;
122
+
123
+ const uploadedLectureFiles = await Promise . all (
124
+ lectureFiles . map ( async ( { file, localUrl } ) => {
125
+ const uploaded = await uploadLectureFile ( file , lectureId ) ;
91
126
return {
92
127
localUrl,
93
128
realUrl : createUrlWithParams ( LECTURE_FILE_GET_URI , {
94
129
lectureId,
95
- fileId : uploadedFile ?. id ! ,
130
+ fileId : uploaded ?. id ! ,
96
131
} ) ,
97
132
} ;
98
- }
133
+ } )
99
134
) ;
100
135
101
- const lectureHomeworkUploadPromises = homeworkFiles . map (
102
- async ( { file, localUrl } ) => {
103
- const uploadedFile = await uploadLectureHomeworkFile ( file , lectureId ) ;
136
+ const uploadedHomeworkFiles = await Promise . all (
137
+ homeworkFiles . map ( async ( { file, localUrl } ) => {
138
+ const uploaded = await uploadLectureHomeworkFile ( file , lectureId ) ;
104
139
return {
105
140
localUrl,
106
141
realUrl : createUrlWithParams ( LECTURE_HOMEWORK_FILE_GET_URI , {
107
142
lectureId,
108
- fileId : uploadedFile ?. id ! ,
143
+ fileId : uploaded ?. id ! ,
109
144
} ) ,
110
145
} ;
111
- }
112
- ) ;
113
-
114
- const uploadedLectureFiles = await Promise . all ( lectureUploadPromises ) ;
115
- const uploadedLectureHomeworkFiles = await Promise . all (
116
- lectureHomeworkUploadPromises
146
+ } )
117
147
) ;
118
148
119
149
uploadedLectureFiles . forEach ( ( { localUrl, realUrl } ) => {
120
- content = content ? .replaceAll ( localUrl , realUrl ) ;
150
+ content = content . replaceAll ( localUrl , realUrl ) ;
121
151
} ) ;
122
152
123
- uploadedLectureHomeworkFiles . forEach ( ( { localUrl, realUrl } ) => {
124
- contentHomework = contentHomework ? .replaceAll ( localUrl , realUrl ) ;
153
+ uploadedHomeworkFiles . forEach ( ( { localUrl, realUrl } ) => {
154
+ contentHomework = contentHomework . replaceAll ( localUrl , realUrl ) ;
125
155
} ) ;
126
156
157
+ const contentNode = rteRefContent . current ?. editor ?. state . doc ;
158
+ const contentHomeworkNode =
159
+ rteRefContentHomeWork . current ?. editor ?. state . doc ;
160
+
161
+ const currentFileIds = [
162
+ ...collectFileIds ( contentNode ! ) ,
163
+ ...collectFileIds ( contentHomeworkNode ! ) ,
164
+ ] ;
165
+
127
166
const submissionData = {
128
167
...restData ,
129
168
speakers : emails ,
@@ -133,24 +172,24 @@ const EditLecture: FC<IEditLecture> = ({
133
172
} ;
134
173
135
174
await updateLecture ( {
136
- variables : {
137
- input : submissionData ,
138
- } ,
175
+ variables : { input : submissionData } ,
139
176
onCompleted : async ( ) => {
140
177
for ( const fileId of deletedLectureFileIds ) {
141
- await deleteLectureFile ( lectureId , fileId ) ;
178
+ if ( ! currentFileIds . includes ( fileId ) ) {
179
+ await deleteLectureFile ( lectureId , fileId ) ;
180
+ }
142
181
}
182
+
143
183
for ( const fileId of deletedHomeworkFileIds ) {
144
- await deleteLectureHomeworkFile ( lectureId , fileId ) ;
184
+ if ( ! currentFileIds . includes ( fileId ) ) {
185
+ await deleteLectureHomeworkFile ( lectureId , fileId ) ;
186
+ }
145
187
}
146
188
147
189
enqueueSnackbar ( "Урок обновлен" , { variant : "success" } ) ;
148
190
} ,
149
191
onError : ( ) => {
150
- enqueueSnackbar (
151
- "Не удалось обновить данные. Пожалуйста, попробуйте снова" ,
152
- { variant : "error" }
153
- ) ;
192
+ enqueueSnackbar ( "Ошибка при обновлении" , { variant : "error" } ) ;
154
193
} ,
155
194
} ) ;
156
195
0 commit comments