/api/files/:id/download требует Bearer-заголовок, поэтому <img>, переход по
ссылке и «Скачать» для сохранённых картинок ломались (битое изображение,
клик не открывал). Теперь личные картинки складываются в uploads/materials и
отдаются статикой (как flashcards): POST /api/files/personal возвращает
{ url:'/uploads/materials/<file>' }. board-clip, material-save, textbook-clip
и рисовалка в my-materials сохраняют этот публичный url.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
POST /api/files требует teacher/admin + library.upload — поэтому сохранение
картинок в «Мои материалы» (вырезка области учебника, обрезка доски,
рисунок, аннотация) падало с 403 у учеников и учителей без этого права.
Добавлен auth-only эндпоинт POST /api/files/personal (только картинки,
is_public=1) + LS.uploadMaterialFile. На него переключены board-clip,
material-save, textbook-clip (вырезка области) и рисовалка в my-materials.
Загрузка в учительскую библиотеку (library/lesson-editor) не тронута.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Плавающая кнопка «Вырезать область» на странице учебника: выделяешь
прямоугольник прямо на живой странице → регион растеризуется в PNG
(html2canvas, грузится лениво только при первом использовании) →
превью с редактируемым названием → сохраняется как материал-картинка.
Рядом сохранена прежняя кнопка «В мои материалы» (ссылка).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Сервер инжектит в /textbook/<slug> плавающую кнопку «В мои материалы» (js/textbook-clip.js +
material-save.js рядом с deep-link). Сохраняет текущий § как ссылку /textbook/<slug>#sec-<id>
(заголовок = название §, источник = глава). Скрыта в classroom-embed и для неавторизованных.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>