@openrails/contentkit-ui 0.85.1 → 0.87.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -7
- package/dist/client/beacons.d.ts +13 -4
- package/dist/client/beacons.js +14 -7
- package/dist/client/beacons.js.map +1 -1
- package/dist/client/client.d.ts +3 -0
- package/dist/client/client.js +29 -27
- package/dist/client/client.js.map +1 -1
- package/dist/client/codes.d.ts +6 -1
- package/dist/client/codes.js +4 -1
- package/dist/client/codes.js.map +1 -1
- package/dist/client/content/types.d.ts +4 -2
- package/dist/client/content/types.js.map +1 -1
- package/dist/client/discovery.js +3 -0
- package/dist/client/discovery.js.map +1 -1
- package/dist/client/errors.d.ts +6 -0
- package/dist/client/errors.js +6 -2
- package/dist/client/errors.js.map +1 -1
- package/dist/client/gallery.d.ts +3 -5
- package/dist/client/gallery.js +16 -20
- package/dist/client/gallery.js.map +1 -1
- package/dist/client/generated/error-codes.d.ts +1 -1
- package/dist/client/generated/error-codes.js +9 -1
- package/dist/client/generated/error-codes.js.map +1 -1
- package/dist/client/generated/routes.d.ts +29 -3
- package/dist/client/generated/routes.js +44 -3
- package/dist/client/generated/routes.js.map +1 -1
- package/dist/client/generated/wire.d.ts +60 -10
- package/dist/client/generated/wire.js.map +1 -1
- package/dist/client/index.d.ts +2 -1
- package/dist/client/media/queue.d.ts +4 -2
- package/dist/client/media/queue.js +18 -12
- package/dist/client/media/queue.js.map +1 -1
- package/dist/client/media/rules.d.ts +7 -1
- package/dist/client/media/rules.js +27 -21
- package/dist/client/media/rules.js.map +1 -1
- package/dist/client/media/windows.js +1 -1
- package/dist/client/media/windows.js.map +1 -1
- package/dist/client/stats.d.ts +32 -0
- package/dist/client/stats.js +35 -0
- package/dist/client/stats.js.map +1 -0
- package/dist/client/versions.d.ts +6 -4
- package/dist/client/versions.js +24 -26
- package/dist/client/versions.js.map +1 -1
- package/dist/client.js +30 -29
- package/dist/components/admin/content-manager.js +206 -206
- package/dist/components/admin/content-manager.js.map +1 -1
- package/dist/components/admin/group-manager.js +71 -70
- package/dist/components/admin/group-manager.js.map +1 -1
- package/dist/components/admin/media-item-panel.d.ts +24 -7
- package/dist/components/admin/media-item-panel.js +209 -197
- package/dist/components/admin/media-item-panel.js.map +1 -1
- package/dist/components/admin/poll-manager.js +25 -25
- package/dist/components/admin/stats-dashboard.d.ts +22 -0
- package/dist/components/admin/stats-dashboard.js +257 -0
- package/dist/components/admin/stats-dashboard.js.map +1 -0
- package/dist/components/content/card.d.ts +5 -3
- package/dist/components/content/card.js +155 -133
- package/dist/components/content/card.js.map +1 -1
- package/dist/components/content/download-button.d.ts +26 -0
- package/dist/components/content/download-button.js +51 -0
- package/dist/components/content/download-button.js.map +1 -0
- package/dist/components/content/editors.js +455 -427
- package/dist/components/content/editors.js.map +1 -1
- package/dist/components/content/grid.d.ts +8 -1
- package/dist/components/content/grid.js +153 -104
- package/dist/components/content/grid.js.map +1 -1
- package/dist/components/content/index.d.ts +4 -2
- package/dist/components/content/listing.d.ts +3 -1
- package/dist/components/content/listing.js +34 -34
- package/dist/components/content/listing.js.map +1 -1
- package/dist/components/content/paywall.d.ts +17 -5
- package/dist/components/content/paywall.js +115 -100
- package/dist/components/content/paywall.js.map +1 -1
- package/dist/components/content/reader-stats.d.ts +12 -0
- package/dist/components/content/reader-stats.js +47 -0
- package/dist/components/content/reader-stats.js.map +1 -0
- package/dist/components/groups/banner.js +33 -33
- package/dist/components/groups/directory.js +11 -11
- package/dist/components/groups/editor.js +293 -293
- package/dist/components/groups/editor.js.map +1 -1
- package/dist/components/groups/header.js +27 -27
- package/dist/components/groups/header.js.map +1 -1
- package/dist/components/groups/memberships.js +180 -180
- package/dist/components/groups/parts.d.ts +0 -2
- package/dist/components/groups/parts.js +9 -27
- package/dist/components/groups/parts.js.map +1 -1
- package/dist/components/media-folder-editor.js +239 -189
- package/dist/components/media-folder-editor.js.map +1 -1
- package/dist/components/media-gallery.d.ts +1 -4
- package/dist/components/media-gallery.js +19 -34
- package/dist/components/media-gallery.js.map +1 -1
- package/dist/components/notifications.js +17 -17
- package/dist/components/slot-upload.d.ts +2 -2
- package/dist/components/slot-upload.js +84 -79
- package/dist/components/slot-upload.js.map +1 -1
- package/dist/components/social/bans.js +34 -34
- package/dist/components/social/comments.js +1 -1
- package/dist/components/social/comments.js.map +1 -1
- package/dist/components/social/engagement.d.ts +2 -1
- package/dist/components/social/engagement.js +5 -3
- package/dist/components/social/engagement.js.map +1 -1
- package/dist/components/social/moderation.js +52 -48
- package/dist/components/social/moderation.js.map +1 -1
- package/dist/components/video-player.d.ts +2 -0
- package/dist/components/video-player.js +318 -314
- package/dist/components/video-player.js.map +1 -1
- package/dist/i18n/context.d.ts +2 -0
- package/dist/i18n/context.js +23 -5
- package/dist/i18n/context.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +13 -10
- package/dist/locales/admin/de.js +27 -0
- package/dist/locales/admin/de.js.map +1 -1
- package/dist/locales/admin/en.d.ts +27 -0
- package/dist/locales/admin/en.js +27 -0
- package/dist/locales/admin/en.js.map +1 -1
- package/dist/locales/admin/es.js +27 -0
- package/dist/locales/admin/es.js.map +1 -1
- package/dist/locales/admin/ja.js +27 -0
- package/dist/locales/admin/ja.js.map +1 -1
- package/dist/locales/admin/ko.js +27 -0
- package/dist/locales/admin/ko.js.map +1 -1
- package/dist/locales/admin/zh.js +27 -0
- package/dist/locales/admin/zh.js.map +1 -1
- package/dist/locales/content/de.js +6 -0
- package/dist/locales/content/de.js.map +1 -1
- package/dist/locales/content/en.d.ts +6 -0
- package/dist/locales/content/en.js +6 -0
- package/dist/locales/content/en.js.map +1 -1
- package/dist/locales/content/es.js +6 -0
- package/dist/locales/content/es.js.map +1 -1
- package/dist/locales/content/ja.js +6 -0
- package/dist/locales/content/ja.js.map +1 -1
- package/dist/locales/content/ko.js +6 -0
- package/dist/locales/content/ko.js.map +1 -1
- package/dist/locales/content/zh.js +6 -0
- package/dist/locales/content/zh.js.map +1 -1
- package/dist/locales/de.js +14 -2
- package/dist/locales/de.js.map +1 -1
- package/dist/locales/discovery/de.js +3 -0
- package/dist/locales/discovery/de.js.map +1 -1
- package/dist/locales/discovery/en.d.ts +3 -0
- package/dist/locales/discovery/en.js +3 -0
- package/dist/locales/discovery/en.js.map +1 -1
- package/dist/locales/discovery/es.js +3 -0
- package/dist/locales/discovery/es.js.map +1 -1
- package/dist/locales/discovery/ja.js +3 -0
- package/dist/locales/discovery/ja.js.map +1 -1
- package/dist/locales/discovery/ko.js +3 -0
- package/dist/locales/discovery/ko.js.map +1 -1
- package/dist/locales/discovery/zh.js +3 -0
- package/dist/locales/discovery/zh.js.map +1 -1
- package/dist/locales/en.d.ts +50 -2
- package/dist/locales/en.js +14 -2
- package/dist/locales/en.js.map +1 -1
- package/dist/locales/es.js +14 -2
- package/dist/locales/es.js.map +1 -1
- package/dist/locales/ja.js +14 -2
- package/dist/locales/ja.js.map +1 -1
- package/dist/locales/ko.js +14 -2
- package/dist/locales/ko.js.map +1 -1
- package/dist/locales/zh.js +14 -2
- package/dist/locales/zh.js.map +1 -1
- package/dist/react/admin.js +22 -23
- package/dist/react/admin.js.map +1 -1
- package/dist/react/canonical.d.ts +4 -3
- package/dist/react/canonical.js +34 -33
- package/dist/react/canonical.js.map +1 -1
- package/dist/react/comments.d.ts +1 -1
- package/dist/react/comments.js +3 -2
- package/dist/react/comments.js.map +1 -1
- package/dist/react/contents.js +144 -144
- package/dist/react/contents.js.map +1 -1
- package/dist/react/context.d.ts +1 -1
- package/dist/react/context.js.map +1 -1
- package/dist/react/detail.d.ts +12 -6
- package/dist/react/detail.js +31 -24
- package/dist/react/detail.js.map +1 -1
- package/dist/react/discovery.d.ts +11 -0
- package/dist/react/discovery.js +49 -30
- package/dist/react/discovery.js.map +1 -1
- package/dist/react/engagement.d.ts +6 -2
- package/dist/react/engagement.js +2 -6
- package/dist/react/engagement.js.map +1 -1
- package/dist/react/folder.d.ts +7 -2
- package/dist/react/folder.js +165 -147
- package/dist/react/folder.js.map +1 -1
- package/dist/react/groups.d.ts +0 -1
- package/dist/react/groups.js +13 -12
- package/dist/react/groups.js.map +1 -1
- package/dist/react/index.d.ts +6 -4
- package/dist/react/location.d.ts +11 -0
- package/dist/react/location.js +18 -0
- package/dist/react/location.js.map +1 -0
- package/dist/react/public.d.ts +8 -0
- package/dist/react/public.js +32 -27
- package/dist/react/public.js.map +1 -1
- package/dist/react/stats.d.ts +24 -0
- package/dist/react/stats.js +28 -0
- package/dist/react/stats.js.map +1 -0
- package/dist/react/use-resource.js +8 -7
- package/dist/react/use-resource.js.map +1 -1
- package/dist/react/versions.d.ts +25 -5
- package/dist/react/versions.js +61 -40
- package/dist/react/versions.js.map +1 -1
- package/dist/react.js +26 -24
- package/dist/styles.css +1 -1
- package/dist/urls/index.d.ts +35 -10
- package/dist/urls.js +100 -70
- package/dist/urls.js.map +1 -1
- package/package.json +1 -1
package/dist/locales/ko.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ko.js","names":[],"sources":["../../src/locales/ko.ts"],"sourcesContent":["import type { ContentKitUiMessageBundle } from \"../i18n/messages.js\";\nimport { admin } from \"./admin/ko.js\";\nimport { social } from \"./social/ko.js\";\nimport { groups } from \"./groups/ko.js\";\nimport { discovery } from \"./discovery/ko.js\";\nimport { content } from \"./content/ko.js\";\n\nexport const ko: ContentKitUiMessageBundle = {\n ...social,\n ...admin,\n ...groups,\n ...discovery,\n ...content,\n common: {\n cancel: \"취소\",\n close: \"닫기\",\n save: \"저장\",\n saving: \"저장 중…\",\n retry: \"다시 시도\",\n change: \"변경\",\n upload: \"업로드\",\n editCrop: \"자르기 편집\",\n remove: \"삭제\",\n rename: \"이름 바꾸기\",\n replace: \"바꾸기\",\n },\n crop: {\n title: \"이미지 자르기\",\n avatarTitle: \"아바타 자르기\",\n coverTitle: \"커버 이미지 자르기\",\n description: \"드래그해서 위치를 조정하세요. 스크롤, 핀치 또는 슬라이더로 확대/축소할 수 있습니다.\",\n area: \"자르기 영역. 화살표 키로 이미지를 이동하고 + 또는 −로 확대/축소, R로 회전하세요.\",\n zoom: \"확대/축소\",\n zoomIn: \"확대\",\n zoomOut: \"축소\",\n rotateLeft: \"왼쪽으로 회전\",\n rotateRight: \"오른쪽으로 회전\",\n reset: \"초기화\",\n undersized: \"이 자르기 영역의 너비는 {width}px입니다. 고밀도 화면에서 선명하게 보이려면 {target}px 이상이 좋습니다.\",\n tooSmall: \"이 이미지의 너비는 최대 {width}px입니다. 최소 {min}px이어야 합니다. 더 큰 이미지를 사용하세요.\",\n shape: \"비율\",\n original: \"원본\",\n preview: \"결과 미리보기\",\n size: \"{width} × {height}px\",\n },\n sortable: {\n handle: \"{name} 순서 변경\",\n instructions: \"순서를 바꾸려면 Space 또는 Enter를 누르고 화살표 키로 옮긴 뒤 Space 또는 Enter를 다시 눌러 놓으세요. Escape를 누르면 취소됩니다.\",\n pickedUp: \"{name}을(를) 들었습니다. {total}개 중 {position}번째입니다.\",\n over: \"{name}이(가) {total}개 중 {position}번째로 이동합니다.\",\n dropped: \"{name}을(를) {total}개 중 {position}번째에 놓았습니다.\",\n droppedAway: \"{name}을(를) 놓았습니다.\",\n canceled: \"{name} 이동을 취소했습니다.\",\n },\n folder: {\n label: \"미디어\",\n drop: \"여기에 파일을 놓거나 클릭해서 선택하세요\",\n add: \"파일 추가\",\n commit: \"{count}개 추가\",\n commitAgain: \"다시 추가\",\n adding: \"추가하는 중…\",\n queued: \"대기 중\",\n uploaded: \"업로드됨\",\n processing: \"처리 중…\",\n processingPercent: \"처리 중 {percent}%\",\n edited: \"편집됨\",\n failed: \"처리되지 않음\",\n failedVideo: \"재생할 수 없음\",\n crop: \"자르기 및 회전\",\n select: \"{name} 선택\",\n selected: \"{count}개 선택됨\",\n removeSelected: \"선택 항목 삭제\",\n clearSelection: \"선택 해제\",\n confirmRemove: \"파일 {count}개를 삭제할까요? 되돌릴 수 없습니다.\",\n renameLabel: \"{name}의 새 이름\",\n paused: \"업로드가 일시 중지됨\",\n resume: \"다시 시작\",\n dismiss: \"닫기\",\n limitSize: \"{what} 최대 {size}\",\n limitMax: \"최대 {max}개\",\n limitAspect: \"동영상 비율 {min} ~ {max}\",\n kinds: {\n image: \"이미지\",\n video: \"동영상\",\n audio: \"오디오\",\n subtitle: \"자막\",\n file: \"파일\",\n },\n },\n readiness: {\n processing: \"미디어 처리 중\",\n processingHint: \"모든 파일이 처리되면 자동으로 게시됩니다.\",\n failedOne: \"{name}을(를) 처리할 수 없습니다\",\n failedMany: \"파일 {count}개를 처리할 수 없습니다: {names}\",\n failedHint: \"이 파일들을 삭제하면 자동으로 게시됩니다.\",\n },\n avatar: {\n label: \"아바타\",\n empty: \"아바타 없음\",\n hint: \"정사각형 이미지, {size}px 이상.\",\n },\n cover: {\n label: \"커버 이미지\",\n empty: \"커버 이미지 없음\",\n hint: \"가로로 긴 이미지, {width} × {height}px 이상.\",\n drop: \"여기에 이미지를 놓으세요\",\n },\n poster: {\n title: \"커버 설정\",\n description: \"동영상의 프레임을 고르거나 이미지를 업로드하세요. 커버는 동영상과 같은 비율입니다.\",\n frame: \"동영상 프레임\",\n upload: \"이미지 업로드\",\n time: \"시간\",\n previousFrame: \"이전 프레임\",\n nextFrame: \"다음 프레임\",\n jumpTo: \"{time}(으)로 이동\",\n useFrame: \"이 프레임 사용\",\n crop: \"자르기…\",\n cropTitle: \"커버 자르기\",\n auto: \"자동\",\n autoHint: \"직접 고르기 전까지 자동으로 선택된 프레임이 사용됩니다.\",\n drop: \"여기에 이미지를 놓거나 클릭해서 선택하세요\",\n processing: \"동영상을 아직 처리 중입니다. 인코딩이 끝나면 커버를 설정할 수 있습니다.\",\n rendering: \"커버 생성 중…\",\n },\n progress: {\n decoding: \"이미지 여는 중…\",\n hashing: \"준비 중…\",\n uploading: \"업로드 중… {percent}%\",\n completing: \"업로드 마무리 중…\",\n rendering: \"크기별 이미지 생성 중…\",\n },\n encode: {\n processing: \"동영상 처리 중\",\n queued: \"처리 대기 중\",\n queuedPosition: \"대기 중 · {position}번째\",\n stalled: \"처리가 일시 중지되었습니다. 서버를 기다리는 중…\",\n segments: \"세그먼트 {done} / {total}\",\n higherQualities: \"고화질\",\n remainingSeconds: \"약 {seconds}초 남음\",\n remainingMinutes: \"약 {minutes}분 남음\",\n remainingHours: \"약 {hours}시간 {minutes}분 남음\",\n almostDone: \"거의 완료\",\n estimating: \"남은 시간 계산 중…\",\n phase: {\n queued: \"대기 중\",\n downloading: \"준비 중\",\n probing: \"분석 중\",\n encoding: \"인코딩 중\",\n muxing: \"패키징 중\",\n uploading: \"저장 중\",\n publishing: \"게시 중\",\n images: \"커버 만드는 중\",\n },\n },\n gallery: {\n label: \"미디어\",\n view: \"보기\",\n carousel: \"캐러셀\",\n grid: \"그리드\",\n counter: \"{current} / {total}\",\n slide: \"{total}개 중 {current}번째\",\n previous: \"이전\",\n next: \"다음\",\n goTo: \"{index}번째 항목으로 이동\",\n open: \"{total}개 중 {index}번째 항목 열기\",\n lightbox: \"미디어 뷰어\",\n lockedOne: \"1개 항목이 더 잠겨 있습니다\",\n lockedMany: \"{count}개 항목이 더 잠겨 있습니다\",\n processingImage: \"이미지 처리 중…\",\n image: \"이미지 {index}\",\n video: \"동영상 {index}\",\n audio: \"오디오 {index}\",\n processingAudio: \"오디오 처리 중…\",\n download: \"다운로드\",\n failedAudio: \"이 오디오를 처리할 수 없습니다.\",\n failedImage: \"이 이미지를 처리할 수 없습니다.\",\n },\n player: {\n play: \"동영상 재생\",\n loading: \"동영상 불러오는 중…\",\n retry: \"다시 시도\",\n code: \"코드 {code}\",\n quality: \"화질\",\n auto: \"자동\",\n autoCurrent: \"자동({quality})\",\n label: \"동영상 플레이어\",\n resume: \"재생\",\n pause: \"일시정지\",\n replay: \"다시 재생\",\n seek: \"탐색\",\n time: \"{current} / {duration}\",\n seekBack: \"{seconds}초 뒤로\",\n seekForward: \"{seconds}초 앞으로\",\n seconds: \"{seconds}초\",\n mute: \"음소거\",\n unmute: \"음소거 해제\",\n volume: \"볼륨\",\n settings: \"설정\",\n speed: \"재생 속도\",\n normal: \"보통\",\n audio: \"오디오\",\n subtitles: \"자막\",\n subtitlesOff: \"사용 안함\",\n forced: \"{label}(강제)\",\n track: \"트랙 {number}\",\n fullscreen: \"전체 화면\",\n exitFullscreen: \"전체 화면 종료\",\n pip: \"PIP 모드\",\n exitPip: \"PIP 모드 종료\",\n theater: \"영화관 모드\",\n miniPlayer: \"미니 플레이어\",\n expand: \"확대\",\n close: \"닫기\",\n failed: \"이 동영상을 처리하지 못했습니다.\",\n errors: {\n network: \"동영상 서버에 연결할 수 없습니다.\",\n access: \"이 동영상에 더 이상 접근할 수 없습니다.\",\n not_found: \"이 동영상을 사용할 수 없습니다.\",\n rate_limited: \"요청이 너무 많습니다. 잠시 후 다시 시도해 주세요.\",\n unsupported: \"이 브라우저에서는 이 동영상을 재생할 수 없습니다.\",\n stalled: \"재생이 멈췄습니다. 연결을 확인하고 다시 시도해 주세요.\",\n unknown: \"지금은 이 동영상을 재생할 수 없습니다.\",\n },\n },\n errors: {\n generic: \"서버에서 문제가 발생했습니다. 다시 시도하세요.\",\n network: \"연결이 끊어졌습니다. 네트워크를 확인하고 다시 시도해 주세요.\",\n storage: \"업로드가 중단되었습니다. 다시 시도해 주세요.\",\n decode: \"이 파일은 이미지로 열 수 없습니다.\",\n invalid_request: \"이미지를 저장할 수 없습니다.\",\n unauthorized: \"세션이 만료되었습니다. 다시 로그인해 주세요.\",\n forbidden: \"이 이미지를 변경할 권한이 없습니다.\",\n not_found: \"이 항목은 더 이상 존재하지 않습니다.\",\n conflict: \"다른 곳에서 변경되었습니다. 새로고침 후 다시 시도해 주세요.\",\n incomplete: \"업로드가 완료되지 않았습니다. 다시 시도해 주세요.\",\n not_uploaded: \"업로드가 만료되었습니다. 이미지를 다시 선택해 주세요.\",\n too_large: \"파일이 너무 큽니다.\",\n quota_exceeded: \"저장 공간 한도에 도달했습니다.\",\n type_not_allowed: \"이 파일 형식은 여기에서 지원되지 않습니다.\",\n checksum_mismatch: \"업로드 중 파일이 변경되었습니다. 다시 시도해 주세요.\",\n rate_limited: \"업로드가 너무 많습니다. {seconds}초 후에 다시 시도해 주세요.\",\n unavailable: \"미디어 저장소를 사용할 수 없습니다. 잠시 후 다시 시도하세요.\",\n upgrade_required: \"이 항목은 업그레이드 중입니다. 잠시 후 다시 시도하세요.\",\n internal_error: \"서버에서 문제가 발생했습니다. 다시 시도하세요.\",\n allowedTypes: \"{allowed} 형식을 사용하세요.\",\n tooLargeBy: \"이 파일은 {size}입니다. 제한은 {max}입니다.\",\n image_too_small: \"자른 이미지의 너비는 {width}px입니다. 최소 {min}px이어야 합니다. 더 넓은 영역을 선택하거나 더 큰 이미지를 사용하세요.\",\n image_too_large: \"이 이미지는 {width}×{height}px입니다. 이미지는 최대 {megapixels}메가픽셀까지 가능합니다.\",\n image_unreadable: \"이 파일은 올바른 {format} 이미지가 아닙니다.\",\n render_timeout: \"서버에서 아직 처리 중입니다. 준비되면 표시됩니다. 잠시 후 다시 확인하세요.\",\n animation_not_allowed: \"여기에는 움직이는 이미지를 사용할 수 없습니다. 정지 이미지를 업로드하세요.\",\n animation_unsupported: \"움직이는 {format} 이미지는 지원되지 않습니다. 움직이는 WebP 또는 GIF를 사용하세요.\",\n animationFrames: \"애니메이션은 최대 {maxFrames}프레임까지 가능합니다. 이 이미지는 {frames}프레임입니다.\",\n animationSeconds: \"애니메이션은 최대 {maxSeconds}초까지 가능합니다.\",\n animationTooLarge: \"이 애니메이션이 너무 큽니다: {width}×{height}px, {frames}프레임. 프레임 수나 크기를 줄이세요.\",\n too_many_files: \"이 항목에 허용된 파일 수가 이미 찼습니다. 먼저 일부를 삭제하세요.\",\n animation_too_long: \"이 애니메이션이 너무 깁니다.\",\n video_too_long: \"이 파일은 허용된 길이보다 깁니다.\",\n video_too_large: \"이 동영상의 프레임 크기가 허용 범위보다 큽니다.\",\n videoTooLongBy: \"이 파일의 길이는 {duration}초입니다. 여기서는 최대 {maxSeconds}초까지 가능합니다.\",\n videoTooLargeBy: \"이 동영상은 {width}×{height}px입니다. 동영상은 최대 {megapixels}메가픽셀까지 가능합니다.\",\n video_over_budget: \"이 동영상은 처리 시간이 너무 오래 걸립니다. 더 짧거나 작은 동영상을 사용하세요.\",\n video_aspect_unsupported: \"이 동영상은 가로나 세로로 너무 길어 여기에서 사용할 수 없습니다.\",\n videoAspectBy: \"이 동영상의 비율은 {shape}입니다. 여기에서는 {minAspect}에서 {maxAspect} 사이의 동영상만 사용할 수 있습니다.\",\n tooManyFilesBy: \"이 항목에는 이 파일을 최대 {maxFiles}개까지 넣을 수 있습니다. 먼저 일부를 삭제하세요.\",\n aborted: \"취소되었습니다.\",\n resume_mismatch: \"저장된 업로드가 다른 파일의 것입니다. 파일을 다시 선택하세요.\",\n moderation_rejected: \"검토 결과 거부되었습니다.\",\n comment_banned: \"여기에는 댓글을 달 수 없습니다.\",\n comments_closed: \"여기는 댓글이 닫혀 있습니다.\",\n comments_locked: \"댓글을 보고 쓰려면 잠금을 해제하세요.\",\n not_joinable: \"지금은 이 그룹에 가입할 수 없습니다.\",\n limit_reached: \"허용된 개수를 모두 사용했습니다.\",\n comment_too_long: \"댓글이 너무 깁니다.\",\n commentTooLongBy: \"댓글은 최대 {maxChars}자까지 쓸 수 있습니다.\",\n not_configured: \"이 사이트에서는 사용할 수 없는 기능입니다.\",\n tenant_mismatch: \"서버에서 문제가 발생했습니다. 다시 시도하세요.\",\n gone: \"이 콘텐츠는 더 이상 사용할 수 없습니다.\",\n },\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ko.js","names":[],"sources":["../../src/locales/ko.ts"],"sourcesContent":["import type { ContentKitUiMessageBundle } from \"../i18n/messages.js\";\nimport { admin } from \"./admin/ko.js\";\nimport { social } from \"./social/ko.js\";\nimport { groups } from \"./groups/ko.js\";\nimport { discovery } from \"./discovery/ko.js\";\nimport { content } from \"./content/ko.js\";\n\nexport const ko: ContentKitUiMessageBundle = {\n ...social,\n ...admin,\n ...groups,\n ...discovery,\n ...content,\n common: {\n cancel: \"취소\",\n close: \"닫기\",\n save: \"저장\",\n saving: \"저장 중…\",\n retry: \"다시 시도\",\n change: \"변경\",\n upload: \"업로드\",\n editCrop: \"자르기 편집\",\n remove: \"삭제\",\n rename: \"이름 바꾸기\",\n replace: \"바꾸기\",\n },\n crop: {\n title: \"이미지 자르기\",\n avatarTitle: \"아바타 자르기\",\n coverTitle: \"커버 이미지 자르기\",\n description: \"드래그해서 위치를 조정하세요. 스크롤, 핀치 또는 슬라이더로 확대/축소할 수 있습니다.\",\n area: \"자르기 영역. 화살표 키로 이미지를 이동하고 + 또는 −로 확대/축소, R로 회전하세요.\",\n zoom: \"확대/축소\",\n zoomIn: \"확대\",\n zoomOut: \"축소\",\n rotateLeft: \"왼쪽으로 회전\",\n rotateRight: \"오른쪽으로 회전\",\n reset: \"초기화\",\n undersized: \"이 자르기 영역의 너비는 {width}px입니다. 고밀도 화면에서 선명하게 보이려면 {target}px 이상이 좋습니다.\",\n tooSmall: \"이 이미지의 너비는 최대 {width}px입니다. 최소 {min}px이어야 합니다. 더 큰 이미지를 사용하세요.\",\n shape: \"비율\",\n original: \"원본\",\n preview: \"결과 미리보기\",\n size: \"{width} × {height}px\",\n },\n sortable: {\n handle: \"{name} 순서 변경\",\n instructions: \"순서를 바꾸려면 Space 또는 Enter를 누르고 화살표 키로 옮긴 뒤 Space 또는 Enter를 다시 눌러 놓으세요. Escape를 누르면 취소됩니다.\",\n pickedUp: \"{name}을(를) 들었습니다. {total}개 중 {position}번째입니다.\",\n over: \"{name}이(가) {total}개 중 {position}번째로 이동합니다.\",\n dropped: \"{name}을(를) {total}개 중 {position}번째에 놓았습니다.\",\n droppedAway: \"{name}을(를) 놓았습니다.\",\n canceled: \"{name} 이동을 취소했습니다.\",\n },\n folder: {\n label: \"미디어\",\n drop: \"여기에 파일을 놓거나 클릭해서 선택하세요\",\n add: \"파일 추가\",\n commit: \"{count}개 추가\",\n commitAgain: \"다시 추가\",\n adding: \"추가하는 중…\",\n queued: \"대기 중\",\n uploaded: \"업로드됨\",\n notAdded: \"업로드됨, 아직 추가되지 않음\",\n processing: \"처리 중…\",\n processingPercent: \"처리 중 {percent}%\",\n edited: \"편집됨\",\n failed: \"처리되지 않음\",\n failedVideo: \"재생할 수 없음\",\n crop: \"자르기 및 회전\",\n select: \"{name} 선택\",\n selected: \"{count}개 선택됨\",\n removeSelected: \"선택 항목 삭제\",\n clearSelection: \"선택 해제\",\n confirmRemove: \"파일 {count}개를 삭제할까요? 되돌릴 수 없습니다.\",\n renameLabel: \"{name}의 새 이름\",\n paused: \"업로드가 일시 중지됨\",\n resume: \"다시 시작\",\n dismiss: \"닫기\",\n limitSize: \"{what} 최대 {size}\",\n limitMax: \"최대 {max}개\",\n limitAspect: \"동영상 비율 {min} ~ {max}\",\n kinds: {\n image: \"이미지\",\n video: \"동영상\",\n audio: \"오디오\",\n subtitle: \"자막\",\n file: \"파일\",\n },\n },\n readiness: {\n processing: \"미디어 처리 중\",\n processingHint: \"모든 파일이 처리되면 자동으로 게시됩니다.\",\n failedOne: \"{name}을(를) 처리할 수 없습니다\",\n failedMany: \"파일 {count}개를 처리할 수 없습니다: {names}\",\n failedHint: \"이 파일들을 삭제하면 자동으로 게시됩니다.\",\n },\n avatar: {\n label: \"아바타\",\n empty: \"아바타 없음\",\n hint: \"정사각형 이미지, {size}px 이상.\",\n },\n cover: {\n label: \"커버 이미지\",\n empty: \"커버 이미지 없음\",\n hint: \"가로로 긴 이미지, {width} × {height}px 이상.\",\n drop: \"여기에 이미지를 놓으세요\",\n },\n poster: {\n title: \"커버 설정\",\n description: \"동영상의 프레임을 고르거나 이미지를 업로드하세요. 커버는 동영상과 같은 비율입니다.\",\n frame: \"동영상 프레임\",\n upload: \"이미지 업로드\",\n time: \"시간\",\n previousFrame: \"이전 프레임\",\n nextFrame: \"다음 프레임\",\n jumpTo: \"{time}(으)로 이동\",\n useFrame: \"이 프레임 사용\",\n crop: \"자르기…\",\n cropTitle: \"커버 자르기\",\n auto: \"자동\",\n autoHint: \"직접 고르기 전까지 자동으로 선택된 프레임이 사용됩니다.\",\n drop: \"여기에 이미지를 놓거나 클릭해서 선택하세요\",\n processing: \"동영상을 아직 처리 중입니다. 인코딩이 끝나면 커버를 설정할 수 있습니다.\",\n rendering: \"커버 생성 중…\",\n },\n progress: {\n decoding: \"이미지 여는 중…\",\n hashing: \"준비 중…\",\n uploading: \"업로드 중… {percent}%\",\n completing: \"업로드 마무리 중…\",\n rendering: \"크기별 이미지 생성 중…\",\n },\n encode: {\n processing: \"동영상 처리 중\",\n queued: \"처리 대기 중\",\n queuedPosition: \"대기 중 · {position}번째\",\n stalled: \"처리가 일시 중지되었습니다. 서버를 기다리는 중…\",\n segments: \"세그먼트 {done} / {total}\",\n higherQualities: \"고화질\",\n remainingSeconds: \"약 {seconds}초 남음\",\n remainingMinutes: \"약 {minutes}분 남음\",\n remainingHours: \"약 {hours}시간 {minutes}분 남음\",\n almostDone: \"거의 완료\",\n estimating: \"남은 시간 계산 중…\",\n phase: {\n queued: \"대기 중\",\n downloading: \"준비 중\",\n probing: \"분석 중\",\n encoding: \"인코딩 중\",\n muxing: \"패키징 중\",\n uploading: \"저장 중\",\n publishing: \"게시 중\",\n images: \"커버 만드는 중\",\n },\n },\n gallery: {\n label: \"미디어\",\n view: \"보기\",\n carousel: \"캐러셀\",\n grid: \"그리드\",\n counter: \"{current} / {total}\",\n slide: \"{total}개 중 {current}번째\",\n previous: \"이전\",\n next: \"다음\",\n goTo: \"{index}번째 항목으로 이동\",\n open: \"{total}개 중 {index}번째 항목 열기\",\n lightbox: \"미디어 뷰어\",\n locked: \"나머지는 잠겨 있습니다\",\n processingImage: \"이미지 처리 중…\",\n image: \"이미지 {index}\",\n video: \"동영상 {index}\",\n audio: \"오디오 {index}\",\n processingAudio: \"오디오 처리 중…\",\n download: \"다운로드\",\n failedAudio: \"이 오디오를 처리할 수 없습니다.\",\n failedImage: \"이 이미지를 처리할 수 없습니다.\",\n },\n player: {\n play: \"동영상 재생\",\n loading: \"동영상 불러오는 중…\",\n retry: \"다시 시도\",\n code: \"코드 {code}\",\n quality: \"화질\",\n auto: \"자동\",\n autoCurrent: \"자동({quality})\",\n label: \"동영상 플레이어\",\n resume: \"재생\",\n pause: \"일시정지\",\n replay: \"다시 재생\",\n seek: \"탐색\",\n time: \"{current} / {duration}\",\n seekBack: \"{seconds}초 뒤로\",\n seekForward: \"{seconds}초 앞으로\",\n seconds: \"{seconds}초\",\n mute: \"음소거\",\n unmute: \"음소거 해제\",\n volume: \"볼륨\",\n settings: \"설정\",\n speed: \"재생 속도\",\n normal: \"보통\",\n audio: \"오디오\",\n subtitles: \"자막\",\n subtitlesOff: \"사용 안함\",\n forced: \"{label}(강제)\",\n track: \"트랙 {number}\",\n fullscreen: \"전체 화면\",\n exitFullscreen: \"전체 화면 종료\",\n pip: \"PIP 모드\",\n exitPip: \"PIP 모드 종료\",\n theater: \"영화관 모드\",\n miniPlayer: \"미니 플레이어\",\n expand: \"확대\",\n close: \"닫기\",\n failed: \"이 동영상을 처리하지 못했습니다.\",\n errors: {\n network: \"동영상 서버에 연결할 수 없습니다.\",\n access: \"이 동영상에 더 이상 접근할 수 없습니다.\",\n not_found: \"이 동영상을 사용할 수 없습니다.\",\n rate_limited: \"요청이 너무 많습니다. 잠시 후 다시 시도해 주세요.\",\n unsupported: \"이 브라우저에서는 이 동영상을 재생할 수 없습니다.\",\n stalled: \"재생이 멈췄습니다. 연결을 확인하고 다시 시도해 주세요.\",\n unknown: \"지금은 이 동영상을 재생할 수 없습니다.\",\n },\n },\n versionDownload: {\n unavailable: \"지금은 다운로드할 수 없습니다.\",\n availableIn_one: \"{count}일 후에 다운로드할 수 있습니다\",\n availableIn_other: \"{count}일 후에 다운로드할 수 있습니다\",\n label: \"다운로드\",\n preparing: \"다운로드 준비 중…\",\n locked: \"다운로드하려면 잠금을 해제하세요.\",\n limited: \"다운로드 한도에 도달했습니다. {minutes}분 후에 다시 시도하세요.\",\n failed: \"다운로드를 시작할 수 없습니다. 다시 시도하세요.\",\n },\n errors: {\n download_unavailable: \"지금은 다운로드할 수 없습니다.\",\n no_download: \"아직 다운로드할 항목이 없습니다.\",\n generic: \"서버에서 문제가 발생했습니다. 다시 시도하세요.\",\n network: \"연결이 끊어졌습니다. 네트워크를 확인하고 다시 시도해 주세요.\",\n storage: \"업로드가 중단되었습니다. 다시 시도해 주세요.\",\n decode: \"이 파일은 이미지로 열 수 없습니다.\",\n invalid_request: \"이미지를 저장할 수 없습니다.\",\n unauthorized: \"세션이 만료되었습니다. 다시 로그인해 주세요.\",\n forbidden: \"이 이미지를 변경할 권한이 없습니다.\",\n not_found: \"이 항목은 더 이상 존재하지 않습니다.\",\n conflict: \"다른 곳에서 변경되었습니다. 새로고침 후 다시 시도해 주세요.\",\n incomplete: \"업로드가 완료되지 않았습니다. 다시 시도해 주세요.\",\n not_uploaded: \"업로드가 만료되었습니다. 이미지를 다시 선택해 주세요.\",\n too_large: \"파일이 너무 큽니다.\",\n quota_exceeded: \"저장 공간 한도에 도달했습니다.\",\n type_not_allowed: \"이 파일 형식은 여기에서 지원되지 않습니다.\",\n checksum_mismatch: \"업로드 중 파일이 변경되었습니다. 다시 시도해 주세요.\",\n rate_limited: \"업로드가 너무 많습니다. {seconds}초 후에 다시 시도해 주세요.\",\n unavailable: \"미디어 저장소를 사용할 수 없습니다. 잠시 후 다시 시도하세요.\",\n upgrade_required: \"이 항목은 업그레이드 중입니다. 잠시 후 다시 시도하세요.\",\n internal_error: \"서버에서 문제가 발생했습니다. 다시 시도하세요.\",\n allowedTypes: \"{allowed} 형식을 사용하세요.\",\n tooLargeBy: \"이 파일은 {size}입니다. 제한은 {max}입니다.\",\n image_too_small: \"자른 이미지의 너비는 {width}px입니다. 최소 {min}px이어야 합니다. 더 넓은 영역을 선택하거나 더 큰 이미지를 사용하세요.\",\n image_too_large: \"이 이미지는 {width}×{height}px입니다. 이미지는 최대 {megapixels}메가픽셀까지 가능합니다.\",\n image_unreadable: \"이 파일은 올바른 {format} 이미지가 아닙니다.\",\n render_timeout: \"서버에서 아직 처리 중입니다. 준비되면 표시됩니다. 잠시 후 다시 확인하세요.\",\n animation_not_allowed: \"여기에는 움직이는 이미지를 사용할 수 없습니다. 정지 이미지를 업로드하세요.\",\n animation_unsupported: \"움직이는 {format} 이미지는 지원되지 않습니다. 움직이는 WebP 또는 GIF를 사용하세요.\",\n animationFrames: \"애니메이션은 최대 {maxFrames}프레임까지 가능합니다. 이 이미지는 {frames}프레임입니다.\",\n animationSeconds: \"애니메이션은 최대 {maxSeconds}초까지 가능합니다.\",\n animationTooLarge: \"이 애니메이션이 너무 큽니다: {width}×{height}px, {frames}프레임. 프레임 수나 크기를 줄이세요.\",\n too_many_files: \"이 항목에 허용된 파일 수가 이미 찼습니다. 먼저 일부를 삭제하세요.\",\n animation_too_long: \"이 애니메이션이 너무 깁니다.\",\n video_too_long: \"이 파일은 허용된 길이보다 깁니다.\",\n video_too_large: \"이 동영상의 프레임 크기가 허용 범위보다 큽니다.\",\n videoTooLongBy: \"이 파일의 길이는 {duration}초입니다. 여기서는 최대 {maxSeconds}초까지 가능합니다.\",\n videoTooLargeBy: \"이 동영상은 {width}×{height}px입니다. 동영상은 최대 {megapixels}메가픽셀까지 가능합니다.\",\n video_over_budget: \"이 동영상은 처리 시간이 너무 오래 걸립니다. 더 짧거나 작은 동영상을 사용하세요.\",\n video_aspect_unsupported: \"이 동영상은 가로나 세로로 너무 길어 여기에서 사용할 수 없습니다.\",\n videoAspectBy: \"이 동영상의 비율은 {shape}입니다. 여기에서는 {minAspect}에서 {maxAspect} 사이의 동영상만 사용할 수 있습니다.\",\n tooManyFilesBy: \"이 항목에는 이 파일을 최대 {maxFiles}개까지 넣을 수 있습니다. 먼저 일부를 삭제하세요.\",\n aborted: \"취소되었습니다.\",\n resume_mismatch: \"저장된 업로드가 다른 파일의 것입니다. 파일을 다시 선택하세요.\",\n moderation_rejected: \"검토 결과 거부되었습니다.\",\n comment_banned: \"여기에는 댓글을 달 수 없습니다.\",\n comments_closed: \"여기는 댓글이 닫혀 있습니다.\",\n comments_locked: \"댓글을 보고 쓰려면 잠금을 해제하세요.\",\n not_joinable: \"지금은 이 그룹에 가입할 수 없습니다.\",\n limit_reached: \"허용된 개수를 모두 사용했습니다.\",\n comment_too_long: \"댓글이 너무 깁니다.\",\n commentTooLongBy: \"댓글은 최대 {maxChars}자까지 쓸 수 있습니다.\",\n not_configured: \"이 사이트에서는 사용할 수 없는 기능입니다.\",\n tenant_mismatch: \"서버에서 문제가 발생했습니다. 다시 시도하세요.\",\n gone: \"이 콘텐츠는 더 이상 사용할 수 없습니다.\",\n },\n};\n"],"mappings":"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"}
|
package/dist/locales/zh.js
CHANGED
|
@@ -60,6 +60,7 @@ var a = {
|
|
|
60
60
|
adding: "正在添加…",
|
|
61
61
|
queued: "等待中",
|
|
62
62
|
uploaded: "已上传",
|
|
63
|
+
notAdded: "已上传,尚未添加",
|
|
63
64
|
processing: "处理中…",
|
|
64
65
|
processingPercent: "处理中 {percent}%",
|
|
65
66
|
edited: "已编辑",
|
|
@@ -164,8 +165,7 @@ var a = {
|
|
|
164
165
|
goTo: "转到第 {index} 项",
|
|
165
166
|
open: "打开第 {index} 项,共 {total} 项",
|
|
166
167
|
lightbox: "媒体查看器",
|
|
167
|
-
|
|
168
|
-
lockedMany: "还有 {count} 项已锁定",
|
|
168
|
+
locked: "其余内容已锁定",
|
|
169
169
|
processingImage: "正在处理图片…",
|
|
170
170
|
image: "图片 {index}",
|
|
171
171
|
video: "视频 {index}",
|
|
@@ -222,7 +222,19 @@ var a = {
|
|
|
222
222
|
unknown: "目前无法播放此视频。"
|
|
223
223
|
}
|
|
224
224
|
},
|
|
225
|
+
versionDownload: {
|
|
226
|
+
unavailable: "目前无法下载。",
|
|
227
|
+
availableIn_one: "{count} 天后可下载",
|
|
228
|
+
availableIn_other: "{count} 天后可下载",
|
|
229
|
+
label: "下载",
|
|
230
|
+
preparing: "正在准备下载…",
|
|
231
|
+
locked: "解锁后即可下载。",
|
|
232
|
+
limited: "已达到下载上限,请在 {minutes} 分钟后重试。",
|
|
233
|
+
failed: "无法开始下载,请重试。"
|
|
234
|
+
},
|
|
225
235
|
errors: {
|
|
236
|
+
download_unavailable: "目前无法下载。",
|
|
237
|
+
no_download: "暂时没有可下载的内容。",
|
|
226
238
|
generic: "我们这边出了问题,请重试。",
|
|
227
239
|
network: "连接已断开,请检查网络后重试。",
|
|
228
240
|
storage: "上传中断,请重试。",
|
package/dist/locales/zh.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zh.js","names":[],"sources":["../../src/locales/zh.ts"],"sourcesContent":["import type { ContentKitUiMessageBundle } from \"../i18n/messages.js\";\nimport { admin } from \"./admin/zh.js\";\nimport { social } from \"./social/zh.js\";\nimport { groups } from \"./groups/zh.js\";\nimport { discovery } from \"./discovery/zh.js\";\nimport { content } from \"./content/zh.js\";\n\nexport const zh: ContentKitUiMessageBundle = {\n ...social,\n ...admin,\n ...groups,\n ...discovery,\n ...content,\n common: {\n cancel: \"取消\",\n close: \"关闭\",\n save: \"保存\",\n saving: \"正在保存…\",\n retry: \"重试\",\n change: \"更换\",\n upload: \"上传\",\n editCrop: \"编辑裁剪\",\n remove: \"移除\",\n rename: \"重命名\",\n replace: \"替换\",\n },\n crop: {\n title: \"裁剪图片\",\n avatarTitle: \"裁剪头像\",\n coverTitle: \"裁剪封面\",\n description: \"拖动调整位置。滚动、双指缩放或使用滑块来缩放。\",\n area: \"裁剪区域。使用方向键移动图片,按 + 或 − 缩放,按 R 旋转。\",\n zoom: \"缩放\",\n zoomIn: \"放大\",\n zoomOut: \"缩小\",\n rotateLeft: \"向左旋转\",\n rotateRight: \"向右旋转\",\n reset: \"重置\",\n undersized: \"此裁剪宽 {width} 像素;在高分辨率屏幕上需要 {target} 像素或以上才清晰。\",\n tooSmall: \"此图片最宽 {width} 像素;至少需要 {min} 像素。请使用更大的图片。\",\n shape: \"比例\",\n original: \"原始比例\",\n preview: \"效果预览\",\n size: \"{width} × {height} 像素\",\n },\n sortable: {\n handle: \"调整 {name} 的顺序\",\n instructions: \"要调整顺序,请按空格键或回车键,用方向键移动,再按空格键或回车键放下。按 Esc 取消。\",\n pickedUp: \"已拿起 {name},位于第 {position} 位,共 {total} 项。\",\n over: \"{name} 将移到第 {position} 位,共 {total} 项。\",\n dropped: \"{name} 已放在第 {position} 位,共 {total} 项。\",\n droppedAway: \"{name} 已放下。\",\n canceled: \"已取消移动 {name}。\",\n },\n folder: {\n label: \"媒体\",\n drop: \"将文件拖放到此处,或点击选择\",\n add: \"添加文件\",\n commit: \"添加 {count} 个\",\n commitAgain: \"重新添加\",\n adding: \"正在添加…\",\n queued: \"等待中\",\n uploaded: \"已上传\",\n processing: \"处理中…\",\n processingPercent: \"处理中 {percent}%\",\n edited: \"已编辑\",\n failed: \"未处理\",\n failedVideo: \"无法播放\",\n crop: \"裁剪和旋转\",\n select: \"选择 {name}\",\n selected: \"已选择 {count} 个\",\n removeSelected: \"移除所选\",\n clearSelection: \"取消选择\",\n confirmRemove: \"要移除 {count} 个文件吗?此操作无法撤销。\",\n renameLabel: \"{name} 的新名称\",\n paused: \"上传已暂停\",\n resume: \"继续\",\n dismiss: \"关闭\",\n limitSize: \"{what}最大 {size}\",\n limitMax: \"最多 {max} 个\",\n limitAspect: \"视频比例为 {min} 至 {max}\",\n kinds: {\n image: \"图片\",\n video: \"视频\",\n audio: \"音频\",\n subtitle: \"字幕\",\n file: \"文件\",\n },\n },\n readiness: {\n processing: \"正在处理媒体\",\n processingHint: \"所有文件处理完成后将自动发布。\",\n failedOne: \"无法处理 {name}\",\n failedMany: \"无法处理 {count} 个文件:{names}\",\n failedHint: \"移除这些文件后将自动发布。\",\n },\n avatar: {\n label: \"头像\",\n empty: \"暂无头像\",\n hint: \"正方形图片,至少 {size} 像素。\",\n },\n cover: {\n label: \"封面图片\",\n empty: \"暂无封面\",\n hint: \"横向图片,至少 {width} × {height} 像素。\",\n drop: \"将图片拖放到此处\",\n },\n poster: {\n title: \"设置封面\",\n description: \"从视频中选取一帧,或上传一张图片。封面与视频比例相同。\",\n frame: \"视频画面\",\n upload: \"上传图片\",\n time: \"时间\",\n previousFrame: \"上一帧\",\n nextFrame: \"下一帧\",\n jumpTo: \"跳到 {time}\",\n useFrame: \"使用此帧\",\n crop: \"裁剪…\",\n cropTitle: \"裁剪封面\",\n auto: \"自动\",\n autoHint: \"在你选择之前,将使用自动选取的画面。\",\n drop: \"将图片拖到这里,或点击选择\",\n processing: \"视频仍在处理中。编码完成后即可选择封面。\",\n rendering: \"正在生成封面…\",\n },\n progress: {\n decoding: \"正在打开图片…\",\n hashing: \"正在准备…\",\n uploading: \"正在上传… {percent}%\",\n completing: \"正在完成上传…\",\n rendering: \"正在生成各尺寸…\",\n },\n encode: {\n processing: \"正在处理视频\",\n queued: \"等待处理\",\n queuedPosition: \"排队中 · 第 {position} 位\",\n stalled: \"处理已暂停,正在等待服务器…\",\n segments: \"片段 {done} / {total}\",\n higherQualities: \"更高画质\",\n remainingSeconds: \"剩余约 {seconds} 秒\",\n remainingMinutes: \"剩余约 {minutes} 分钟\",\n remainingHours: \"剩余约 {hours} 小时 {minutes} 分钟\",\n almostDone: \"即将完成\",\n estimating: \"正在估算…\",\n phase: {\n queued: \"排队中\",\n downloading: \"准备中\",\n probing: \"分析中\",\n encoding: \"编码中\",\n muxing: \"封装中\",\n uploading: \"保存中\",\n publishing: \"发布中\",\n images: \"正在生成封面\",\n },\n },\n gallery: {\n label: \"媒体\",\n view: \"布局\",\n carousel: \"轮播\",\n grid: \"网格\",\n counter: \"{current} / {total}\",\n slide: \"第 {current} 项,共 {total} 项\",\n previous: \"上一个\",\n next: \"下一个\",\n goTo: \"转到第 {index} 项\",\n open: \"打开第 {index} 项,共 {total} 项\",\n lightbox: \"媒体查看器\",\n lockedOne: \"还有 1 项已锁定\",\n lockedMany: \"还有 {count} 项已锁定\",\n processingImage: \"正在处理图片…\",\n image: \"图片 {index}\",\n video: \"视频 {index}\",\n audio: \"音频 {index}\",\n processingAudio: \"正在处理音频…\",\n download: \"下载\",\n failedAudio: \"无法处理此音频。\",\n failedImage: \"无法处理此图片。\",\n },\n player: {\n play: \"播放视频\",\n loading: \"正在加载视频…\",\n retry: \"重试\",\n code: \"代码 {code}\",\n quality: \"画质\",\n auto: \"自动\",\n autoCurrent: \"自动({quality})\",\n label: \"视频播放器\",\n resume: \"播放\",\n pause: \"暂停\",\n replay: \"重新播放\",\n seek: \"跳转\",\n time: \"{current} / {duration}\",\n seekBack: \"后退 {seconds} 秒\",\n seekForward: \"前进 {seconds} 秒\",\n seconds: \"{seconds} 秒\",\n mute: \"静音\",\n unmute: \"取消静音\",\n volume: \"音量\",\n settings: \"设置\",\n speed: \"播放速度\",\n normal: \"正常\",\n audio: \"音轨\",\n subtitles: \"字幕\",\n subtitlesOff: \"关闭\",\n forced: \"{label}(强制)\",\n track: \"轨道 {number}\",\n fullscreen: \"全屏\",\n exitFullscreen: \"退出全屏\",\n pip: \"画中画\",\n exitPip: \"退出画中画\",\n theater: \"影院模式\",\n miniPlayer: \"迷你播放器\",\n expand: \"展开\",\n close: \"关闭\",\n failed: \"无法处理此视频。\",\n errors: {\n network: \"无法连接到视频服务器。\",\n access: \"你已无权访问此视频。\",\n not_found: \"此视频不可用。\",\n rate_limited: \"请求过多,请稍后重试。\",\n unsupported: \"此浏览器无法播放此视频。\",\n stalled: \"播放已停滞。请检查网络连接后重试。\",\n unknown: \"目前无法播放此视频。\",\n },\n },\n errors: {\n generic: \"我们这边出了问题,请重试。\",\n network: \"连接已断开,请检查网络后重试。\",\n storage: \"上传中断,请重试。\",\n decode: \"无法将此文件作为图片打开。\",\n invalid_request: \"无法保存图片。\",\n unauthorized: \"会话已过期,请重新登录后上传。\",\n forbidden: \"你没有权限更改此图片。\",\n not_found: \"此项目已不存在。\",\n conflict: \"已在其他地方被更改,请刷新后重试。\",\n incomplete: \"上传未完成,请重试。\",\n not_uploaded: \"上传已过期,请重新选择图片。\",\n too_large: \"文件过大。\",\n quota_exceeded: \"已达到存储空间上限。\",\n type_not_allowed: \"此处不支持该文件类型。\",\n checksum_mismatch: \"上传过程中文件发生了变化,请重试。\",\n rate_limited: \"上传次数过多,请在 {seconds} 秒后重试。\",\n unavailable: \"媒体存储暂时不可用,请稍后重试。\",\n upgrade_required: \"此项目正在升级,请稍后重试。\",\n internal_error: \"我们这边出了问题,请重试。\",\n allowedTypes: \"请使用 {allowed}。\",\n tooLargeBy: \"此文件为 {size};上限为 {max}。\",\n image_too_small: \"裁剪后图片宽 {width} 像素;至少需要 {min} 像素。请选择更大的区域或使用更大的图片。\",\n image_too_large: \"此图片为 {width}×{height} 像素;图片最多 {megapixels} 百万像素。\",\n image_unreadable: \"此文件不是有效的 {format} 图片。\",\n render_timeout: \"服务器仍在处理,完成后会显示;请稍后再查看。\",\n animation_not_allowed: \"此处不允许动图。请上传静态图片。\",\n animation_unsupported: \"不支持动态 {format} 图片。请使用动态 WebP 或 GIF。\",\n animationFrames: \"动图最多 {maxFrames} 帧;此图有 {frames} 帧。\",\n animationSeconds: \"动图最长 {maxSeconds} 秒。\",\n animationTooLarge: \"此动图过大:{frames} 帧 {width}×{height} 像素。请减少帧数或缩小尺寸。\",\n too_many_files: \"此项目的文件数已达上限。请先删除一些。\",\n animation_too_long: \"此动图过长。\",\n video_too_long: \"此文件时长超出此处允许的范围。\",\n video_too_large: \"此视频的画面尺寸超出此处允许的范围。\",\n videoTooLongBy: \"此文件时长 {duration} 秒;此处上限为 {maxSeconds} 秒。\",\n videoTooLargeBy: \"此视频为 {width}×{height} 像素;视频最多 {megapixels} 百万像素。\",\n video_over_budget: \"处理此视频耗时过长。请使用更短或更小的视频。\",\n video_aspect_unsupported: \"此视频过宽或过高,无法在此使用。\",\n videoAspectBy: \"此视频的比例为 {shape};此处的视频比例须在 {minAspect} 至 {maxAspect} 之间。\",\n tooManyFilesBy: \"此项目最多可包含 {maxFiles} 个此类文件。请先移除一些。\",\n aborted: \"已取消。\",\n resume_mismatch: \"保存的上传属于另一个文件。请重新选择文件。\",\n moderation_rejected: \"已被审核拒绝。\",\n comment_banned: \"你无法在此评论。\",\n comments_closed: \"此处评论已关闭。\",\n comments_locked: \"解锁后即可查看和发表评论。\",\n not_joinable: \"目前无法加入此群组。\",\n limit_reached: \"已达到允许的上限。\",\n comment_too_long: \"评论太长了。\",\n commentTooLongBy: \"评论最多 {maxChars} 个字符。\",\n not_configured: \"此网站未提供该功能。\",\n tenant_mismatch: \"我们这边出了点问题,请重试。\",\n gone: \"此内容已不可用。\",\n },\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"zh.js","names":[],"sources":["../../src/locales/zh.ts"],"sourcesContent":["import type { ContentKitUiMessageBundle } from \"../i18n/messages.js\";\nimport { admin } from \"./admin/zh.js\";\nimport { social } from \"./social/zh.js\";\nimport { groups } from \"./groups/zh.js\";\nimport { discovery } from \"./discovery/zh.js\";\nimport { content } from \"./content/zh.js\";\n\nexport const zh: ContentKitUiMessageBundle = {\n ...social,\n ...admin,\n ...groups,\n ...discovery,\n ...content,\n common: {\n cancel: \"取消\",\n close: \"关闭\",\n save: \"保存\",\n saving: \"正在保存…\",\n retry: \"重试\",\n change: \"更换\",\n upload: \"上传\",\n editCrop: \"编辑裁剪\",\n remove: \"移除\",\n rename: \"重命名\",\n replace: \"替换\",\n },\n crop: {\n title: \"裁剪图片\",\n avatarTitle: \"裁剪头像\",\n coverTitle: \"裁剪封面\",\n description: \"拖动调整位置。滚动、双指缩放或使用滑块来缩放。\",\n area: \"裁剪区域。使用方向键移动图片,按 + 或 − 缩放,按 R 旋转。\",\n zoom: \"缩放\",\n zoomIn: \"放大\",\n zoomOut: \"缩小\",\n rotateLeft: \"向左旋转\",\n rotateRight: \"向右旋转\",\n reset: \"重置\",\n undersized: \"此裁剪宽 {width} 像素;在高分辨率屏幕上需要 {target} 像素或以上才清晰。\",\n tooSmall: \"此图片最宽 {width} 像素;至少需要 {min} 像素。请使用更大的图片。\",\n shape: \"比例\",\n original: \"原始比例\",\n preview: \"效果预览\",\n size: \"{width} × {height} 像素\",\n },\n sortable: {\n handle: \"调整 {name} 的顺序\",\n instructions: \"要调整顺序,请按空格键或回车键,用方向键移动,再按空格键或回车键放下。按 Esc 取消。\",\n pickedUp: \"已拿起 {name},位于第 {position} 位,共 {total} 项。\",\n over: \"{name} 将移到第 {position} 位,共 {total} 项。\",\n dropped: \"{name} 已放在第 {position} 位,共 {total} 项。\",\n droppedAway: \"{name} 已放下。\",\n canceled: \"已取消移动 {name}。\",\n },\n folder: {\n label: \"媒体\",\n drop: \"将文件拖放到此处,或点击选择\",\n add: \"添加文件\",\n commit: \"添加 {count} 个\",\n commitAgain: \"重新添加\",\n adding: \"正在添加…\",\n queued: \"等待中\",\n uploaded: \"已上传\",\n notAdded: \"已上传,尚未添加\",\n processing: \"处理中…\",\n processingPercent: \"处理中 {percent}%\",\n edited: \"已编辑\",\n failed: \"未处理\",\n failedVideo: \"无法播放\",\n crop: \"裁剪和旋转\",\n select: \"选择 {name}\",\n selected: \"已选择 {count} 个\",\n removeSelected: \"移除所选\",\n clearSelection: \"取消选择\",\n confirmRemove: \"要移除 {count} 个文件吗?此操作无法撤销。\",\n renameLabel: \"{name} 的新名称\",\n paused: \"上传已暂停\",\n resume: \"继续\",\n dismiss: \"关闭\",\n limitSize: \"{what}最大 {size}\",\n limitMax: \"最多 {max} 个\",\n limitAspect: \"视频比例为 {min} 至 {max}\",\n kinds: {\n image: \"图片\",\n video: \"视频\",\n audio: \"音频\",\n subtitle: \"字幕\",\n file: \"文件\",\n },\n },\n readiness: {\n processing: \"正在处理媒体\",\n processingHint: \"所有文件处理完成后将自动发布。\",\n failedOne: \"无法处理 {name}\",\n failedMany: \"无法处理 {count} 个文件:{names}\",\n failedHint: \"移除这些文件后将自动发布。\",\n },\n avatar: {\n label: \"头像\",\n empty: \"暂无头像\",\n hint: \"正方形图片,至少 {size} 像素。\",\n },\n cover: {\n label: \"封面图片\",\n empty: \"暂无封面\",\n hint: \"横向图片,至少 {width} × {height} 像素。\",\n drop: \"将图片拖放到此处\",\n },\n poster: {\n title: \"设置封面\",\n description: \"从视频中选取一帧,或上传一张图片。封面与视频比例相同。\",\n frame: \"视频画面\",\n upload: \"上传图片\",\n time: \"时间\",\n previousFrame: \"上一帧\",\n nextFrame: \"下一帧\",\n jumpTo: \"跳到 {time}\",\n useFrame: \"使用此帧\",\n crop: \"裁剪…\",\n cropTitle: \"裁剪封面\",\n auto: \"自动\",\n autoHint: \"在你选择之前,将使用自动选取的画面。\",\n drop: \"将图片拖到这里,或点击选择\",\n processing: \"视频仍在处理中。编码完成后即可选择封面。\",\n rendering: \"正在生成封面…\",\n },\n progress: {\n decoding: \"正在打开图片…\",\n hashing: \"正在准备…\",\n uploading: \"正在上传… {percent}%\",\n completing: \"正在完成上传…\",\n rendering: \"正在生成各尺寸…\",\n },\n encode: {\n processing: \"正在处理视频\",\n queued: \"等待处理\",\n queuedPosition: \"排队中 · 第 {position} 位\",\n stalled: \"处理已暂停,正在等待服务器…\",\n segments: \"片段 {done} / {total}\",\n higherQualities: \"更高画质\",\n remainingSeconds: \"剩余约 {seconds} 秒\",\n remainingMinutes: \"剩余约 {minutes} 分钟\",\n remainingHours: \"剩余约 {hours} 小时 {minutes} 分钟\",\n almostDone: \"即将完成\",\n estimating: \"正在估算…\",\n phase: {\n queued: \"排队中\",\n downloading: \"准备中\",\n probing: \"分析中\",\n encoding: \"编码中\",\n muxing: \"封装中\",\n uploading: \"保存中\",\n publishing: \"发布中\",\n images: \"正在生成封面\",\n },\n },\n gallery: {\n label: \"媒体\",\n view: \"布局\",\n carousel: \"轮播\",\n grid: \"网格\",\n counter: \"{current} / {total}\",\n slide: \"第 {current} 项,共 {total} 项\",\n previous: \"上一个\",\n next: \"下一个\",\n goTo: \"转到第 {index} 项\",\n open: \"打开第 {index} 项,共 {total} 项\",\n lightbox: \"媒体查看器\",\n locked: \"其余内容已锁定\",\n processingImage: \"正在处理图片…\",\n image: \"图片 {index}\",\n video: \"视频 {index}\",\n audio: \"音频 {index}\",\n processingAudio: \"正在处理音频…\",\n download: \"下载\",\n failedAudio: \"无法处理此音频。\",\n failedImage: \"无法处理此图片。\",\n },\n player: {\n play: \"播放视频\",\n loading: \"正在加载视频…\",\n retry: \"重试\",\n code: \"代码 {code}\",\n quality: \"画质\",\n auto: \"自动\",\n autoCurrent: \"自动({quality})\",\n label: \"视频播放器\",\n resume: \"播放\",\n pause: \"暂停\",\n replay: \"重新播放\",\n seek: \"跳转\",\n time: \"{current} / {duration}\",\n seekBack: \"后退 {seconds} 秒\",\n seekForward: \"前进 {seconds} 秒\",\n seconds: \"{seconds} 秒\",\n mute: \"静音\",\n unmute: \"取消静音\",\n volume: \"音量\",\n settings: \"设置\",\n speed: \"播放速度\",\n normal: \"正常\",\n audio: \"音轨\",\n subtitles: \"字幕\",\n subtitlesOff: \"关闭\",\n forced: \"{label}(强制)\",\n track: \"轨道 {number}\",\n fullscreen: \"全屏\",\n exitFullscreen: \"退出全屏\",\n pip: \"画中画\",\n exitPip: \"退出画中画\",\n theater: \"影院模式\",\n miniPlayer: \"迷你播放器\",\n expand: \"展开\",\n close: \"关闭\",\n failed: \"无法处理此视频。\",\n errors: {\n network: \"无法连接到视频服务器。\",\n access: \"你已无权访问此视频。\",\n not_found: \"此视频不可用。\",\n rate_limited: \"请求过多,请稍后重试。\",\n unsupported: \"此浏览器无法播放此视频。\",\n stalled: \"播放已停滞。请检查网络连接后重试。\",\n unknown: \"目前无法播放此视频。\",\n },\n },\n versionDownload: {\n unavailable: \"目前无法下载。\",\n availableIn_one: \"{count} 天后可下载\",\n availableIn_other: \"{count} 天后可下载\",\n label: \"下载\",\n preparing: \"正在准备下载…\",\n locked: \"解锁后即可下载。\",\n limited: \"已达到下载上限,请在 {minutes} 分钟后重试。\",\n failed: \"无法开始下载,请重试。\",\n },\n errors: {\n download_unavailable: \"目前无法下载。\",\n no_download: \"暂时没有可下载的内容。\",\n generic: \"我们这边出了问题,请重试。\",\n network: \"连接已断开,请检查网络后重试。\",\n storage: \"上传中断,请重试。\",\n decode: \"无法将此文件作为图片打开。\",\n invalid_request: \"无法保存图片。\",\n unauthorized: \"会话已过期,请重新登录后上传。\",\n forbidden: \"你没有权限更改此图片。\",\n not_found: \"此项目已不存在。\",\n conflict: \"已在其他地方被更改,请刷新后重试。\",\n incomplete: \"上传未完成,请重试。\",\n not_uploaded: \"上传已过期,请重新选择图片。\",\n too_large: \"文件过大。\",\n quota_exceeded: \"已达到存储空间上限。\",\n type_not_allowed: \"此处不支持该文件类型。\",\n checksum_mismatch: \"上传过程中文件发生了变化,请重试。\",\n rate_limited: \"上传次数过多,请在 {seconds} 秒后重试。\",\n unavailable: \"媒体存储暂时不可用,请稍后重试。\",\n upgrade_required: \"此项目正在升级,请稍后重试。\",\n internal_error: \"我们这边出了问题,请重试。\",\n allowedTypes: \"请使用 {allowed}。\",\n tooLargeBy: \"此文件为 {size};上限为 {max}。\",\n image_too_small: \"裁剪后图片宽 {width} 像素;至少需要 {min} 像素。请选择更大的区域或使用更大的图片。\",\n image_too_large: \"此图片为 {width}×{height} 像素;图片最多 {megapixels} 百万像素。\",\n image_unreadable: \"此文件不是有效的 {format} 图片。\",\n render_timeout: \"服务器仍在处理,完成后会显示;请稍后再查看。\",\n animation_not_allowed: \"此处不允许动图。请上传静态图片。\",\n animation_unsupported: \"不支持动态 {format} 图片。请使用动态 WebP 或 GIF。\",\n animationFrames: \"动图最多 {maxFrames} 帧;此图有 {frames} 帧。\",\n animationSeconds: \"动图最长 {maxSeconds} 秒。\",\n animationTooLarge: \"此动图过大:{frames} 帧 {width}×{height} 像素。请减少帧数或缩小尺寸。\",\n too_many_files: \"此项目的文件数已达上限。请先删除一些。\",\n animation_too_long: \"此动图过长。\",\n video_too_long: \"此文件时长超出此处允许的范围。\",\n video_too_large: \"此视频的画面尺寸超出此处允许的范围。\",\n videoTooLongBy: \"此文件时长 {duration} 秒;此处上限为 {maxSeconds} 秒。\",\n videoTooLargeBy: \"此视频为 {width}×{height} 像素;视频最多 {megapixels} 百万像素。\",\n video_over_budget: \"处理此视频耗时过长。请使用更短或更小的视频。\",\n video_aspect_unsupported: \"此视频过宽或过高,无法在此使用。\",\n videoAspectBy: \"此视频的比例为 {shape};此处的视频比例须在 {minAspect} 至 {maxAspect} 之间。\",\n tooManyFilesBy: \"此项目最多可包含 {maxFiles} 个此类文件。请先移除一些。\",\n aborted: \"已取消。\",\n resume_mismatch: \"保存的上传属于另一个文件。请重新选择文件。\",\n moderation_rejected: \"已被审核拒绝。\",\n comment_banned: \"你无法在此评论。\",\n comments_closed: \"此处评论已关闭。\",\n comments_locked: \"解锁后即可查看和发表评论。\",\n not_joinable: \"目前无法加入此群组。\",\n limit_reached: \"已达到允许的上限。\",\n comment_too_long: \"评论太长了。\",\n commentTooLongBy: \"评论最多 {maxChars} 个字符。\",\n not_configured: \"此网站未提供该功能。\",\n tenant_mismatch: \"我们这边出了点问题,请重试。\",\n gone: \"此内容已不可用。\",\n },\n};\n"],"mappings":"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"}
|
package/dist/react/admin.js
CHANGED
|
@@ -2,10 +2,11 @@ import { toContentKitError as e } from "../client/errors.js";
|
|
|
2
2
|
import { useContentKitClient as t } from "./context.js";
|
|
3
3
|
import { keyOf as n, useContentScope as r, useResource as i } from "./use-resource.js";
|
|
4
4
|
import { createContentKitClient as a } from "../client/client.js";
|
|
5
|
-
import {
|
|
5
|
+
import { MOVED as o, subscribeHistory as s } from "./location.js";
|
|
6
|
+
import { useCallback as c, useMemo as l, useState as u, useSyncExternalStore as d } from "react";
|
|
6
7
|
//#region src/react/admin.ts
|
|
7
|
-
function
|
|
8
|
-
let i =
|
|
8
|
+
function f({ client: e, baseUrl: n, auth: r }) {
|
|
9
|
+
let i = l(() => e || n === void 0 ? null : a({
|
|
9
10
|
baseUrl: n,
|
|
10
11
|
fetch: r ? (e, t) => r.authFetch(e, t) : void 0,
|
|
11
12
|
token: r?.getAccessToken ? () => r.getAccessToken() : void 0
|
|
@@ -16,9 +17,7 @@ function u({ client: e, baseUrl: n, auth: r }) {
|
|
|
16
17
|
]);
|
|
17
18
|
return t(e ?? i);
|
|
18
19
|
}
|
|
19
|
-
var
|
|
20
|
-
removeEventListener("popstate", e), removeEventListener(d, e);
|
|
21
|
-
}), p = () => location.pathname + location.search, m = () => "";
|
|
20
|
+
var p = () => location.pathname + location.search, m = () => "";
|
|
22
21
|
function h(e = {}) {
|
|
23
22
|
let t = new URLSearchParams();
|
|
24
23
|
for (let [n, r] of Object.entries(e)) r != null && r !== "" && t.set(n, String(r));
|
|
@@ -26,31 +25,31 @@ function h(e = {}) {
|
|
|
26
25
|
return n ? `?${n}` : "";
|
|
27
26
|
}
|
|
28
27
|
function g(e, t) {
|
|
29
|
-
let n =
|
|
28
|
+
let n = d(t || e === void 0 ? _ : s, p, m), [r, i] = u({
|
|
30
29
|
view: "",
|
|
31
30
|
search: ""
|
|
32
|
-
}), a = e?.replace(/\/+$/, "") ?? "",
|
|
33
|
-
if (e === void 0 && !t) ({view:
|
|
31
|
+
}), a = e?.replace(/\/+$/, "") ?? "", f, g;
|
|
32
|
+
if (e === void 0 && !t) ({view: f, search: g} = r);
|
|
34
33
|
else {
|
|
35
34
|
let [e, r = ""] = v(t ? t.pathname + t.search : n, "?");
|
|
36
|
-
g = r ? `?${r}` : "",
|
|
35
|
+
g = r ? `?${r}` : "", f = e === a || e === `${a}/` ? "" : e.startsWith(`${a}/`) ? e.slice(a.length + 1).replace(/\/+$/, "") : "";
|
|
37
36
|
}
|
|
38
|
-
let y =
|
|
39
|
-
let
|
|
37
|
+
let y = c((n, r, s = {}) => {
|
|
38
|
+
let c = h(r);
|
|
40
39
|
if (e === void 0 && !t) return i({
|
|
41
40
|
view: n,
|
|
42
|
-
search:
|
|
41
|
+
search: c
|
|
43
42
|
});
|
|
44
|
-
let
|
|
45
|
-
if (t) return t.navigate(
|
|
46
|
-
window.history[
|
|
43
|
+
let l = (n ? `${a}/${n}` : a || "/") + c;
|
|
44
|
+
if (t) return t.navigate(l, s);
|
|
45
|
+
window.history[s.replace ? "replaceState" : "pushState"](null, "", l), dispatchEvent(new Event(o));
|
|
47
46
|
}, [
|
|
48
47
|
e,
|
|
49
48
|
a,
|
|
50
49
|
t
|
|
51
|
-
]), b =
|
|
50
|
+
]), b = l(() => new URLSearchParams(g), [g]);
|
|
52
51
|
return {
|
|
53
|
-
view:
|
|
52
|
+
view: f,
|
|
54
53
|
query: b,
|
|
55
54
|
go: y
|
|
56
55
|
};
|
|
@@ -76,7 +75,7 @@ var y = "00000000-0000-7000-8000-000000000000", b = {
|
|
|
76
75
|
})
|
|
77
76
|
};
|
|
78
77
|
function x(t, a = {}) {
|
|
79
|
-
let o =
|
|
78
|
+
let o = f(a), { store: s, scope: c } = r(o), l = i(s, n("access", c, ...t), { type: "access" }, async (n) => {
|
|
80
79
|
let r = {};
|
|
81
80
|
return await Promise.all(t.map(async (t) => {
|
|
82
81
|
try {
|
|
@@ -87,15 +86,15 @@ function x(t, a = {}) {
|
|
|
87
86
|
r[t] = !1;
|
|
88
87
|
}
|
|
89
88
|
})), r;
|
|
90
|
-
}),
|
|
89
|
+
}), u = Object.fromEntries(t.map((e) => [e, l.data?.[e] ?? !0]));
|
|
91
90
|
return {
|
|
92
91
|
loading: l.loading || !l.loaded,
|
|
93
|
-
allowed:
|
|
94
|
-
any: t.some((e) =>
|
|
92
|
+
allowed: u,
|
|
93
|
+
any: t.some((e) => u[e]),
|
|
95
94
|
error: l.error
|
|
96
95
|
};
|
|
97
96
|
}
|
|
98
97
|
//#endregion
|
|
99
|
-
export { g as useAdminLocation,
|
|
98
|
+
export { g as useAdminLocation, f as useFlowClient, x as useStaffAccess };
|
|
100
99
|
|
|
101
100
|
//# sourceMappingURL=admin.js.map
|
package/dist/react/admin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin.js","names":[],"sources":["../../src/react/admin.ts"],"sourcesContent":["import { useCallback, useMemo, useState, useSyncExternalStore } from \"react\";\nimport { createContentKitClient, type ContentKitClient } from \"../client/client.js\";\nimport { toContentKitError, type ContentKitError } from \"../client/errors.js\";\nimport type { TokenSource } from \"../client/http.js\";\nimport { useContentKitClient } from \"./context.js\";\nimport { keyOf, useContentScope, useResource } from \"./use-resource.js\";\n\n/** What a flow needs of the host's auth: an authenticating fetch, as auth-ui's AuthClient and IssuerClient have. */\nexport interface ContentKitAuth {\n authFetch: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;\n /** The access token, for HLS playlists on the API origin. */\n getAccessToken?: TokenSource;\n}\n\n/** How a flow reaches ContentKit: its own client, or baseUrl with the host's auth; else the provider's client. */\nexport interface FlowClientOptions {\n client?: ContentKitClient;\n baseUrl?: string;\n auth?: ContentKitAuth;\n}\n\n/** The flow's client: `client`, else one made from `baseUrl` and `auth`, else the provider's. */\nexport function useFlowClient({ client, baseUrl, auth }: FlowClientOptions): ContentKitClient {\n const made = useMemo(\n () =>\n client || baseUrl === undefined\n ? null\n : createContentKitClient({\n baseUrl,\n fetch: auth ? (input, init) => auth.authFetch(input, init) : undefined,\n token: auth?.getAccessToken ? () => auth.getAccessToken!() : undefined,\n }),\n [client, baseUrl, auth],\n );\n return useContentKitClient(client ?? made);\n}\n\n/** The host router as a flow sees it. With React Router: `{ pathname, search }` of useLocation() and useNavigate(). */\nexport interface AdminNavigation {\n pathname: string;\n search: string;\n navigate: (to: string, options?: { replace?: boolean }) => void;\n}\n\n/** A query for a view; empty values are left out. */\nexport type AdminQuery = Record<string, string | number | null | undefined>;\n\nexport interface AdminLocation {\n /** The view: the path under basePath, \"\" at its root. */\n view: string;\n query: URLSearchParams;\n go: (view: string, query?: AdminQuery, options?: { replace?: boolean }) => void;\n}\n\nconst MOVED = \"ckui:navigate\";\nconst subscribeHistory = (cb: () => void) => {\n addEventListener(\"popstate\", cb);\n addEventListener(MOVED, cb);\n return () => {\n removeEventListener(\"popstate\", cb);\n removeEventListener(MOVED, cb);\n };\n};\nconst historySnapshot = () => location.pathname + location.search;\nconst noHistory = () => \"\";\n\nfunction encode(query: AdminQuery = {}): string {\n const q = new URLSearchParams();\n for (const [k, v] of Object.entries(query)) if (v !== undefined && v !== null && v !== \"\") q.set(k, String(v));\n const s = q.toString();\n return s ? `?${s}` : \"\";\n}\n\n/**\n * A multi-view flow's place: under basePath in the host router (navigation),\n * else in the browser history; without basePath, in memory.\n */\nexport function useAdminLocation(basePath: string | undefined, navigation: AdminNavigation | undefined): AdminLocation {\n const history = useSyncExternalStore(navigation || basePath === undefined ? subscribeNone : subscribeHistory, historySnapshot, noHistory);\n const [memory, setMemory] = useState({ view: \"\", search: \"\" });\n const base = basePath?.replace(/\\/+$/, \"\") ?? \"\";\n let view: string;\n let search: string;\n if (basePath === undefined && !navigation) {\n ({ view, search } = memory);\n } else {\n const at = navigation ? navigation.pathname + navigation.search : history;\n const [pathname, query = \"\"] = splitOnce(at, \"?\");\n search = query ? `?${query}` : \"\";\n view = pathname === base || pathname === `${base}/` ? \"\" : pathname.startsWith(`${base}/`) ? pathname.slice(base.length + 1).replace(/\\/+$/, \"\") : \"\";\n }\n const go = useCallback(\n (to: string, query?: AdminQuery, o: { replace?: boolean } = {}) => {\n const qs = encode(query);\n if (basePath === undefined && !navigation) return setMemory({ view: to, search: qs });\n const url = (to ? `${base}/${to}` : base || \"/\") + qs;\n if (navigation) return navigation.navigate(url, o);\n window.history[o.replace ? \"replaceState\" : \"pushState\"](null, \"\", url);\n dispatchEvent(new Event(MOVED));\n },\n [basePath, base, navigation],\n );\n const query = useMemo(() => new URLSearchParams(search), [search]);\n return { view, query, go };\n}\n\nconst subscribeNone = () => () => {};\n\nfunction splitOnce(s: string, sep: string): [string, string?] {\n const i = s.indexOf(sep);\n return i < 0 ? [s] : [s.slice(0, i), s.slice(i + 1)];\n}\n\n/** A ContentKit staff area, each behind its own permission. */\nexport type StaffArea = \"comments\" | \"queue\" | \"bans\" | \"words\" | \"ips\" | \"polls\" | \"contents\" | \"groups\";\n\n// No group has this id: staff get not_found, others a refusal.\nconst NO_GROUP = \"00000000-0000-7000-8000-000000000000\";\n\nconst PROBES: Record<StaffArea, (c: ContentKitClient, signal: AbortSignal) => Promise<unknown>> = {\n comments: (c, signal) => c.comments.adminList({ limit: 1 }, signal),\n queue: (c, signal) => c.moderation.held({ kind: \"comment\", limit: 1 }, signal),\n bans: (c, signal) => c.bans.list(\"global\", { limit: 1 }, signal),\n words: (c, signal) => c.moderation.bannedWords(signal),\n ips: (c, signal) => c.moderation.ipBans(signal),\n polls: (c, signal) => c.polls.adminList({ limit: 1 }, signal),\n contents: (c, signal) => c.contents.manage({ limit: 1 }, signal),\n groups: (c, signal) =>\n c.groups.members(NO_GROUP, { limit: 1 }, signal).catch((e) => {\n if (toContentKitError(e).code !== \"not_found\") throw e;\n }),\n};\n\nexport interface StaffAccess<A extends StaffArea> {\n loading: boolean;\n /** Per area; true until known, and when the check itself failed (the area then shows its own error). */\n allowed: Record<A, boolean>;\n /** Some area is allowed. */\n any: boolean;\n error?: ContentKitError;\n}\n\n/**\n * What the caller may do in each area: one small read per area, refused\n * (401, 403) or not, shared by every hook asking on the client.\n */\nexport function useStaffAccess<A extends StaffArea>(areas: readonly A[], o: FlowClientOptions = {}): StaffAccess<A> {\n const client = useFlowClient(o);\n const { store, scope } = useContentScope(client);\n const r = useResource<Record<string, boolean>>(store, keyOf(\"access\", scope, ...areas), { type: \"access\" }, async (signal) => {\n const out: Record<string, boolean> = {};\n await Promise.all(\n areas.map(async (a) => {\n try {\n await PROBES[a](client, signal);\n out[a] = true;\n } catch (e) {\n const err = toContentKitError(e);\n if (err.code !== \"forbidden\" && err.code !== \"unauthorized\") throw err;\n out[a] = false;\n }\n }),\n );\n return out;\n });\n const allowed = Object.fromEntries(areas.map((a) => [a, r.data?.[a] ?? true])) as Record<A, boolean>;\n return { loading: r.loading || !r.loaded, allowed, any: areas.some((a) => allowed[a]), error: r.error };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"admin.js","names":[],"sources":["../../src/react/admin.ts"],"sourcesContent":["import { useCallback, useMemo, useState, useSyncExternalStore } from \"react\";\nimport { createContentKitClient, type ContentKitClient } from \"../client/client.js\";\nimport { toContentKitError, type ContentKitError } from \"../client/errors.js\";\nimport type { TokenSource } from \"../client/http.js\";\nimport { useContentKitClient } from \"./context.js\";\nimport { MOVED, subscribeHistory } from \"./location.js\";\nimport { keyOf, useContentScope, useResource } from \"./use-resource.js\";\n\n/** What a flow needs of the host's auth: an authenticating fetch, as auth-ui's AuthClient and IssuerClient have. */\nexport interface ContentKitAuth {\n authFetch: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;\n /** The access token, for HLS playlists on the API origin. */\n getAccessToken?: TokenSource;\n}\n\n/** How a flow reaches ContentKit: its own client, or baseUrl with the host's auth; else the provider's client. */\nexport interface FlowClientOptions {\n client?: ContentKitClient;\n baseUrl?: string;\n auth?: ContentKitAuth;\n}\n\n/** The flow's client: `client`, else one made from `baseUrl` and `auth`, else the provider's. */\nexport function useFlowClient({ client, baseUrl, auth }: FlowClientOptions): ContentKitClient {\n const made = useMemo(\n () =>\n client || baseUrl === undefined\n ? null\n : createContentKitClient({\n baseUrl,\n fetch: auth ? (input, init) => auth.authFetch(input, init) : undefined,\n token: auth?.getAccessToken ? () => auth.getAccessToken!() : undefined,\n }),\n [client, baseUrl, auth],\n );\n return useContentKitClient(client ?? made);\n}\n\n/** The host router as a flow sees it. With React Router: `{ pathname, search }` of useLocation() and useNavigate(). */\nexport interface AdminNavigation {\n pathname: string;\n search: string;\n navigate: (to: string, options?: { replace?: boolean }) => void;\n}\n\n/** A query for a view; empty values are left out. */\nexport type AdminQuery = Record<string, string | number | null | undefined>;\n\nexport interface AdminLocation {\n /** The view: the path under basePath, \"\" at its root. */\n view: string;\n query: URLSearchParams;\n go: (view: string, query?: AdminQuery, options?: { replace?: boolean }) => void;\n}\n\nconst historySnapshot = () => location.pathname + location.search;\nconst noHistory = () => \"\";\n\nfunction encode(query: AdminQuery = {}): string {\n const q = new URLSearchParams();\n for (const [k, v] of Object.entries(query)) if (v !== undefined && v !== null && v !== \"\") q.set(k, String(v));\n const s = q.toString();\n return s ? `?${s}` : \"\";\n}\n\n/**\n * A multi-view flow's place: under basePath in the host router (navigation),\n * else in the browser history; without basePath, in memory.\n */\nexport function useAdminLocation(basePath: string | undefined, navigation: AdminNavigation | undefined): AdminLocation {\n const history = useSyncExternalStore(navigation || basePath === undefined ? subscribeNone : subscribeHistory, historySnapshot, noHistory);\n const [memory, setMemory] = useState({ view: \"\", search: \"\" });\n const base = basePath?.replace(/\\/+$/, \"\") ?? \"\";\n let view: string;\n let search: string;\n if (basePath === undefined && !navigation) {\n ({ view, search } = memory);\n } else {\n const at = navigation ? navigation.pathname + navigation.search : history;\n const [pathname, query = \"\"] = splitOnce(at, \"?\");\n search = query ? `?${query}` : \"\";\n view = pathname === base || pathname === `${base}/` ? \"\" : pathname.startsWith(`${base}/`) ? pathname.slice(base.length + 1).replace(/\\/+$/, \"\") : \"\";\n }\n const go = useCallback(\n (to: string, query?: AdminQuery, o: { replace?: boolean } = {}) => {\n const qs = encode(query);\n if (basePath === undefined && !navigation) return setMemory({ view: to, search: qs });\n const url = (to ? `${base}/${to}` : base || \"/\") + qs;\n if (navigation) return navigation.navigate(url, o);\n window.history[o.replace ? \"replaceState\" : \"pushState\"](null, \"\", url);\n dispatchEvent(new Event(MOVED));\n },\n [basePath, base, navigation],\n );\n const query = useMemo(() => new URLSearchParams(search), [search]);\n return { view, query, go };\n}\n\nconst subscribeNone = () => () => {};\n\nfunction splitOnce(s: string, sep: string): [string, string?] {\n const i = s.indexOf(sep);\n return i < 0 ? [s] : [s.slice(0, i), s.slice(i + 1)];\n}\n\n/** A ContentKit staff area, each behind its own permission. */\nexport type StaffArea = \"comments\" | \"queue\" | \"bans\" | \"words\" | \"ips\" | \"polls\" | \"contents\" | \"groups\";\n\n// No group has this id: staff get not_found, others a refusal.\nconst NO_GROUP = \"00000000-0000-7000-8000-000000000000\";\n\nconst PROBES: Record<StaffArea, (c: ContentKitClient, signal: AbortSignal) => Promise<unknown>> = {\n comments: (c, signal) => c.comments.adminList({ limit: 1 }, signal),\n queue: (c, signal) => c.moderation.held({ kind: \"comment\", limit: 1 }, signal),\n bans: (c, signal) => c.bans.list(\"global\", { limit: 1 }, signal),\n words: (c, signal) => c.moderation.bannedWords(signal),\n ips: (c, signal) => c.moderation.ipBans(signal),\n polls: (c, signal) => c.polls.adminList({ limit: 1 }, signal),\n contents: (c, signal) => c.contents.manage({ limit: 1 }, signal),\n groups: (c, signal) =>\n c.groups.members(NO_GROUP, { limit: 1 }, signal).catch((e) => {\n if (toContentKitError(e).code !== \"not_found\") throw e;\n }),\n};\n\nexport interface StaffAccess<A extends StaffArea> {\n loading: boolean;\n /** Per area; true until known, and when the check itself failed (the area then shows its own error). */\n allowed: Record<A, boolean>;\n /** Some area is allowed. */\n any: boolean;\n error?: ContentKitError;\n}\n\n/**\n * What the caller may do in each area: one small read per area, refused\n * (401, 403) or not, shared by every hook asking on the client.\n */\nexport function useStaffAccess<A extends StaffArea>(areas: readonly A[], o: FlowClientOptions = {}): StaffAccess<A> {\n const client = useFlowClient(o);\n const { store, scope } = useContentScope(client);\n const r = useResource<Record<string, boolean>>(store, keyOf(\"access\", scope, ...areas), { type: \"access\" }, async (signal) => {\n const out: Record<string, boolean> = {};\n await Promise.all(\n areas.map(async (a) => {\n try {\n await PROBES[a](client, signal);\n out[a] = true;\n } catch (e) {\n const err = toContentKitError(e);\n if (err.code !== \"forbidden\" && err.code !== \"unauthorized\") throw err;\n out[a] = false;\n }\n }),\n );\n return out;\n });\n const allowed = Object.fromEntries(areas.map((a) => [a, r.data?.[a] ?? true])) as Record<A, boolean>;\n return { loading: r.loading || !r.loaded, allowed, any: areas.some((a) => allowed[a]), error: r.error };\n}\n"],"mappings":"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"}
|
|
@@ -15,7 +15,7 @@ export interface CanonicalContentOptions {
|
|
|
15
15
|
defaultLanguage?: string;
|
|
16
16
|
}
|
|
17
17
|
export interface CanonicalContent {
|
|
18
|
-
/** The canonical path in the page's language; undefined until link arrives. */
|
|
18
|
+
/** The canonical path in the page's language, never a version's (?v=); undefined until link arrives. */
|
|
19
19
|
path?: string;
|
|
20
20
|
/** Its absolute URL. */
|
|
21
21
|
url?: string;
|
|
@@ -24,8 +24,9 @@ export interface CanonicalContent {
|
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
26
|
* A content page's canonical URL once its data (link) arrives: replaces the
|
|
27
|
-
* address with the canonical path (
|
|
28
|
-
*
|
|
27
|
+
* address with the canonical path (language prefix, the reader's when the
|
|
28
|
+
* address has none; code spelling, merged code, current slug; the query, ?v=
|
|
29
|
+
* included, kept) through the provider's navigate (else history.replaceState), and keeps
|
|
29
30
|
* `<link rel=canonical>`, og:url, og:title, og:image and hreflang alternates
|
|
30
31
|
* (each language's own slug) in the head while mounted; unmounting removes
|
|
31
32
|
* the tags it set, server-rendered ones included. Needs the provider's `urls`.
|
package/dist/react/canonical.js
CHANGED
|
@@ -20,56 +20,57 @@ var s = (e, t, n) => ({
|
|
|
20
20
|
value: t
|
|
21
21
|
});
|
|
22
22
|
function c(c, l = {}) {
|
|
23
|
-
let u = t(), d = n(e)?.navigate,
|
|
24
|
-
content_kind:
|
|
25
|
-
code:
|
|
26
|
-
slug:
|
|
27
|
-
slugs: JSON.parse(
|
|
23
|
+
let u = t(), d = n(e), f = d?.navigate, p = d?.language, m = l.location ?? (typeof location > "u" ? "" : location.pathname + location.search + location.hash), h = c?.content_kind, g = c?.code, _ = c?.slug, v = JSON.stringify(c?.slugs ?? {}), y = l.languages?.join(","), b = i(() => h && g ? {
|
|
24
|
+
content_kind: h,
|
|
25
|
+
code: g,
|
|
26
|
+
slug: _ ?? "",
|
|
27
|
+
slugs: JSON.parse(v)
|
|
28
28
|
} : null, [
|
|
29
|
-
p,
|
|
30
|
-
m,
|
|
31
29
|
h,
|
|
32
|
-
g
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
30
|
+
g,
|
|
31
|
+
_,
|
|
32
|
+
v
|
|
33
|
+
]), x = i(() => {
|
|
34
|
+
if (!b) return { alternates: {} };
|
|
35
|
+
let e = u.origin ?? (typeof location > "u" ? void 0 : location.origin), t = m.includes("#") ? m.slice(m.indexOf("#")) : "", n = p && u.languages.includes(p) ? p : void 0, r = u.canonical(m, b, { language: n }), i = r?.path ?? u.path(b, { language: n }), a = e ? u.hreflang(b, {
|
|
36
36
|
origin: e,
|
|
37
|
-
languages:
|
|
37
|
+
languages: y?.split(","),
|
|
38
38
|
defaultLanguage: l.defaultLanguage
|
|
39
39
|
}) : {};
|
|
40
40
|
return {
|
|
41
|
-
path:
|
|
42
|
-
url: e ? e +
|
|
43
|
-
alternates:
|
|
44
|
-
redirect:
|
|
41
|
+
path: i,
|
|
42
|
+
url: e ? e + i : void 0,
|
|
43
|
+
alternates: a,
|
|
44
|
+
redirect: r?.redirect ? r.location + t : void 0
|
|
45
45
|
};
|
|
46
46
|
}, [
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
b,
|
|
48
|
+
m,
|
|
49
49
|
u,
|
|
50
|
-
|
|
50
|
+
p,
|
|
51
|
+
y,
|
|
51
52
|
l.defaultLanguage
|
|
52
|
-
]), { redirect:
|
|
53
|
+
]), { redirect: S } = x;
|
|
53
54
|
r(() => {
|
|
54
|
-
|
|
55
|
-
}, [
|
|
56
|
-
let { url:
|
|
55
|
+
S && (f ? f(S, { replace: !0 }) : history.replaceState(history.state, "", S));
|
|
56
|
+
}, [S, f]);
|
|
57
|
+
let { url: C, alternates: w } = x, { title: T, image: E } = l, D = JSON.stringify(w);
|
|
57
58
|
return r(() => {
|
|
58
|
-
if (!
|
|
59
|
-
let e = [s("canonical",
|
|
60
|
-
|
|
61
|
-
for (let [t, n] of Object.entries(JSON.parse(
|
|
59
|
+
if (!C || typeof document > "u") return;
|
|
60
|
+
let e = [s("canonical", C), a("og:url", C)];
|
|
61
|
+
T && e.push(a("og:title", T)), E && e.push(a("og:image", E));
|
|
62
|
+
for (let [t, n] of Object.entries(JSON.parse(D))) e.push(s("alternate", n, t));
|
|
62
63
|
let t = e.map((e) => o(document.head.querySelector(e.selector) ?? document.head.appendChild(e.create()), e.attr, e.value));
|
|
63
64
|
return () => t.forEach((e) => e.remove());
|
|
64
65
|
}, [
|
|
65
|
-
x,
|
|
66
66
|
C,
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
T,
|
|
68
|
+
E,
|
|
69
|
+
D
|
|
69
70
|
]), {
|
|
70
|
-
path:
|
|
71
|
-
url:
|
|
72
|
-
alternates:
|
|
71
|
+
path: x.path,
|
|
72
|
+
url: x.url,
|
|
73
|
+
alternates: x.alternates
|
|
73
74
|
};
|
|
74
75
|
}
|
|
75
76
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canonical.js","names":[],"sources":["../../src/react/canonical.ts"],"sourcesContent":["import { useContext, useEffect, useMemo } from \"react\";\nimport type { ContentLink } from \"../urls/index.js\";\nimport { ContentKitContext, useContentURLs } from \"./context.js\";\n\nexport interface CanonicalContentOptions {\n /** og:title. */\n title?: string;\n /** og:image, an absolute URL. */\n image?: string;\n /**\n * The current location (pathname, search, hash). Default\n * window.location; pass the router's so a navigation checks again.\n */\n location?: string;\n /** Languages the content exists in, for hreflang; default every configured language. */\n languages?: readonly string[];\n /** The language hreflang x-default points at. */\n defaultLanguage?: string;\n}\n\nexport interface CanonicalContent {\n /** The canonical path in the page's language; undefined until link arrives. */\n path?: string;\n /** Its absolute URL. */\n url?: string;\n /** hreflang alternates by language (and x-default). */\n alternates: Record<string, string>;\n}\n\ntype Tag = { selector: string; create: () => HTMLElement; attr: string; value: string };\n\nconst meta = (property: string, value: string): Tag => ({\n selector: `meta[property=\"${property}\"]`,\n create: () => withAttr(document.createElement(\"meta\"), \"property\", property),\n attr: \"content\",\n value,\n});\n\nfunction withAttr<E extends HTMLElement>(el: E, name: string, value: string): E {\n el.setAttribute(name, value);\n return el;\n}\n\nconst link = (rel: string, value: string, hreflang?: string): Tag => ({\n selector: hreflang ? `link[rel=\"${rel}\"][hreflang=\"${hreflang}\"]` : `link[rel=\"${rel}\"]:not([hreflang])`,\n create: () => {\n const el = withAttr(document.createElement(\"link\"), \"rel\", rel);\n if (hreflang) el.setAttribute(\"hreflang\", hreflang);\n return el;\n },\n attr: \"href\",\n value,\n});\n\n/**\n * A content page's canonical URL once its data (link) arrives: replaces the\n * address with the canonical path (code spelling, merged code, current slug
|
|
1
|
+
{"version":3,"file":"canonical.js","names":[],"sources":["../../src/react/canonical.ts"],"sourcesContent":["import { useContext, useEffect, useMemo } from \"react\";\nimport type { ContentLink } from \"../urls/index.js\";\nimport { ContentKitContext, useContentURLs } from \"./context.js\";\n\nexport interface CanonicalContentOptions {\n /** og:title. */\n title?: string;\n /** og:image, an absolute URL. */\n image?: string;\n /**\n * The current location (pathname, search, hash). Default\n * window.location; pass the router's so a navigation checks again.\n */\n location?: string;\n /** Languages the content exists in, for hreflang; default every configured language. */\n languages?: readonly string[];\n /** The language hreflang x-default points at. */\n defaultLanguage?: string;\n}\n\nexport interface CanonicalContent {\n /** The canonical path in the page's language, never a version's (?v=); undefined until link arrives. */\n path?: string;\n /** Its absolute URL. */\n url?: string;\n /** hreflang alternates by language (and x-default). */\n alternates: Record<string, string>;\n}\n\ntype Tag = { selector: string; create: () => HTMLElement; attr: string; value: string };\n\nconst meta = (property: string, value: string): Tag => ({\n selector: `meta[property=\"${property}\"]`,\n create: () => withAttr(document.createElement(\"meta\"), \"property\", property),\n attr: \"content\",\n value,\n});\n\nfunction withAttr<E extends HTMLElement>(el: E, name: string, value: string): E {\n el.setAttribute(name, value);\n return el;\n}\n\nconst link = (rel: string, value: string, hreflang?: string): Tag => ({\n selector: hreflang ? `link[rel=\"${rel}\"][hreflang=\"${hreflang}\"]` : `link[rel=\"${rel}\"]:not([hreflang])`,\n create: () => {\n const el = withAttr(document.createElement(\"link\"), \"rel\", rel);\n if (hreflang) el.setAttribute(\"hreflang\", hreflang);\n return el;\n },\n attr: \"href\",\n value,\n});\n\n/**\n * A content page's canonical URL once its data (link) arrives: replaces the\n * address with the canonical path (language prefix, the reader's when the\n * address has none; code spelling, merged code, current slug; the query, ?v=\n * included, kept) through the provider's navigate (else history.replaceState), and keeps\n * `<link rel=canonical>`, og:url, og:title, og:image and hreflang alternates\n * (each language's own slug) in the head while mounted; unmounting removes\n * the tags it set, server-rendered ones included. Needs the provider's `urls`.\n */\nexport function useCanonicalContent(content: ContentLink | null | undefined, o: CanonicalContentOptions = {}): CanonicalContent {\n const urls = useContentURLs();\n const ctx = useContext(ContentKitContext);\n const navigate = ctx?.navigate;\n const reader = ctx?.language;\n const at = o.location ?? (typeof location === \"undefined\" ? \"\" : location.pathname + location.search + location.hash);\n const kind = content?.content_kind;\n const code = content?.code;\n const slug = content?.slug;\n const slugs = JSON.stringify(content?.slugs ?? {});\n const languages = o.languages?.join(\",\");\n const lnk = useMemo(\n () => (kind && code ? ({ content_kind: kind, code, slug: slug ?? \"\", slugs: JSON.parse(slugs) as Record<string, string> } satisfies ContentLink) : null),\n [kind, code, slug, slugs],\n );\n\n const result = useMemo((): CanonicalContent & { redirect?: string } => {\n if (!lnk) return { alternates: {} };\n const origin = urls.origin ?? (typeof location === \"undefined\" ? undefined : location.origin);\n const hash = at.includes(\"#\") ? at.slice(at.indexOf(\"#\")) : \"\";\n const language = reader && urls.languages.includes(reader) ? reader : undefined;\n const c = urls.canonical(at, lnk, { language });\n const path = c?.path ?? urls.path(lnk, { language });\n const alternates = origin ? urls.hreflang(lnk, { origin, languages: languages?.split(\",\"), defaultLanguage: o.defaultLanguage }) : {};\n return { path, url: origin ? origin + path : undefined, alternates, redirect: c?.redirect ? c.location + hash : undefined };\n }, [lnk, at, urls, reader, languages, o.defaultLanguage]);\n\n const { redirect } = result;\n useEffect(() => {\n if (!redirect) return;\n if (navigate) navigate(redirect, { replace: true });\n else history.replaceState(history.state, \"\", redirect);\n }, [redirect, navigate]);\n\n const { url, alternates } = result;\n const { title, image } = o;\n const alternatesKey = JSON.stringify(alternates);\n useEffect(() => {\n if (!url || typeof document === \"undefined\") return;\n const tags: Tag[] = [link(\"canonical\", url), meta(\"og:url\", url)];\n if (title) tags.push(meta(\"og:title\", title));\n if (image) tags.push(meta(\"og:image\", image));\n for (const [lang, href] of Object.entries(JSON.parse(alternatesKey) as Record<string, string>)) tags.push(link(\"alternate\", href, lang));\n const set = tags.map((t) => withAttr(document.head.querySelector<HTMLElement>(t.selector) ?? document.head.appendChild(t.create()), t.attr, t.value));\n // The tags describe this page: leaving it removes them, server-rendered ones\n // included (restoring those would leave this page's values on the next).\n return () => set.forEach((el) => el.remove());\n }, [url, title, image, alternatesKey]);\n\n return { path: result.path, url: result.url, alternates: result.alternates };\n}\n"],"mappings":"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"}
|
package/dist/react/comments.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { BanScope, Decision, HeldKind, Reaction, Sort, Target } from '../client/
|
|
|
3
3
|
import { ContentKitError } from '../client/errors.js';
|
|
4
4
|
import { AdminComment, BanInput, BannedWord, BannedWordInput, Comment, CommentBan, CommentStanding, FeedItem, HeldItem, IPBan, IPBanInput, ReactionCounts } from '../client/generated/wire.js';
|
|
5
5
|
import { UseList } from './use-resource.js';
|
|
6
|
-
/** Counts after the caller's reaction changes from counts.mine to value. */
|
|
6
|
+
/** Counts after the caller's reaction changes from counts.mine to value; a hidden tally stays hidden. */
|
|
7
7
|
export declare function withReaction(counts: ReactionCounts, value: Reaction): ReactionCounts;
|
|
8
8
|
export interface UseCommentsOptions {
|
|
9
9
|
sort?: Sort;
|
package/dist/react/comments.js
CHANGED
|
@@ -2,9 +2,10 @@ import { keyOf as e, offsetPages as t, useContentScope as n, useList as r, useRe
|
|
|
2
2
|
import { useCallback as a } from "react";
|
|
3
3
|
//#region src/react/comments.ts
|
|
4
4
|
function o(e, t) {
|
|
5
|
+
let n = (e, t, n) => e === void 0 ? void 0 : e - +!!t + +!!n;
|
|
5
6
|
return {
|
|
6
|
-
likes: e.likes
|
|
7
|
-
dislikes: e.dislikes
|
|
7
|
+
likes: n(e.likes, e.mine === 1, t === 1),
|
|
8
|
+
dislikes: n(e.dislikes, e.mine === -1, t === -1),
|
|
8
9
|
mine: t
|
|
9
10
|
};
|
|
10
11
|
}
|