@dxos/plugin-youtube 0.8.3 → 0.8.4-main.bcb3aa67d6

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.
Files changed (129) hide show
  1. package/dist/lib/browser/blueprints/index.mjs +49 -8
  2. package/dist/lib/browser/blueprints/index.mjs.map +4 -4
  3. package/dist/lib/browser/{chunk-C26XKDK2.mjs → chunk-5N5SWF3I.mjs} +3 -3
  4. package/dist/lib/browser/chunk-GTIWG45H.mjs +157 -0
  5. package/dist/lib/browser/chunk-GTIWG45H.mjs.map +7 -0
  6. package/dist/lib/browser/{chunk-P67QEKBQ.mjs → chunk-SWWE4LUJ.mjs} +3 -5
  7. package/dist/lib/browser/{chunk-P67QEKBQ.mjs.map → chunk-SWWE4LUJ.mjs.map} +1 -1
  8. package/dist/lib/browser/{clear-synced-videos-EVMJIZPD.mjs → clear-synced-videos-PIKJZET3.mjs} +4 -5
  9. package/dist/lib/{node-esm/clear-synced-videos-5UCH6XHL.mjs.map → browser/clear-synced-videos-PIKJZET3.mjs.map} +1 -1
  10. package/dist/lib/browser/index.mjs +86 -81
  11. package/dist/lib/browser/index.mjs.map +4 -4
  12. package/dist/lib/browser/meta.json +1 -1
  13. package/dist/lib/browser/{sync-423Q4BDD.mjs → sync-II7O2LPG.mjs} +6 -7
  14. package/dist/lib/{node-esm/sync-CEF5DX2J.mjs.map → browser/sync-II7O2LPG.mjs.map} +1 -1
  15. package/dist/lib/browser/types/index.mjs +2 -4
  16. package/dist/lib/node-esm/blueprints/index.mjs +49 -8
  17. package/dist/lib/node-esm/blueprints/index.mjs.map +4 -4
  18. package/dist/lib/node-esm/{chunk-JM5SBBP5.mjs → chunk-BVKMXV2G.mjs} +3 -3
  19. package/dist/lib/node-esm/{chunk-JSGRZMG3.mjs → chunk-RL46XZ2D.mjs} +3 -5
  20. package/dist/lib/node-esm/{chunk-JSGRZMG3.mjs.map → chunk-RL46XZ2D.mjs.map} +1 -1
  21. package/dist/lib/node-esm/chunk-YOE54ALJ.mjs +158 -0
  22. package/dist/lib/node-esm/chunk-YOE54ALJ.mjs.map +7 -0
  23. package/dist/lib/node-esm/{clear-synced-videos-5UCH6XHL.mjs → clear-synced-videos-Q3MZO2CD.mjs} +4 -5
  24. package/dist/lib/node-esm/index.mjs +86 -81
  25. package/dist/lib/node-esm/index.mjs.map +4 -4
  26. package/dist/lib/node-esm/meta.json +1 -1
  27. package/dist/lib/node-esm/{sync-CEF5DX2J.mjs → sync-BEXQNNSH.mjs} +6 -7
  28. package/dist/lib/node-esm/types/index.mjs +2 -4
  29. package/dist/types/src/YouTubePlugin.d.ts.map +1 -1
  30. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
  31. package/dist/types/src/capabilities/blueprint-definition.d.ts.map +1 -0
  32. package/dist/types/src/capabilities/index.d.ts +5 -3
  33. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  34. package/dist/types/src/capabilities/migrations.d.ts +5 -0
  35. package/dist/types/src/capabilities/migrations.d.ts.map +1 -0
  36. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
  37. package/dist/types/src/containers/VideoArticle/VideoArticle.d.ts +2 -7
  38. package/dist/types/src/containers/VideoArticle/VideoArticle.d.ts.map +1 -1
  39. package/dist/types/src/containers/VideoCard/VideoCard.d.ts +2 -2
  40. package/dist/types/src/containers/VideoCard/VideoCard.d.ts.map +1 -1
  41. package/dist/types/src/operations/definitions.d.ts +6 -2
  42. package/dist/types/src/operations/definitions.d.ts.map +1 -1
  43. package/dist/types/src/translations.d.ts +38 -38
  44. package/dist/types/src/translations.d.ts.map +1 -1
  45. package/dist/types/src/types/Channel.d.ts +28 -3
  46. package/dist/types/src/types/Channel.d.ts.map +1 -1
  47. package/dist/types/src/types/Video.d.ts +22 -0
  48. package/dist/types/src/types/Video.d.ts.map +1 -1
  49. package/dist/types/tsconfig.tsbuildinfo +1 -1
  50. package/package.json +48 -40
  51. package/src/YouTubePlugin.tsx +11 -5
  52. package/src/blueprints/youtube.ts +1 -1
  53. package/src/capabilities/{app-graph-builder/app-graph-builder.ts → app-graph-builder.ts} +19 -22
  54. package/src/capabilities/{blueprint-definition/blueprint-definition.ts → blueprint-definition.ts} +1 -1
  55. package/src/capabilities/index.ts +7 -4
  56. package/src/capabilities/migrations.ts +35 -0
  57. package/src/capabilities/{react-surface/react-surface.tsx → react-surface.tsx} +4 -4
  58. package/src/containers/VideoArticle/VideoArticle.tsx +2 -7
  59. package/src/containers/VideoCard/VideoCard.tsx +2 -2
  60. package/src/translations.ts +38 -38
  61. package/src/types/Channel.ts +18 -1
  62. package/src/types/Video.ts +25 -1
  63. package/dist/lib/browser/ChannelArticle-CDQR4BBY.mjs +0 -90
  64. package/dist/lib/browser/ChannelArticle-CDQR4BBY.mjs.map +0 -7
  65. package/dist/lib/browser/ChannelSettings-ZYUNW3VS.mjs +0 -28
  66. package/dist/lib/browser/ChannelSettings-ZYUNW3VS.mjs.map +0 -7
  67. package/dist/lib/browser/VideoArticle-FC4A6E7B.mjs +0 -76
  68. package/dist/lib/browser/VideoArticle-FC4A6E7B.mjs.map +0 -7
  69. package/dist/lib/browser/VideoCard-CCPXDCB7.mjs +0 -64
  70. package/dist/lib/browser/VideoCard-CCPXDCB7.mjs.map +0 -7
  71. package/dist/lib/browser/app-graph-builder-MJY6A6SN.mjs +0 -195
  72. package/dist/lib/browser/app-graph-builder-MJY6A6SN.mjs.map +0 -7
  73. package/dist/lib/browser/blueprint-definition-FRYUYJ22.mjs +0 -22
  74. package/dist/lib/browser/blueprint-definition-FRYUYJ22.mjs.map +0 -7
  75. package/dist/lib/browser/chunk-DFRSBBSO.mjs +0 -21
  76. package/dist/lib/browser/chunk-DFRSBBSO.mjs.map +0 -7
  77. package/dist/lib/browser/chunk-GFRR4TTX.mjs +0 -72
  78. package/dist/lib/browser/chunk-GFRR4TTX.mjs.map +0 -7
  79. package/dist/lib/browser/chunk-MUE22YUM.mjs +0 -57
  80. package/dist/lib/browser/chunk-MUE22YUM.mjs.map +0 -7
  81. package/dist/lib/browser/chunk-YMDT37TA.mjs +0 -62
  82. package/dist/lib/browser/chunk-YMDT37TA.mjs.map +0 -7
  83. package/dist/lib/browser/chunk-Z3DGTMKC.mjs +0 -8
  84. package/dist/lib/browser/chunk-Z3DGTMKC.mjs.map +0 -7
  85. package/dist/lib/browser/react-surface-EDA5VYDC.mjs +0 -77
  86. package/dist/lib/browser/react-surface-EDA5VYDC.mjs.map +0 -7
  87. package/dist/lib/node-esm/ChannelArticle-GQ64BO7V.mjs +0 -91
  88. package/dist/lib/node-esm/ChannelArticle-GQ64BO7V.mjs.map +0 -7
  89. package/dist/lib/node-esm/ChannelSettings-DM2HWNKO.mjs +0 -29
  90. package/dist/lib/node-esm/ChannelSettings-DM2HWNKO.mjs.map +0 -7
  91. package/dist/lib/node-esm/VideoArticle-WLTWZO3K.mjs +0 -77
  92. package/dist/lib/node-esm/VideoArticle-WLTWZO3K.mjs.map +0 -7
  93. package/dist/lib/node-esm/VideoCard-FOWQZK75.mjs +0 -65
  94. package/dist/lib/node-esm/VideoCard-FOWQZK75.mjs.map +0 -7
  95. package/dist/lib/node-esm/app-graph-builder-IU5TBAXN.mjs +0 -196
  96. package/dist/lib/node-esm/app-graph-builder-IU5TBAXN.mjs.map +0 -7
  97. package/dist/lib/node-esm/blueprint-definition-W264MZ3D.mjs +0 -23
  98. package/dist/lib/node-esm/blueprint-definition-W264MZ3D.mjs.map +0 -7
  99. package/dist/lib/node-esm/chunk-5KNC2JMP.mjs +0 -58
  100. package/dist/lib/node-esm/chunk-5KNC2JMP.mjs.map +0 -7
  101. package/dist/lib/node-esm/chunk-6BUJ2DQX.mjs +0 -73
  102. package/dist/lib/node-esm/chunk-6BUJ2DQX.mjs.map +0 -7
  103. package/dist/lib/node-esm/chunk-CX6MV3QM.mjs +0 -23
  104. package/dist/lib/node-esm/chunk-CX6MV3QM.mjs.map +0 -7
  105. package/dist/lib/node-esm/chunk-CZSLL3XQ.mjs +0 -63
  106. package/dist/lib/node-esm/chunk-CZSLL3XQ.mjs.map +0 -7
  107. package/dist/lib/node-esm/chunk-M4S6BE47.mjs +0 -10
  108. package/dist/lib/node-esm/chunk-M4S6BE47.mjs.map +0 -7
  109. package/dist/lib/node-esm/react-surface-5DJAQPHJ.mjs +0 -78
  110. package/dist/lib/node-esm/react-surface-5DJAQPHJ.mjs.map +0 -7
  111. package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts.map +0 -1
  112. package/dist/types/src/capabilities/app-graph-builder/index.d.ts +0 -3
  113. package/dist/types/src/capabilities/app-graph-builder/index.d.ts.map +0 -1
  114. package/dist/types/src/capabilities/blueprint-definition/blueprint-definition.d.ts.map +0 -1
  115. package/dist/types/src/capabilities/blueprint-definition/index.d.ts +0 -3
  116. package/dist/types/src/capabilities/blueprint-definition/index.d.ts.map +0 -1
  117. package/dist/types/src/capabilities/react-surface/index.d.ts +0 -3
  118. package/dist/types/src/capabilities/react-surface/index.d.ts.map +0 -1
  119. package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +0 -1
  120. package/src/capabilities/app-graph-builder/index.ts +0 -7
  121. package/src/capabilities/blueprint-definition/index.ts +0 -7
  122. package/src/capabilities/react-surface/index.ts +0 -7
  123. /package/dist/lib/browser/{chunk-C26XKDK2.mjs.map → chunk-5N5SWF3I.mjs.map} +0 -0
  124. /package/dist/lib/node-esm/{chunk-JM5SBBP5.mjs.map → chunk-BVKMXV2G.mjs.map} +0 -0
  125. /package/dist/lib/{browser/clear-synced-videos-EVMJIZPD.mjs.map → node-esm/clear-synced-videos-Q3MZO2CD.mjs.map} +0 -0
  126. /package/dist/lib/{browser/sync-423Q4BDD.mjs.map → node-esm/sync-BEXQNNSH.mjs.map} +0 -0
  127. /package/dist/types/src/capabilities/{app-graph-builder/app-graph-builder.d.ts → app-graph-builder.d.ts} +0 -0
  128. /package/dist/types/src/capabilities/{blueprint-definition/blueprint-definition.d.ts → blueprint-definition.d.ts} +0 -0
  129. /package/dist/types/src/capabilities/{react-surface/react-surface.d.ts → react-surface.d.ts} +0 -0
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/types/types.ts", "../../../src/types/Channel.ts"],
4
- "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\n/**\n * YouTube plugin operations (placeholder for future expansion).\n */\nexport const YouTubeOperation = {\n // Operations will be defined here when needed.\n} as const;\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport * as Schema from 'effect/Schema';\n\nimport { Annotation, Feed, Obj, Ref, Type } from '@dxos/echo';\nimport { FormInputAnnotation } from '@dxos/echo/internal';\nimport { FeedAnnotation } from '@dxos/schema';\nimport { AccessToken } from '@dxos/types';\n\n// @import-as-namespace\n\n/**\n * YouTubeChannel schema representing a YouTube channel to sync videos from.\n */\nexport const YouTubeChannel = Schema.Struct({\n /** Display name for the channel. */\n name: Schema.String.pipe(Schema.optional),\n /** YouTube channel ID (e.g., UC...). */\n channelId: Schema.String.pipe(Schema.optional),\n /** YouTube channel URL or handle. */\n channelUrl: Schema.String.pipe(Schema.optional),\n /** Feed containing YouTubeVideo objects. */\n feed: Ref.Ref(Feed.Feed).pipe(FormInputAnnotation.set(false)),\n /** Last sync timestamp. */\n lastSyncedAt: Schema.String.pipe(FormInputAnnotation.set(false), Schema.optional),\n /** Google API credentials for fetching channel data. */\n accessToken: Schema.optional(\n Ref.Ref(AccessToken.AccessToken).annotations({\n title: 'Account',\n description: 'Google account credentials for syncing this YouTube channel.',\n }),\n ),\n}).pipe(\n Type.object({\n typename: 'org.dxos.type.youtube-channel',\n version: '0.1.0',\n }),\n Annotation.IconAnnotation.set({\n icon: 'ph--youtube-logo--regular',\n hue: 'red',\n }),\n FeedAnnotation.set(true),\n);\n\nexport interface YouTubeChannel extends Schema.Schema.Type<typeof YouTubeChannel> {}\n\n/** Checks if a value is a YouTubeChannel object. */\nexport const instanceOf = (value: unknown): value is YouTubeChannel => Obj.instanceOf(YouTubeChannel, value);\n\nexport const CreateYouTubeChannelSchema = Schema.Struct({\n name: Schema.optional(Schema.String.annotations({ title: 'Name' })),\n channelUrl: Schema.optional(\n Schema.String.annotations({\n title: 'Channel URL',\n description: 'YouTube channel URL, handle (e.g., @channelname), or channel ID.',\n }),\n ),\n accessToken: Schema.optional(\n Ref.Ref(AccessToken.AccessToken).annotations({\n title: 'Account',\n description: 'Google account credentials for syncing this YouTube channel.',\n }),\n ),\n});\nexport interface CreateYouTubeChannelSchema extends Schema.Schema.Type<typeof CreateYouTubeChannelSchema> {}\n\ntype YouTubeChannelProps = Omit<Obj.MakeProps<typeof YouTubeChannel>, 'feed' | 'lastSyncedAt'>;\n\n/** Creates a YouTubeChannel object with a backing feed. */\nexport const make = (props: YouTubeChannelProps = {}) => {\n const feed = Feed.make();\n const channel = Obj.make(YouTubeChannel, {\n feed: Ref.make(feed),\n ...props,\n });\n Obj.setParent(feed, channel);\n return channel;\n};\n"],
5
- "mappings": ";;;;;AAOO,IAAMA,mBAAmB,CAEhC;;;ACTA;;;;;;;AAIA,YAAYC,YAAY;AAExB,SAASC,YAAYC,MAAMC,KAAKC,KAAKC,YAAY;AACjD,SAASC,2BAA2B;AACpC,SAASC,sBAAsB;AAC/B,SAASC,mBAAmB;AAOrB,IAAMC,iBAAwBC,cAAO;;EAE1CC,MAAaC,cAAOC,KAAYC,eAAQ;;EAExCC,WAAkBH,cAAOC,KAAYC,eAAQ;;EAE7CE,YAAmBJ,cAAOC,KAAYC,eAAQ;;EAE9CG,MAAMC,IAAIA,IAAIC,KAAKA,IAAI,EAAEN,KAAKO,oBAAoBC,IAAI,KAAA,CAAA;;EAEtDC,cAAqBV,cAAOC,KAAKO,oBAAoBC,IAAI,KAAA,GAAeP,eAAQ;;EAEhFS,aAAoBT,gBAClBI,IAAIA,IAAIM,YAAYA,WAAW,EAAEC,YAAY;IAC3CC,OAAO;IACPC,aAAa;EACf,CAAA,CAAA;AAEJ,CAAA,EAAGd,KACDe,KAAKC,OAAO;EACVC,UAAU;EACVC,SAAS;AACX,CAAA,GACAC,WAAWC,eAAeZ,IAAI;EAC5Ba,MAAM;EACNC,KAAK;AACP,CAAA,GACAC,eAAef,IAAI,IAAA,CAAA;AAMd,IAAMgB,aAAa,CAACC,UAA4CC,IAAIF,WAAW5B,gBAAgB6B,KAAAA;AAE/F,IAAME,6BAAoC9B,cAAO;EACtDC,MAAaG,gBAAgBF,cAAOa,YAAY;IAAEC,OAAO;EAAO,CAAA,CAAA;EAChEV,YAAmBF,gBACVF,cAAOa,YAAY;IACxBC,OAAO;IACPC,aAAa;EACf,CAAA,CAAA;EAEFJ,aAAoBT,gBAClBI,IAAIA,IAAIM,YAAYA,WAAW,EAAEC,YAAY;IAC3CC,OAAO;IACPC,aAAa;EACf,CAAA,CAAA;AAEJ,CAAA;AAMO,IAAMc,OAAO,CAACC,QAA6B,CAAC,MAAC;AAClD,QAAMzB,OAAOE,KAAKsB,KAAI;AACtB,QAAME,UAAUJ,IAAIE,KAAKhC,gBAAgB;IACvCQ,MAAMC,IAAIuB,KAAKxB,IAAAA;IACf,GAAGyB;EACL,CAAA;AACAH,MAAIK,UAAU3B,MAAM0B,OAAAA;AACpB,SAAOA;AACT;",
6
- "names": ["YouTubeOperation", "Schema", "Annotation", "Feed", "Obj", "Ref", "Type", "FormInputAnnotation", "FeedAnnotation", "AccessToken", "YouTubeChannel", "Struct", "name", "String", "pipe", "optional", "channelId", "channelUrl", "feed", "Ref", "Feed", "FormInputAnnotation", "set", "lastSyncedAt", "accessToken", "AccessToken", "annotations", "title", "description", "Type", "object", "typename", "version", "Annotation", "IconAnnotation", "icon", "hue", "FeedAnnotation", "instanceOf", "value", "Obj", "CreateYouTubeChannelSchema", "make", "props", "channel", "setParent"]
7
- }
@@ -1,57 +0,0 @@
1
- import {
2
- ClearSyncedVideos,
3
- Sync
4
- } from "./chunk-P67QEKBQ.mjs";
5
-
6
- // src/blueprints/youtube.ts
7
- import { Blueprint, Template } from "@dxos/blueprints";
8
- import { trim } from "@dxos/util";
9
- var BLUEPRINT_KEY = "dxos.org/blueprint/youtube";
10
- var make = () => Blueprint.make({
11
- key: BLUEPRINT_KEY,
12
- name: "YouTube",
13
- tools: Blueprint.toolDefinitions({
14
- operations: [
15
- Sync,
16
- ClearSyncedVideos
17
- ],
18
- tools: []
19
- }),
20
- instructions: Template.make({
21
- source: trim`
22
- You manage YouTube channel subscriptions and video content.
23
-
24
- # Summary formatting:
25
- - Format summaries as markdown documents without extra comments.
26
- - Use markdown formatting for headings and bullet points.
27
- - Format video summaries as lists with key points.
28
-
29
- # References
30
- - Use references to objects in the form of:
31
- @dxn:queue:data:B6INSIBY3CBEF4M5VZRYBCMAHQMPYK5AJ:01K24XMVHSZHS97SG1VTVQDM5Z:01K24XPK464FSCKVQJAB2H662M
32
- - References are rendered as rich content in the response to the user.
33
-
34
- # Video Analysis
35
- When analyzing videos:
36
- - Summarize the key topics and themes.
37
- - Extract important quotes or statements.
38
- - Identify action items or recommendations.
39
- - Note any timestamps for important sections.
40
-
41
- # Transcript Usage
42
- - Videos may include transcripts that can be used for deeper analysis.
43
- - When summarizing content, reference the transcript for accuracy.
44
- - Transcripts include timestamps that can help locate specific content.
45
- `
46
- })
47
- });
48
- var blueprint = {
49
- key: BLUEPRINT_KEY,
50
- make
51
- };
52
- var youtube_default = blueprint;
53
-
54
- export {
55
- youtube_default
56
- };
57
- //# sourceMappingURL=chunk-MUE22YUM.mjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/blueprints/youtube.ts"],
4
- "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { type AppCapabilities } from '@dxos/app-toolkit';\nimport { Blueprint, Template } from '@dxos/blueprints';\nimport { trim } from '@dxos/util';\n\nimport { ClearSyncedVideos, Sync } from '../operations';\n\nconst BLUEPRINT_KEY = 'dxos.org/blueprint/youtube';\n\nconst make = () =>\n Blueprint.make({\n key: BLUEPRINT_KEY,\n name: 'YouTube',\n tools: Blueprint.toolDefinitions({ operations: [Sync, ClearSyncedVideos], tools: [] }),\n instructions: Template.make({\n source: trim`\n You manage YouTube channel subscriptions and video content.\n\n # Summary formatting:\n - Format summaries as markdown documents without extra comments.\n - Use markdown formatting for headings and bullet points.\n - Format video summaries as lists with key points.\n\n # References\n - Use references to objects in the form of:\n @dxn:queue:data:B6INSIBY3CBEF4M5VZRYBCMAHQMPYK5AJ:01K24XMVHSZHS97SG1VTVQDM5Z:01K24XPK464FSCKVQJAB2H662M\n - References are rendered as rich content in the response to the user.\n\n # Video Analysis\n When analyzing videos:\n - Summarize the key topics and themes.\n - Extract important quotes or statements.\n - Identify action items or recommendations.\n - Note any timestamps for important sections.\n\n # Transcript Usage\n - Videos may include transcripts that can be used for deeper analysis.\n - When summarizing content, reference the transcript for accuracy.\n - Transcripts include timestamps that can help locate specific content.\n `,\n }),\n });\n\nconst blueprint: AppCapabilities.BlueprintDefinition = {\n key: BLUEPRINT_KEY,\n make,\n};\n\nexport default blueprint;\n"],
5
- "mappings": ";;;;;;AAKA,SAASA,WAAWC,gBAAgB;AACpC,SAASC,YAAY;AAIrB,IAAMC,gBAAgB;AAEtB,IAAMC,OAAO,MACXC,UAAUD,KAAK;EACbE,KAAKH;EACLI,MAAM;EACNC,OAAOH,UAAUI,gBAAgB;IAAEC,YAAY;MAACC;MAAMC;;IAAoBJ,OAAO,CAAA;EAAG,CAAA;EACpFK,cAAcC,SAASV,KAAK;IAC1BW,QAAQC;;;;;;;;;;;;;;;;;;;;;;;;;EAyBV,CAAA;AACF,CAAA;AAEF,IAAMC,YAAiD;EACrDX,KAAKH;EACLC;AACF;AAEA,IAAA,kBAAea;",
6
- "names": ["Blueprint", "Template", "trim", "BLUEPRINT_KEY", "make", "Blueprint", "key", "name", "tools", "toolDefinitions", "operations", "Sync", "ClearSyncedVideos", "instructions", "Template", "source", "trim", "blueprint"]
7
- }
@@ -1,62 +0,0 @@
1
- import {
2
- __export
3
- } from "./chunk-J5LGTIGS.mjs";
4
-
5
- // src/types/Video.ts
6
- var Video_exports = {};
7
- __export(Video_exports, {
8
- TranscriptSegment: () => TranscriptSegment,
9
- YouTubeVideo: () => YouTubeVideo,
10
- instanceOf: () => instanceOf
11
- });
12
- import * as Schema from "effect/Schema";
13
- import { Annotation, Obj, Type } from "@dxos/echo";
14
- var TranscriptSegment = Schema.Struct({
15
- /** Transcript text. */
16
- text: Schema.String,
17
- /** Start time in seconds. */
18
- offset: Schema.Number,
19
- /** Duration in seconds. */
20
- duration: Schema.Number
21
- });
22
- var YouTubeVideo = Schema.Struct({
23
- /** Video title. */
24
- title: Schema.String,
25
- /** YouTube video ID. */
26
- videoId: Schema.String,
27
- /** Video description. */
28
- description: Schema.String.pipe(Schema.optional),
29
- /** Video URL. */
30
- url: Schema.String,
31
- /** Thumbnail URL. */
32
- thumbnailUrl: Schema.String.pipe(Schema.optional),
33
- /** Channel name. */
34
- channelTitle: Schema.String.pipe(Schema.optional),
35
- /** Published date as ISO string. */
36
- publishedAt: Schema.String,
37
- /** Video duration in ISO 8601 format (e.g., PT1H30M15S). */
38
- duration: Schema.String.pipe(Schema.optional),
39
- /** View count. */
40
- viewCount: Schema.Number.pipe(Schema.optional),
41
- /** Like count. */
42
- likeCount: Schema.Number.pipe(Schema.optional),
43
- /** Full transcript text. */
44
- transcript: Schema.String.pipe(Schema.optional),
45
- /** Transcript segments with timestamps. */
46
- transcriptSegments: Schema.Array(TranscriptSegment).pipe(Schema.optional),
47
- /** True when transcript text was successfully loaded; false when disabled or none available. */
48
- transcriptFetched: Schema.Boolean.pipe(Schema.optional)
49
- }).pipe(Type.object({
50
- typename: "org.dxos.type.youtube-video",
51
- version: "0.1.0"
52
- }), Annotation.IconAnnotation.set({
53
- icon: "ph--play--regular",
54
- hue: "red"
55
- }));
56
- var instanceOf = (value) => Obj.instanceOf(YouTubeVideo, value);
57
-
58
- export {
59
- YouTubeVideo,
60
- Video_exports
61
- };
62
- //# sourceMappingURL=chunk-YMDT37TA.mjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/types/Video.ts"],
4
- "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport * as Schema from 'effect/Schema';\n\nimport { Annotation, Obj, Type } from '@dxos/echo';\n\n/**\n * Transcript segment from a YouTube video.\n */\nexport const TranscriptSegment = Schema.Struct({\n /** Transcript text. */\n text: Schema.String,\n /** Start time in seconds. */\n offset: Schema.Number,\n /** Duration in seconds. */\n duration: Schema.Number,\n});\n\nexport type TranscriptSegment = Schema.Schema.Type<typeof TranscriptSegment>;\n\n/**\n * YouTubeVideo schema representing a video from a YouTube channel.\n */\nexport const YouTubeVideo = Schema.Struct({\n /** Video title. */\n title: Schema.String,\n /** YouTube video ID. */\n videoId: Schema.String,\n /** Video description. */\n description: Schema.String.pipe(Schema.optional),\n /** Video URL. */\n url: Schema.String,\n /** Thumbnail URL. */\n thumbnailUrl: Schema.String.pipe(Schema.optional),\n /** Channel name. */\n channelTitle: Schema.String.pipe(Schema.optional),\n /** Published date as ISO string. */\n publishedAt: Schema.String,\n /** Video duration in ISO 8601 format (e.g., PT1H30M15S). */\n duration: Schema.String.pipe(Schema.optional),\n /** View count. */\n viewCount: Schema.Number.pipe(Schema.optional),\n /** Like count. */\n likeCount: Schema.Number.pipe(Schema.optional),\n /** Full transcript text. */\n transcript: Schema.String.pipe(Schema.optional),\n /** Transcript segments with timestamps. */\n transcriptSegments: Schema.Array(TranscriptSegment).pipe(Schema.optional),\n /** True when transcript text was successfully loaded; false when disabled or none available. */\n transcriptFetched: Schema.Boolean.pipe(Schema.optional),\n}).pipe(\n Type.object({\n typename: 'org.dxos.type.youtube-video',\n version: '0.1.0',\n }),\n Annotation.IconAnnotation.set({\n icon: 'ph--play--regular',\n hue: 'red',\n }),\n);\n\nexport interface YouTubeVideo extends Schema.Schema.Type<typeof YouTubeVideo> {}\n\n/** Checks if a value is a YouTubeVideo object. */\nexport const instanceOf = (value: unknown): value is YouTubeVideo => Obj.instanceOf(YouTubeVideo, value);\n"],
5
- "mappings": ";;;;;AAAA;;;;;;AAIA,YAAYA,YAAY;AAExB,SAASC,YAAYC,KAAKC,YAAY;AAK/B,IAAMC,oBAA2BC,cAAO;;EAE7CC,MAAaC;;EAEbC,QAAeC;;EAEfC,UAAiBD;AACnB,CAAA;AAOO,IAAME,eAAsBN,cAAO;;EAExCO,OAAcL;;EAEdM,SAAgBN;;EAEhBO,aAAoBP,cAAOQ,KAAYC,eAAQ;;EAE/CC,KAAYV;;EAEZW,cAAqBX,cAAOQ,KAAYC,eAAQ;;EAEhDG,cAAqBZ,cAAOQ,KAAYC,eAAQ;;EAEhDI,aAAoBb;;EAEpBG,UAAiBH,cAAOQ,KAAYC,eAAQ;;EAE5CK,WAAkBZ,cAAOM,KAAYC,eAAQ;;EAE7CM,WAAkBb,cAAOM,KAAYC,eAAQ;;EAE7CO,YAAmBhB,cAAOQ,KAAYC,eAAQ;;EAE9CQ,oBAA2BC,aAAMrB,iBAAAA,EAAmBW,KAAYC,eAAQ;;EAExEU,mBAA0BC,eAAQZ,KAAYC,eAAQ;AACxD,CAAA,EAAGD,KACDa,KAAKC,OAAO;EACVC,UAAU;EACVC,SAAS;AACX,CAAA,GACAC,WAAWC,eAAeC,IAAI;EAC5BC,MAAM;EACNC,KAAK;AACP,CAAA,CAAA;AAMK,IAAMC,aAAa,CAACC,UAA0CC,IAAIF,WAAW1B,cAAc2B,KAAAA;",
6
- "names": ["Schema", "Annotation", "Obj", "Type", "TranscriptSegment", "Struct", "text", "String", "offset", "Number", "duration", "YouTubeVideo", "title", "videoId", "description", "pipe", "optional", "url", "thumbnailUrl", "channelTitle", "publishedAt", "viewCount", "likeCount", "transcript", "transcriptSegments", "Array", "transcriptFetched", "Boolean", "Type", "object", "typename", "version", "Annotation", "IconAnnotation", "set", "icon", "hue", "instanceOf", "value", "Obj"]
7
- }
@@ -1,8 +0,0 @@
1
- // src/operations/index.ts
2
- import { OperationHandlerSet } from "@dxos/operation";
3
- var YouTubeHandlers = OperationHandlerSet.lazy(() => import("./clear-synced-videos-EVMJIZPD.mjs"), () => import("./sync-423Q4BDD.mjs"));
4
-
5
- export {
6
- YouTubeHandlers
7
- };
8
- //# sourceMappingURL=chunk-Z3DGTMKC.mjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/operations/index.ts"],
4
- "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { OperationHandlerSet } from '@dxos/operation';\n\nexport { YouTube } from './apis';\nexport * from './definitions';\n\nexport const YouTubeHandlers = OperationHandlerSet.lazy(\n () => import('./clear-synced-videos'),\n () => import('./sync'),\n);\n"],
5
- "mappings": ";AAIA,SAASA,2BAA2B;AAK7B,IAAMC,kBAAkBC,oBAAoBC,KACjD,MAAM,OAAO,oCAAA,GACb,MAAM,OAAO,qBAAA,CAAA;",
6
- "names": ["OperationHandlerSet", "YouTubeHandlers", "OperationHandlerSet", "lazy"]
7
- }
@@ -1,77 +0,0 @@
1
- import {
2
- meta
3
- } from "./chunk-DFRSBBSO.mjs";
4
- import {
5
- Channel_exports
6
- } from "./chunk-GFRR4TTX.mjs";
7
- import {
8
- Video_exports
9
- } from "./chunk-YMDT37TA.mjs";
10
- import "./chunk-J5LGTIGS.mjs";
11
-
12
- // src/capabilities/react-surface/react-surface.tsx
13
- import * as Effect from "effect/Effect";
14
- import React from "react";
15
- import { Capabilities, Capability } from "@dxos/app-framework";
16
- import { Surface } from "@dxos/app-framework/ui";
17
-
18
- // src/containers/index.ts
19
- import { lazy } from "react";
20
- var ChannelArticle = lazy(() => import("./ChannelArticle-CDQR4BBY.mjs"));
21
- var ChannelSettings = lazy(() => import("./ChannelSettings-ZYUNW3VS.mjs"));
22
- var VideoArticle = lazy(() => import("./VideoArticle-FC4A6E7B.mjs"));
23
- var VideoCard = lazy(() => import("./VideoCard-CCPXDCB7.mjs"));
24
-
25
- // src/capabilities/react-surface/react-surface.tsx
26
- var react_surface_default = Capability.makeModule(() => Effect.succeed(Capability.contributes(Capabilities.ReactSurface, [
27
- Surface.create({
28
- id: `${meta.id}.channel`,
29
- role: [
30
- "article"
31
- ],
32
- filter: (data) => Channel_exports.instanceOf(data.subject),
33
- component: ({ data }) => {
34
- return /* @__PURE__ */ React.createElement(ChannelArticle, {
35
- subject: data.subject,
36
- attendableId: data.attendableId
37
- });
38
- }
39
- }),
40
- Surface.create({
41
- id: `${meta.id}.video`,
42
- role: [
43
- "article",
44
- "section"
45
- ],
46
- filter: (data) => typeof data.attendableId === "string" && Video_exports.instanceOf(data.subject) && Channel_exports.instanceOf(data.companionTo),
47
- component: ({ data: { attendableId, companionTo, subject }, role }) => {
48
- return /* @__PURE__ */ React.createElement(VideoArticle, {
49
- role,
50
- subject,
51
- channel: companionTo,
52
- attendableId
53
- });
54
- }
55
- }),
56
- Surface.create({
57
- id: `${meta.id}.video-card`,
58
- role: "card--content",
59
- filter: (data) => Video_exports.instanceOf(data?.subject),
60
- component: ({ data: { subject }, role }) => /* @__PURE__ */ React.createElement(VideoCard, {
61
- subject,
62
- role
63
- })
64
- }),
65
- Surface.create({
66
- id: `${meta.id}.channel.companion.settings`,
67
- role: "object-settings",
68
- filter: (data) => Channel_exports.instanceOf(data.subject),
69
- component: ({ data }) => /* @__PURE__ */ React.createElement(ChannelSettings, {
70
- subject: data.subject
71
- })
72
- })
73
- ])));
74
- export {
75
- react_surface_default as default
76
- };
77
- //# sourceMappingURL=react-surface-EDA5VYDC.mjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/capabilities/react-surface/react-surface.tsx", "../../../src/containers/index.ts"],
4
- "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport React from 'react';\n\nimport { Capabilities, Capability } from '@dxos/app-framework';\nimport { Surface } from '@dxos/app-framework/ui';\n\nimport { ChannelArticle, ChannelSettings, VideoArticle, VideoCard } from '../../containers';\nimport { meta } from '../../meta';\nimport { Channel, Video } from '../../types';\n\nexport default Capability.makeModule(() =>\n Effect.succeed(\n Capability.contributes(Capabilities.ReactSurface, [\n Surface.create({\n id: `${meta.id}.channel`,\n role: ['article'],\n filter: (data): data is { attendableId?: string; subject: Channel.YouTubeChannel } =>\n Channel.instanceOf(data.subject),\n component: ({ data }) => {\n return <ChannelArticle subject={data.subject} attendableId={data.attendableId} />;\n },\n }),\n Surface.create({\n id: `${meta.id}.video`,\n role: ['article', 'section'],\n filter: (\n data,\n ): data is { attendableId: string; subject: Video.YouTubeVideo; companionTo: Channel.YouTubeChannel } =>\n typeof data.attendableId === 'string' &&\n Video.instanceOf(data.subject) &&\n Channel.instanceOf(data.companionTo),\n component: ({ data: { attendableId, companionTo, subject }, role }) => {\n return <VideoArticle role={role} subject={subject} channel={companionTo} attendableId={attendableId} />;\n },\n }),\n Surface.create({\n id: `${meta.id}.video-card`,\n role: 'card--content',\n filter: (data): data is { subject: Video.YouTubeVideo } => Video.instanceOf(data?.subject),\n component: ({ data: { subject }, role }) => <VideoCard subject={subject} role={role} />,\n }),\n Surface.create({\n id: `${meta.id}.channel.companion.settings`,\n role: 'object-settings',\n filter: (data): data is { subject: Channel.YouTubeChannel } => Channel.instanceOf(data.subject),\n component: ({ data }) => <ChannelSettings subject={data.subject} />,\n }),\n ]),\n ),\n);\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { type ComponentType, lazy, type LazyExoticComponent } from 'react';\n\nimport type { ChannelArticleProps } from './ChannelArticle/ChannelArticle';\nimport type { ChannelSettingsProps } from './ChannelSettings/ChannelSettings';\nimport type { VideoArticleProps } from './VideoArticle/VideoArticle';\nimport type { VideoCardProps } from './VideoCard/VideoCard';\n\nexport type { ChannelArticleProps, ChannelSettingsProps, VideoArticleProps, VideoCardProps };\n\nexport const ChannelArticle: LazyExoticComponent<ComponentType<ChannelArticleProps>> = lazy(\n () => import('./ChannelArticle'),\n);\n\nexport const ChannelSettings: LazyExoticComponent<ComponentType<ChannelSettingsProps>> = lazy(\n () => import('./ChannelSettings'),\n);\n\nexport const VideoArticle: LazyExoticComponent<ComponentType<VideoArticleProps>> = lazy(() => import('./VideoArticle'));\n\nexport const VideoCard: LazyExoticComponent<ComponentType<VideoCardProps>> = lazy(() => import('./VideoCard'));\n"],
5
- "mappings": ";;;;;;;;;;;;AAIA,YAAYA,YAAY;AACxB,OAAOC,WAAW;AAElB,SAASC,cAAcC,kBAAkB;AACzC,SAASC,eAAe;;;ACJxB,SAA6BC,YAAsC;AAS5D,IAAMC,iBAA0EC,KACrF,MAAM,OAAO,+BAAA,CAAA;AAGR,IAAMC,kBAA4ED,KACvF,MAAM,OAAO,gCAAA,CAAA;AAGR,IAAME,eAAsEF,KAAK,MAAM,OAAO,6BAAA,CAAA;AAE9F,IAAMG,YAAgEH,KAAK,MAAM,OAAO,0BAAA,CAAA;;;ADT/F,IAAA,wBAAeI,WAAWC,WAAW,MAC5BC,eACLF,WAAWG,YAAYC,aAAaC,cAAc;EAChDC,QAAQC,OAAO;IACbC,IAAI,GAAGC,KAAKD,EAAE;IACdE,MAAM;MAAC;;IACPC,QAAQ,CAACC,SACPC,gBAAQC,WAAWF,KAAKG,OAAO;IACjCC,WAAW,CAAC,EAAEJ,KAAI,MAAE;AAClB,aAAO,sBAAA,cAACK,gBAAAA;QAAeF,SAASH,KAAKG;QAASG,cAAcN,KAAKM;;IACnE;EACF,CAAA;EACAZ,QAAQC,OAAO;IACbC,IAAI,GAAGC,KAAKD,EAAE;IACdE,MAAM;MAAC;MAAW;;IAClBC,QAAQ,CACNC,SAEA,OAAOA,KAAKM,iBAAiB,YAC7BC,cAAML,WAAWF,KAAKG,OAAO,KAC7BF,gBAAQC,WAAWF,KAAKQ,WAAW;IACrCJ,WAAW,CAAC,EAAEJ,MAAM,EAAEM,cAAcE,aAAaL,QAAO,GAAIL,KAAI,MAAE;AAChE,aAAO,sBAAA,cAACW,cAAAA;QAAaX;QAAYK;QAAkBO,SAASF;QAAaF;;IAC3E;EACF,CAAA;EACAZ,QAAQC,OAAO;IACbC,IAAI,GAAGC,KAAKD,EAAE;IACdE,MAAM;IACNC,QAAQ,CAACC,SAAkDO,cAAML,WAAWF,MAAMG,OAAAA;IAClFC,WAAW,CAAC,EAAEJ,MAAM,EAAEG,QAAO,GAAIL,KAAI,MAAO,sBAAA,cAACa,WAAAA;MAAUR;MAAkBL;;EAC3E,CAAA;EACAJ,QAAQC,OAAO;IACbC,IAAI,GAAGC,KAAKD,EAAE;IACdE,MAAM;IACNC,QAAQ,CAACC,SAAsDC,gBAAQC,WAAWF,KAAKG,OAAO;IAC9FC,WAAW,CAAC,EAAEJ,KAAI,MAAO,sBAAA,cAACY,iBAAAA;MAAgBT,SAASH,KAAKG;;EAC1D,CAAA;CACD,CAAA,CAAA;",
6
- "names": ["Effect", "React", "Capabilities", "Capability", "Surface", "lazy", "ChannelArticle", "lazy", "ChannelSettings", "VideoArticle", "VideoCard", "Capability", "makeModule", "succeed", "contributes", "Capabilities", "ReactSurface", "Surface", "create", "id", "meta", "role", "filter", "data", "Channel", "instanceOf", "subject", "component", "ChannelArticle", "attendableId", "Video", "companionTo", "VideoArticle", "channel", "VideoCard", "ChannelSettings"]
7
- }
@@ -1,91 +0,0 @@
1
- import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
- import {
3
- YouTubeVideo
4
- } from "./chunk-CZSLL3XQ.mjs";
5
- import "./chunk-HSLMI22Q.mjs";
6
-
7
- // src/containers/ChannelArticle/ChannelArticle.tsx
8
- import React, { useMemo } from "react";
9
- import { Obj, Query } from "@dxos/echo";
10
- import { Filter, useObject, useQuery } from "@dxos/react-client/echo";
11
- import { Icon, Panel } from "@dxos/react-ui";
12
- var ChannelArticle = ({ subject: channel }) => {
13
- useObject(channel);
14
- const feed = channel.feed?.target;
15
- const db = Obj.getDatabase(channel);
16
- const videos = useQuery(db, feed ? Query.select(Filter.type(YouTubeVideo)).from(feed) : Query.select(Filter.nothing()));
17
- const sortedVideos = useMemo(() => [
18
- ...videos
19
- ].sort((videoA, videoB) => new Date(videoB.publishedAt).getTime() - new Date(videoA.publishedAt).getTime()), [
20
- videos
21
- ]);
22
- return /* @__PURE__ */ React.createElement(Panel.Root, null, /* @__PURE__ */ React.createElement(Panel.Content, {
23
- className: "overflow-auto"
24
- }, /* @__PURE__ */ React.createElement("div", {
25
- className: "flex flex-col gap-4 p-4"
26
- }, /* @__PURE__ */ React.createElement("div", {
27
- className: "flex items-center justify-between"
28
- }, /* @__PURE__ */ React.createElement("div", {
29
- className: "flex items-center gap-2"
30
- }, /* @__PURE__ */ React.createElement(Icon, {
31
- icon: "ph--youtube-logo--regular",
32
- size: 6
33
- }), /* @__PURE__ */ React.createElement("h2", {
34
- className: "text-lg font-semibold"
35
- }, channel.name ?? "YouTube Channel")), channel.lastSyncedAt && /* @__PURE__ */ React.createElement("span", {
36
- className: "text-xs text-description"
37
- }, "Last synced: ", new Date(channel.lastSyncedAt).toLocaleString())), channel.channelUrl && /* @__PURE__ */ React.createElement("div", {
38
- className: "text-sm text-description"
39
- }, /* @__PURE__ */ React.createElement("a", {
40
- href: channel.channelUrl.startsWith("http") ? channel.channelUrl : `https://www.youtube.com/@${channel.channelUrl}`,
41
- target: "_blank",
42
- rel: "noopener noreferrer",
43
- className: "hover:underline"
44
- }, channel.channelUrl)), /* @__PURE__ */ React.createElement("div", {
45
- className: "flex flex-col gap-2"
46
- }, /* @__PURE__ */ React.createElement("h3", {
47
- className: "text-md font-medium"
48
- }, "Videos (", sortedVideos.length, ")"), /* @__PURE__ */ React.createElement("div", {
49
- className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"
50
- }, sortedVideos.map((video) => /* @__PURE__ */ React.createElement("div", {
51
- key: video.videoId,
52
- className: "flex flex-col gap-2 p-2 rounded hover:bg-surface-hover"
53
- }, video.thumbnailUrl ? /* @__PURE__ */ React.createElement("a", {
54
- href: video.url,
55
- target: "_blank",
56
- rel: "noopener noreferrer",
57
- className: "relative aspect-video group"
58
- }, /* @__PURE__ */ React.createElement("img", {
59
- src: video.thumbnailUrl,
60
- alt: video.title,
61
- className: "h-full w-full object-cover rounded"
62
- }), /* @__PURE__ */ React.createElement("div", {
63
- className: "absolute inset-0 flex items-center justify-center bg-black/0 group-hover:bg-black/30 rounded transition-colors"
64
- }, /* @__PURE__ */ React.createElement("div", {
65
- className: "opacity-0 group-hover:opacity-100 bg-red-600 text-white rounded-full p-2 transition-opacity"
66
- }, /* @__PURE__ */ React.createElement(Icon, {
67
- icon: "ph--play--fill",
68
- size: 4
69
- })))) : /* @__PURE__ */ React.createElement("div", {
70
- className: "aspect-video bg-surface-hover rounded flex items-center justify-center"
71
- }, /* @__PURE__ */ React.createElement(Icon, {
72
- icon: "ph--video--regular",
73
- size: 8
74
- })), /* @__PURE__ */ React.createElement("div", {
75
- className: "flex flex-col gap-1"
76
- }, /* @__PURE__ */ React.createElement("span", {
77
- className: "font-medium line-clamp-2",
78
- title: video.title
79
- }, video.title), /* @__PURE__ */ React.createElement("span", {
80
- className: "text-xs text-description"
81
- }, new Date(video.publishedAt).toLocaleDateString(), video.transcript && " \u2022 Transcript available")))), sortedVideos.length === 0 && /* @__PURE__ */ React.createElement("div", {
82
- className: "col-span-full text-sm text-description p-4 text-center"
83
- }, "No videos synced yet. Sync the channel to fetch videos."))))));
84
- };
85
-
86
- // src/containers/ChannelArticle/index.ts
87
- var ChannelArticle_default = ChannelArticle;
88
- export {
89
- ChannelArticle_default as default
90
- };
91
- //# sourceMappingURL=ChannelArticle-GQ64BO7V.mjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/containers/ChannelArticle/ChannelArticle.tsx", "../../../src/containers/ChannelArticle/index.ts"],
4
- "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport React, { useMemo } from 'react';\n\nimport { type Feed, Obj, Query } from '@dxos/echo';\nimport { Filter, useObject, useQuery } from '@dxos/react-client/echo';\nimport { Icon, Panel } from '@dxos/react-ui';\n\nimport * as Channel from '../../types/Channel';\nimport * as Video from '../../types/Video';\n\nexport type ChannelArticleProps = {\n subject: Channel.YouTubeChannel;\n attendableId?: string;\n};\n\nexport const ChannelArticle = ({ subject: channel }: ChannelArticleProps) => {\n useObject(channel);\n const feed = channel.feed?.target as Feed.Feed | undefined;\n const db = Obj.getDatabase(channel);\n const videos = useQuery(\n db,\n feed ? Query.select(Filter.type(Video.YouTubeVideo)).from(feed) : Query.select(Filter.nothing()),\n ) as Video.YouTubeVideo[];\n\n const sortedVideos = useMemo(\n () =>\n [...videos].sort(\n (videoA, videoB) => new Date(videoB.publishedAt).getTime() - new Date(videoA.publishedAt).getTime(),\n ),\n [videos],\n );\n\n return (\n <Panel.Root>\n <Panel.Content className='overflow-auto'>\n <div className='flex flex-col gap-4 p-4'>\n <div className='flex items-center justify-between'>\n <div className='flex items-center gap-2'>\n <Icon icon='ph--youtube-logo--regular' size={6} />\n <h2 className='text-lg font-semibold'>{channel.name ?? 'YouTube Channel'}</h2>\n </div>\n {channel.lastSyncedAt && (\n <span className='text-xs text-description'>\n Last synced: {new Date(channel.lastSyncedAt).toLocaleString()}\n </span>\n )}\n </div>\n\n {channel.channelUrl && (\n <div className='text-sm text-description'>\n <a\n href={\n channel.channelUrl.startsWith('http')\n ? channel.channelUrl\n : `https://www.youtube.com/@${channel.channelUrl}`\n }\n target='_blank'\n rel='noopener noreferrer'\n className='hover:underline'\n >\n {channel.channelUrl}\n </a>\n </div>\n )}\n\n <div className='flex flex-col gap-2'>\n <h3 className='text-md font-medium'>Videos ({sortedVideos.length})</h3>\n <div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4'>\n {sortedVideos.map((video) => (\n <div key={video.videoId} className='flex flex-col gap-2 p-2 rounded hover:bg-surface-hover'>\n {video.thumbnailUrl ? (\n <a\n href={video.url}\n target='_blank'\n rel='noopener noreferrer'\n className='relative aspect-video group'\n >\n <img src={video.thumbnailUrl} alt={video.title} className='h-full w-full object-cover rounded' />\n <div className='absolute inset-0 flex items-center justify-center bg-black/0 group-hover:bg-black/30 rounded transition-colors'>\n <div className='opacity-0 group-hover:opacity-100 bg-red-600 text-white rounded-full p-2 transition-opacity'>\n <Icon icon='ph--play--fill' size={4} />\n </div>\n </div>\n </a>\n ) : (\n <div className='aspect-video bg-surface-hover rounded flex items-center justify-center'>\n <Icon icon='ph--video--regular' size={8} />\n </div>\n )}\n <div className='flex flex-col gap-1'>\n <span className='font-medium line-clamp-2' title={video.title}>\n {video.title}\n </span>\n <span className='text-xs text-description'>\n {new Date(video.publishedAt).toLocaleDateString()}\n {video.transcript && ' • Transcript available'}\n </span>\n </div>\n </div>\n ))}\n {sortedVideos.length === 0 && (\n <div className='col-span-full text-sm text-description p-4 text-center'>\n No videos synced yet. Sync the channel to fetch videos.\n </div>\n )}\n </div>\n </div>\n </div>\n </Panel.Content>\n </Panel.Root>\n );\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { ChannelArticle } from './ChannelArticle';\n\nexport default ChannelArticle;\n"],
5
- "mappings": ";;;;;;;AAIA,OAAOA,SAASC,eAAe;AAE/B,SAAoBC,KAAKC,aAAa;AACtC,SAASC,QAAQC,WAAWC,gBAAgB;AAC5C,SAASC,MAAMC,aAAa;AAUrB,IAAMC,iBAAiB,CAAC,EAAEC,SAASC,QAAO,MAAuB;AACtEC,YAAUD,OAAAA;AACV,QAAME,OAAOF,QAAQE,MAAMC;AAC3B,QAAMC,KAAKC,IAAIC,YAAYN,OAAAA;AAC3B,QAAMO,SAASC,SACbJ,IACAF,OAAOO,MAAMC,OAAOC,OAAOC,KAAWC,YAAY,CAAA,EAAGC,KAAKZ,IAAAA,IAAQO,MAAMC,OAAOC,OAAOI,QAAO,CAAA,CAAA;AAG/F,QAAMC,eAAeC,QACnB,MACE;OAAIV;IAAQW,KACV,CAACC,QAAQC,WAAW,IAAIC,KAAKD,OAAOE,WAAW,EAAEC,QAAO,IAAK,IAAIF,KAAKF,OAAOG,WAAW,EAAEC,QAAO,CAAA,GAErG;IAAChB;GAAO;AAGV,SACE,sBAAA,cAACiB,MAAMC,MAAI,MACT,sBAAA,cAACD,MAAME,SAAO;IAACC,WAAU;KACvB,sBAAA,cAACC,OAAAA;IAAID,WAAU;KACb,sBAAA,cAACC,OAAAA;IAAID,WAAU;KACb,sBAAA,cAACC,OAAAA;IAAID,WAAU;KACb,sBAAA,cAACE,MAAAA;IAAKC,MAAK;IAA4BC,MAAM;MAC7C,sBAAA,cAACC,MAAAA;IAAGL,WAAU;KAAyB3B,QAAQiC,QAAQ,iBAAA,CAAA,GAExDjC,QAAQkC,gBACP,sBAAA,cAACC,QAAAA;IAAKR,WAAU;KAA2B,iBAC3B,IAAIN,KAAKrB,QAAQkC,YAAY,EAAEE,eAAc,CAAA,CAAA,GAKhEpC,QAAQqC,cACP,sBAAA,cAACT,OAAAA;IAAID,WAAU;KACb,sBAAA,cAACW,KAAAA;IACCC,MACEvC,QAAQqC,WAAWG,WAAW,MAAA,IAC1BxC,QAAQqC,aACR,4BAA4BrC,QAAQqC,UAAU;IAEpDlC,QAAO;IACPsC,KAAI;IACJd,WAAU;KAET3B,QAAQqC,UAAU,CAAA,GAKzB,sBAAA,cAACT,OAAAA;IAAID,WAAU;KACb,sBAAA,cAACe,MAAAA;IAAGf,WAAU;KAAsB,YAASX,aAAa2B,QAAO,GAAA,GACjE,sBAAA,cAACf,OAAAA;IAAID,WAAU;KACZX,aAAa4B,IAAI,CAACC,UACjB,sBAAA,cAACjB,OAAAA;IAAIkB,KAAKD,MAAME;IAASpB,WAAU;KAChCkB,MAAMG,eACL,sBAAA,cAACV,KAAAA;IACCC,MAAMM,MAAMI;IACZ9C,QAAO;IACPsC,KAAI;IACJd,WAAU;KAEV,sBAAA,cAACuB,OAAAA;IAAIC,KAAKN,MAAMG;IAAcI,KAAKP,MAAMQ;IAAO1B,WAAU;MAC1D,sBAAA,cAACC,OAAAA;IAAID,WAAU;KACb,sBAAA,cAACC,OAAAA;IAAID,WAAU;KACb,sBAAA,cAACE,MAAAA;IAAKC,MAAK;IAAiBC,MAAM;UAKxC,sBAAA,cAACH,OAAAA;IAAID,WAAU;KACb,sBAAA,cAACE,MAAAA;IAAKC,MAAK;IAAqBC,MAAM;OAG1C,sBAAA,cAACH,OAAAA;IAAID,WAAU;KACb,sBAAA,cAACQ,QAAAA;IAAKR,WAAU;IAA2B0B,OAAOR,MAAMQ;KACrDR,MAAMQ,KAAK,GAEd,sBAAA,cAAClB,QAAAA;IAAKR,WAAU;KACb,IAAIN,KAAKwB,MAAMvB,WAAW,EAAEgC,mBAAkB,GAC9CT,MAAMU,cAAc,8BAAA,CAAA,CAAA,CAAA,GAK5BvC,aAAa2B,WAAW,KACvB,sBAAA,cAACf,OAAAA;IAAID,WAAU;KAAyD,yDAAA,CAAA,CAAA,CAAA,CAAA,CAAA;AAUxF;;;AC5GA,IAAA,yBAAe6B;",
6
- "names": ["React", "useMemo", "Obj", "Query", "Filter", "useObject", "useQuery", "Icon", "Panel", "ChannelArticle", "subject", "channel", "useObject", "feed", "target", "db", "Obj", "getDatabase", "videos", "useQuery", "Query", "select", "Filter", "type", "YouTubeVideo", "from", "nothing", "sortedVideos", "useMemo", "sort", "videoA", "videoB", "Date", "publishedAt", "getTime", "Panel", "Root", "Content", "className", "div", "Icon", "icon", "size", "h2", "name", "lastSyncedAt", "span", "toLocaleString", "channelUrl", "a", "href", "startsWith", "rel", "h3", "length", "map", "video", "key", "videoId", "thumbnailUrl", "url", "img", "src", "alt", "title", "toLocaleDateString", "transcript", "ChannelArticle"]
7
- }
@@ -1,29 +0,0 @@
1
- import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
- import "./chunk-HSLMI22Q.mjs";
3
-
4
- // src/containers/ChannelSettings/ChannelSettings.tsx
5
- import React from "react";
6
- var ChannelSettings = ({ subject: channel }) => {
7
- return /* @__PURE__ */ React.createElement("div", {
8
- className: "flex flex-col gap-4 p-4"
9
- }, /* @__PURE__ */ React.createElement("h3", {
10
- className: "text-md font-medium"
11
- }, "Channel Settings"), /* @__PURE__ */ React.createElement("div", {
12
- className: "flex flex-col gap-2 text-sm"
13
- }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("span", {
14
- className: "text-description"
15
- }, "Name:"), " ", /* @__PURE__ */ React.createElement("span", null, channel.name ?? "Not set")), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("span", {
16
- className: "text-description"
17
- }, "Channel URL:"), " ", /* @__PURE__ */ React.createElement("span", null, channel.channelUrl ?? "Not set")), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("span", {
18
- className: "text-description"
19
- }, "Channel ID:"), " ", /* @__PURE__ */ React.createElement("span", null, channel.channelId ?? "Not set")), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("span", {
20
- className: "text-description"
21
- }, "Last Synced:"), " ", /* @__PURE__ */ React.createElement("span", null, channel.lastSyncedAt ? new Date(channel.lastSyncedAt).toLocaleString() : "Never"))));
22
- };
23
-
24
- // src/containers/ChannelSettings/index.ts
25
- var ChannelSettings_default = ChannelSettings;
26
- export {
27
- ChannelSettings_default as default
28
- };
29
- //# sourceMappingURL=ChannelSettings-DM2HWNKO.mjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/containers/ChannelSettings/ChannelSettings.tsx", "../../../src/containers/ChannelSettings/index.ts"],
4
- "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport React from 'react';\n\nimport * as Channel from '../../types/Channel';\n\nexport type ChannelSettingsProps = {\n subject: Channel.YouTubeChannel;\n};\n\nexport const ChannelSettings = ({ subject: channel }: ChannelSettingsProps) => {\n return (\n <div className='flex flex-col gap-4 p-4'>\n <h3 className='text-md font-medium'>Channel Settings</h3>\n <div className='flex flex-col gap-2 text-sm'>\n <div>\n <span className='text-description'>Name:</span> <span>{channel.name ?? 'Not set'}</span>\n </div>\n <div>\n <span className='text-description'>Channel URL:</span> <span>{channel.channelUrl ?? 'Not set'}</span>\n </div>\n <div>\n <span className='text-description'>Channel ID:</span> <span>{channel.channelId ?? 'Not set'}</span>\n </div>\n <div>\n <span className='text-description'>Last Synced:</span>{' '}\n <span>{channel.lastSyncedAt ? new Date(channel.lastSyncedAt).toLocaleString() : 'Never'}</span>\n </div>\n </div>\n </div>\n );\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { ChannelSettings } from './ChannelSettings';\n\nexport default ChannelSettings;\n"],
5
- "mappings": ";;;;AAIA,OAAOA,WAAW;AAQX,IAAMC,kBAAkB,CAAC,EAAEC,SAASC,QAAO,MAAwB;AACxE,SACE,sBAAA,cAACC,OAAAA;IAAIC,WAAU;KACb,sBAAA,cAACC,MAAAA;IAAGD,WAAU;KAAsB,kBAAA,GACpC,sBAAA,cAACD,OAAAA;IAAIC,WAAU;KACb,sBAAA,cAACD,OAAAA,MACC,sBAAA,cAACG,QAAAA;IAAKF,WAAU;KAAmB,OAAA,GAAY,KAAC,sBAAA,cAACE,QAAAA,MAAMJ,QAAQK,QAAQ,SAAA,CAAA,GAEzE,sBAAA,cAACJ,OAAAA,MACC,sBAAA,cAACG,QAAAA;IAAKF,WAAU;KAAmB,cAAA,GAAmB,KAAC,sBAAA,cAACE,QAAAA,MAAMJ,QAAQM,cAAc,SAAA,CAAA,GAEtF,sBAAA,cAACL,OAAAA,MACC,sBAAA,cAACG,QAAAA;IAAKF,WAAU;KAAmB,aAAA,GAAkB,KAAC,sBAAA,cAACE,QAAAA,MAAMJ,QAAQO,aAAa,SAAA,CAAA,GAEpF,sBAAA,cAACN,OAAAA,MACC,sBAAA,cAACG,QAAAA;IAAKF,WAAU;KAAmB,cAAA,GAAoB,KACvD,sBAAA,cAACE,QAAAA,MAAMJ,QAAQQ,eAAe,IAAIC,KAAKT,QAAQQ,YAAY,EAAEE,eAAc,IAAK,OAAA,CAAA,CAAA,CAAA;AAK1F;;;AC3BA,IAAA,0BAAeC;",
6
- "names": ["React", "ChannelSettings", "subject", "channel", "div", "className", "h3", "span", "name", "channelUrl", "channelId", "lastSyncedAt", "Date", "toLocaleString", "ChannelSettings"]
7
- }
@@ -1,77 +0,0 @@
1
- import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
- import "./chunk-HSLMI22Q.mjs";
3
-
4
- // src/containers/VideoArticle/VideoArticle.tsx
5
- import React, { useState } from "react";
6
- import { Icon, Panel } from "@dxos/react-ui";
7
- var VideoArticle = ({ subject: video, role }) => {
8
- const [showPlayer, setShowPlayer] = useState(false);
9
- const publishedDate = new Date(video.publishedAt).toLocaleDateString();
10
- const hasTranscript = Boolean(video.transcript);
11
- const embedUrl = `https://www.youtube.com/embed/${video.videoId}`;
12
- return /* @__PURE__ */ React.createElement(Panel.Root, null, /* @__PURE__ */ React.createElement(Panel.Content, {
13
- className: role === "section" ? "overflow-auto" : ""
14
- }, /* @__PURE__ */ React.createElement("div", {
15
- className: "flex flex-col gap-4 p-4 max-w-4xl"
16
- }, /* @__PURE__ */ React.createElement("div", {
17
- className: "flex flex-col gap-2"
18
- }, /* @__PURE__ */ React.createElement("h2", {
19
- className: "text-lg font-semibold"
20
- }, video.title), /* @__PURE__ */ React.createElement("div", {
21
- className: "flex items-center gap-2 text-sm text-description"
22
- }, /* @__PURE__ */ React.createElement("span", null, video.channelTitle), /* @__PURE__ */ React.createElement("span", null, "\u2022"), /* @__PURE__ */ React.createElement("span", null, publishedDate), video.viewCount !== void 0 && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("span", null, "\u2022"), /* @__PURE__ */ React.createElement("span", null, video.viewCount.toLocaleString(), " views")), video.likeCount !== void 0 && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("span", null, "\u2022"), /* @__PURE__ */ React.createElement("span", null, video.likeCount.toLocaleString(), " likes")))), /* @__PURE__ */ React.createElement("div", {
23
- className: "aspect-video w-full max-w-2xl"
24
- }, showPlayer ? /* @__PURE__ */ React.createElement("iframe", {
25
- src: embedUrl,
26
- title: video.title,
27
- allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
28
- allowFullScreen: true,
29
- className: "h-full w-full rounded-lg"
30
- }) : /* @__PURE__ */ React.createElement("button", {
31
- type: "button",
32
- onClick: () => setShowPlayer(true),
33
- className: "relative h-full w-full group cursor-pointer"
34
- }, video.thumbnailUrl ? /* @__PURE__ */ React.createElement("img", {
35
- src: video.thumbnailUrl,
36
- alt: video.title,
37
- className: "h-full w-full object-cover rounded-lg"
38
- }) : /* @__PURE__ */ React.createElement("div", {
39
- className: "h-full w-full bg-surface-hover rounded-lg flex items-center justify-center"
40
- }, /* @__PURE__ */ React.createElement(Icon, {
41
- icon: "ph--play--fill",
42
- size: 12
43
- })), /* @__PURE__ */ React.createElement("div", {
44
- className: "absolute inset-0 flex items-center justify-center bg-black/30 group-hover:bg-black/50 rounded-lg transition-colors"
45
- }, /* @__PURE__ */ React.createElement("div", {
46
- className: "bg-red-600 text-white rounded-full p-4 group-hover:scale-110 transition-transform"
47
- }, /* @__PURE__ */ React.createElement(Icon, {
48
- icon: "ph--play--fill",
49
- size: 8
50
- }))))), video.description && /* @__PURE__ */ React.createElement("div", {
51
- className: "max-w-2xl"
52
- }, /* @__PURE__ */ React.createElement("h3", {
53
- className: "text-md font-medium mb-2"
54
- }, "Description"), /* @__PURE__ */ React.createElement("p", {
55
- className: "whitespace-pre-wrap text-sm"
56
- }, video.description)), hasTranscript && /* @__PURE__ */ React.createElement("div", {
57
- className: "max-w-2xl"
58
- }, /* @__PURE__ */ React.createElement("h3", {
59
- className: "text-md font-medium mb-2"
60
- }, "Transcript"), /* @__PURE__ */ React.createElement("div", {
61
- className: "bg-surface-input p-4 rounded-lg max-h-96 overflow-auto"
62
- }, /* @__PURE__ */ React.createElement("p", {
63
- className: "whitespace-pre-wrap text-sm"
64
- }, video.transcript))), /* @__PURE__ */ React.createElement("a", {
65
- href: video.url,
66
- target: "_blank",
67
- rel: "noopener noreferrer",
68
- className: "inline-flex items-center gap-2 text-sm text-primary hover:underline"
69
- }, "Watch on YouTube \u2192"))));
70
- };
71
-
72
- // src/containers/VideoArticle/index.ts
73
- var VideoArticle_default = VideoArticle;
74
- export {
75
- VideoArticle_default as default
76
- };
77
- //# sourceMappingURL=VideoArticle-WLTWZO3K.mjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/containers/VideoArticle/VideoArticle.tsx", "../../../src/containers/VideoArticle/index.ts"],
4
- "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport React, { useState } from 'react';\n\nimport { Icon, Panel } from '@dxos/react-ui';\n\nimport * as Channel from '../../types/Channel';\nimport * as Video from '../../types/Video';\n\nexport type VideoArticleProps = {\n role: string | string[];\n subject: Video.YouTubeVideo;\n channel: Channel.YouTubeChannel;\n attendableId?: string;\n};\n\nexport const VideoArticle = ({ subject: video, role }: VideoArticleProps) => {\n const [showPlayer, setShowPlayer] = useState(false);\n const publishedDate = new Date(video.publishedAt).toLocaleDateString();\n const hasTranscript = Boolean(video.transcript);\n const embedUrl = `https://www.youtube.com/embed/${video.videoId}`;\n\n return (\n <Panel.Root>\n <Panel.Content className={role === 'section' ? 'overflow-auto' : ''}>\n <div className='flex flex-col gap-4 p-4 max-w-4xl'>\n <div className='flex flex-col gap-2'>\n <h2 className='text-lg font-semibold'>{video.title}</h2>\n <div className='flex items-center gap-2 text-sm text-description'>\n <span>{video.channelTitle}</span>\n <span>•</span>\n <span>{publishedDate}</span>\n {video.viewCount !== undefined && (\n <>\n <span>•</span>\n <span>{video.viewCount.toLocaleString()} views</span>\n </>\n )}\n {video.likeCount !== undefined && (\n <>\n <span>•</span>\n <span>{video.likeCount.toLocaleString()} likes</span>\n </>\n )}\n </div>\n </div>\n\n <div className='aspect-video w-full max-w-2xl'>\n {showPlayer ? (\n <iframe\n src={embedUrl}\n title={video.title}\n allow='accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture'\n allowFullScreen\n className='h-full w-full rounded-lg'\n />\n ) : (\n <button\n type='button'\n onClick={() => setShowPlayer(true)}\n className='relative h-full w-full group cursor-pointer'\n >\n {video.thumbnailUrl ? (\n <img src={video.thumbnailUrl} alt={video.title} className='h-full w-full object-cover rounded-lg' />\n ) : (\n <div className='h-full w-full bg-surface-hover rounded-lg flex items-center justify-center'>\n <Icon icon='ph--play--fill' size={12} />\n </div>\n )}\n <div className='absolute inset-0 flex items-center justify-center bg-black/30 group-hover:bg-black/50 rounded-lg transition-colors'>\n <div className='bg-red-600 text-white rounded-full p-4 group-hover:scale-110 transition-transform'>\n <Icon icon='ph--play--fill' size={8} />\n </div>\n </div>\n </button>\n )}\n </div>\n\n {video.description && (\n <div className='max-w-2xl'>\n <h3 className='text-md font-medium mb-2'>Description</h3>\n <p className='whitespace-pre-wrap text-sm'>{video.description}</p>\n </div>\n )}\n\n {hasTranscript && (\n <div className='max-w-2xl'>\n <h3 className='text-md font-medium mb-2'>Transcript</h3>\n <div className='bg-surface-input p-4 rounded-lg max-h-96 overflow-auto'>\n <p className='whitespace-pre-wrap text-sm'>{video.transcript}</p>\n </div>\n </div>\n )}\n\n <a\n href={video.url}\n target='_blank'\n rel='noopener noreferrer'\n className='inline-flex items-center gap-2 text-sm text-primary hover:underline'\n >\n Watch on YouTube →\n </a>\n </div>\n </Panel.Content>\n </Panel.Root>\n );\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { VideoArticle } from './VideoArticle';\n\nexport default VideoArticle;\n"],
5
- "mappings": ";;;;AAIA,OAAOA,SAASC,gBAAgB;AAEhC,SAASC,MAAMC,aAAa;AAYrB,IAAMC,eAAe,CAAC,EAAEC,SAASC,OAAOC,KAAI,MAAqB;AACtE,QAAM,CAACC,YAAYC,aAAAA,IAAiBC,SAAS,KAAA;AAC7C,QAAMC,gBAAgB,IAAIC,KAAKN,MAAMO,WAAW,EAAEC,mBAAkB;AACpE,QAAMC,gBAAgBC,QAAQV,MAAMW,UAAU;AAC9C,QAAMC,WAAW,iCAAiCZ,MAAMa,OAAO;AAE/D,SACE,sBAAA,cAACC,MAAMC,MAAI,MACT,sBAAA,cAACD,MAAME,SAAO;IAACC,WAAWhB,SAAS,YAAY,kBAAkB;KAC/D,sBAAA,cAACiB,OAAAA;IAAID,WAAU;KACb,sBAAA,cAACC,OAAAA;IAAID,WAAU;KACb,sBAAA,cAACE,MAAAA;IAAGF,WAAU;KAAyBjB,MAAMoB,KAAK,GAClD,sBAAA,cAACF,OAAAA;IAAID,WAAU;KACb,sBAAA,cAACI,QAAAA,MAAMrB,MAAMsB,YAAY,GACzB,sBAAA,cAACD,QAAAA,MAAK,QAAA,GACN,sBAAA,cAACA,QAAAA,MAAMhB,aAAAA,GACNL,MAAMuB,cAAcC,UACnB,sBAAA,cAAA,MAAA,UAAA,MACE,sBAAA,cAACH,QAAAA,MAAK,QAAA,GACN,sBAAA,cAACA,QAAAA,MAAMrB,MAAMuB,UAAUE,eAAc,GAAG,QAAA,CAAA,GAG3CzB,MAAM0B,cAAcF,UACnB,sBAAA,cAAA,MAAA,UAAA,MACE,sBAAA,cAACH,QAAAA,MAAK,QAAA,GACN,sBAAA,cAACA,QAAAA,MAAMrB,MAAM0B,UAAUD,eAAc,GAAG,QAAA,CAAA,CAAA,CAAA,GAMhD,sBAAA,cAACP,OAAAA;IAAID,WAAU;KACZf,aACC,sBAAA,cAACyB,UAAAA;IACCC,KAAKhB;IACLQ,OAAOpB,MAAMoB;IACbS,OAAM;IACNC,iBAAAA;IACAb,WAAU;OAGZ,sBAAA,cAACc,UAAAA;IACCC,MAAK;IACLC,SAAS,MAAM9B,cAAc,IAAA;IAC7Bc,WAAU;KAETjB,MAAMkC,eACL,sBAAA,cAACC,OAAAA;IAAIP,KAAK5B,MAAMkC;IAAcE,KAAKpC,MAAMoB;IAAOH,WAAU;OAE1D,sBAAA,cAACC,OAAAA;IAAID,WAAU;KACb,sBAAA,cAACoB,MAAAA;IAAKC,MAAK;IAAiBC,MAAM;OAGtC,sBAAA,cAACrB,OAAAA;IAAID,WAAU;KACb,sBAAA,cAACC,OAAAA;IAAID,WAAU;KACb,sBAAA,cAACoB,MAAAA;IAAKC,MAAK;IAAiBC,MAAM;UAO3CvC,MAAMwC,eACL,sBAAA,cAACtB,OAAAA;IAAID,WAAU;KACb,sBAAA,cAACwB,MAAAA;IAAGxB,WAAU;KAA2B,aAAA,GACzC,sBAAA,cAACyB,KAAAA;IAAEzB,WAAU;KAA+BjB,MAAMwC,WAAW,CAAA,GAIhE/B,iBACC,sBAAA,cAACS,OAAAA;IAAID,WAAU;KACb,sBAAA,cAACwB,MAAAA;IAAGxB,WAAU;KAA2B,YAAA,GACzC,sBAAA,cAACC,OAAAA;IAAID,WAAU;KACb,sBAAA,cAACyB,KAAAA;IAAEzB,WAAU;KAA+BjB,MAAMW,UAAU,CAAA,CAAA,GAKlE,sBAAA,cAACgC,KAAAA;IACCC,MAAM5C,MAAM6C;IACZC,QAAO;IACPC,KAAI;IACJ9B,WAAU;KACX,yBAAA,CAAA,CAAA,CAAA;AAOX;;;ACtGA,IAAA,uBAAe+B;",
6
- "names": ["React", "useState", "Icon", "Panel", "VideoArticle", "subject", "video", "role", "showPlayer", "setShowPlayer", "useState", "publishedDate", "Date", "publishedAt", "toLocaleDateString", "hasTranscript", "Boolean", "transcript", "embedUrl", "videoId", "Panel", "Root", "Content", "className", "div", "h2", "title", "span", "channelTitle", "viewCount", "undefined", "toLocaleString", "likeCount", "iframe", "src", "allow", "allowFullScreen", "button", "type", "onClick", "thumbnailUrl", "img", "alt", "Icon", "icon", "size", "description", "h3", "p", "a", "href", "url", "target", "rel", "VideoArticle"]
7
- }
@@ -1,65 +0,0 @@
1
- import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
- import "./chunk-HSLMI22Q.mjs";
3
-
4
- // src/containers/VideoCard/VideoCard.tsx
5
- import React, { useState } from "react";
6
- import { Card, Icon } from "@dxos/react-ui";
7
- var VideoCard = ({ subject: video }) => {
8
- const [showPlayer, setShowPlayer] = useState(false);
9
- const publishedDate = new Date(video.publishedAt).toLocaleDateString();
10
- const hasTranscript = Boolean(video.transcript);
11
- const embedUrl = `https://www.youtube.com/embed/${video.videoId}?autoplay=1`;
12
- return /* @__PURE__ */ React.createElement(Card.Content, null, showPlayer ? /* @__PURE__ */ React.createElement("div", {
13
- className: "aspect-video w-full"
14
- }, /* @__PURE__ */ React.createElement("iframe", {
15
- src: embedUrl,
16
- title: video.title,
17
- allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
18
- allowFullScreen: true,
19
- className: "h-full w-full rounded"
20
- })) : /* @__PURE__ */ React.createElement("button", {
21
- type: "button",
22
- onClick: () => setShowPlayer(true),
23
- className: "relative aspect-video w-full group cursor-pointer"
24
- }, video.thumbnailUrl ? /* @__PURE__ */ React.createElement("img", {
25
- src: video.thumbnailUrl,
26
- alt: video.title,
27
- className: "h-full w-full object-cover rounded"
28
- }) : /* @__PURE__ */ React.createElement("div", {
29
- className: "h-full w-full bg-surface-hover rounded flex items-center justify-center"
30
- }, /* @__PURE__ */ React.createElement(Icon, {
31
- icon: "ph--play--fill",
32
- size: 12
33
- })), /* @__PURE__ */ React.createElement("div", {
34
- className: "absolute inset-0 flex items-center justify-center bg-black/30 group-hover:bg-black/50 rounded transition-colors"
35
- }, /* @__PURE__ */ React.createElement("div", {
36
- className: "bg-red-600 text-white rounded-full p-3 group-hover:scale-110 transition-transform"
37
- }, /* @__PURE__ */ React.createElement(Icon, {
38
- icon: "ph--play--fill",
39
- size: 6
40
- })))), /* @__PURE__ */ React.createElement(Card.Toolbar, null, /* @__PURE__ */ React.createElement(Card.IconBlock, null, /* @__PURE__ */ React.createElement(Icon, {
41
- icon: "ph--youtube-logo--regular",
42
- size: 5
43
- })), /* @__PURE__ */ React.createElement("div", {
44
- className: "flex gap-3 items-center justify-between col-span-2"
45
- }, /* @__PURE__ */ React.createElement("span", {
46
- className: "grow truncate font-medium"
47
- }, video.title), /* @__PURE__ */ React.createElement("span", {
48
- className: "text-xs text-description text-right whitespace-nowrap pe-2"
49
- }, publishedDate))), /* @__PURE__ */ React.createElement(Card.Row, null, /* @__PURE__ */ React.createElement("span", {
50
- className: "text-xs text-description"
51
- }, video.channelTitle)), video.description && /* @__PURE__ */ React.createElement(Card.Row, null, /* @__PURE__ */ React.createElement(Card.Text, {
52
- variant: "description"
53
- }, video.description.slice(0, 150), "...")), /* @__PURE__ */ React.createElement(Card.Row, null, /* @__PURE__ */ React.createElement("div", {
54
- className: "flex gap-2 items-center text-xs text-description"
55
- }, video.viewCount !== void 0 && /* @__PURE__ */ React.createElement("span", null, video.viewCount.toLocaleString(), " views"), hasTranscript && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("span", null, "\u2022"), /* @__PURE__ */ React.createElement("span", {
56
- className: "text-green-600"
57
- }, "Transcript available")))));
58
- };
59
-
60
- // src/containers/VideoCard/index.ts
61
- var VideoCard_default = VideoCard;
62
- export {
63
- VideoCard_default as default
64
- };
65
- //# sourceMappingURL=VideoCard-FOWQZK75.mjs.map