@learnpack/learnpack 5.0.265 → 5.0.266

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.
@@ -10,7 +10,7 @@
10
10
  />
11
11
 
12
12
  <title>Learnpack Creator: Craft tutorials in seconds!</title>
13
- <script type="module" crossorigin src="/creator/assets/index-6e9E-1qG.js"></script>
13
+ <script type="module" crossorigin src="/creator/assets/index-BXp9oelr.js"></script>
14
14
  <link rel="stylesheet" crossorigin href="/creator/assets/index-DmpsXknz.css">
15
15
  </head>
16
16
  <body>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@learnpack/learnpack",
3
3
  "description": "Seamlessly build, sell and/or take interactive & auto-graded tutorials, start learning now or build a new tutorial to your audience.",
4
- "version": "5.0.265",
4
+ "version": "5.0.266",
5
5
  "author": "Alejandro Sanchez @alesanchezr",
6
6
  "contributors": [
7
7
  {
@@ -1,5 +1,7 @@
1
1
  import { flags } from "@oclif/command"
2
2
 
3
+ import { Buffer } from "buffer"
4
+
3
5
  import { YoutubeTranscript } from "youtube-transcript"
4
6
  import * as express from "express"
5
7
  import * as cors from "cors"
@@ -547,36 +549,63 @@ export default class ServeCommand extends SessionCommand {
547
549
  app.post("/webhooks/:courseSlug/images/:imageId", async (req, res) => {
548
550
  const { courseSlug, imageId } = req.params
549
551
  const body = req.body
550
- console.log("RECEIVING IMAGE WEBHOOK", body)
551
-
552
- const imageUrl = body.image_url
553
- const imagePath = `courses/${courseSlug}/.learn/assets/${imageId}`
554
-
555
- const imageFile = bucket.file(imagePath)
556
- const [exists] = await imageFile.exists()
557
- if (!exists) {
558
- // Descargar la imagen
559
- const response = await fetch(imageUrl)
560
- if (!response.ok) {
561
- return res.status(400).json({
552
+ try {
553
+ if (body.error) {
554
+ emitToNotification(imageId, {
562
555
  status: "ERROR",
563
- message: "No se pudo descargar la imagen",
556
+ message: "Error generating image",
564
557
  })
558
+ return res.json({ status: "ERROR" })
565
559
  }
566
560
 
567
- const buffer = await response.arrayBuffer()
561
+ fs.writeFileSync(`image-${imageId}.json`, JSON.stringify(body, null, 2))
562
+
563
+ const imageUrl = body.image_url
564
+ const format = body.format
565
+ const imagePath = `courses/${courseSlug}/.learn/assets/${imageId}`
566
+ const imageFile = bucket.file(imagePath)
567
+ const [exists] = await imageFile.exists()
568
+ if (!exists) {
569
+ let buffer: Uint8Array
570
+
571
+ if (format === "b64" || imageUrl.startsWith("data:image/")) {
572
+ const base64Data = imageUrl.includes(",") ?
573
+ imageUrl.split(",")[1] :
574
+ imageUrl
575
+ buffer = Buffer.from(base64Data, "base64")
576
+ } else if (imageUrl.startsWith("http")) {
577
+ const response = await fetch(imageUrl)
578
+ if (!response.ok) {
579
+ return res.status(400).json({
580
+ status: "ERROR",
581
+ message: "Could not download the image",
582
+ })
583
+ }
584
+
585
+ buffer = new Uint8Array(await response.arrayBuffer())
586
+ } else {
587
+ return res.status(400).json({
588
+ status: "ERROR",
589
+ message: "Image_url format not supported",
590
+ })
591
+ }
592
+
593
+ await imageFile.save(buffer, { contentType: "image/png" })
594
+ }
568
595
 
569
- // Guardar la imagen en el bucket
570
- await imageFile.save(new Uint8Array(buffer), {
571
- contentType: "image/png",
596
+ emitToNotification(imageId, {
597
+ status: "SUCCESS",
598
+ message: "Image generated successfully",
599
+ })
600
+ res.json({ status: "SUCCESS" })
601
+ } catch (error) {
602
+ emitToNotification(imageId, {
603
+ status: "ERROR",
604
+ message: "Error receiving image webhook",
572
605
  })
606
+ console.error("❌ Error receiving image webhook:", error)
607
+ res.status(500).json({ error: (error as Error).message })
573
608
  }
574
-
575
- emitToNotification(imageId, {
576
- status: "SUCCESS",
577
- message: "Image generated successfully",
578
- })
579
- res.json({ status: "SUCCESS" })
580
609
  })
581
610
 
582
611
  app.post(
@@ -1001,7 +1030,7 @@ export default class ServeCommand extends SessionCommand {
1001
1030
  const translationPath = `courses/${courseSlug}/exercises/${slug}/README${getReadmeExtension(
1002
1031
  language
1003
1032
  )}`
1004
-
1033
+
1005
1034
  const [exists] = await bucket.file(translationPath).exists()
1006
1035
  if (exists) {
1007
1036
  console.log(
@@ -1009,7 +1038,7 @@ export default class ServeCommand extends SessionCommand {
1009
1038
  )
1010
1039
  return
1011
1040
  }
1012
-
1041
+
1013
1042
  await translateExercise(
1014
1043
  rigoToken,
1015
1044
  {
@@ -1089,7 +1118,6 @@ export default class ServeCommand extends SessionCommand {
1089
1118
 
1090
1119
  await Promise.all(
1091
1120
  missingReadmeTranslations.map(async languageCode => {
1092
-
1093
1121
  await translateExercise(
1094
1122
  rigoToken,
1095
1123
  {
@@ -3,6 +3,7 @@ import { RigoLoader } from "./RigoLoader"
3
3
  import { SVGS } from "../assets/svgs"
4
4
  import useStore from "../utils/store"
5
5
  import { MarkdownRenderer } from "./MarkdownRenderer"
6
+ import { useTranslation } from "react-i18next"
6
7
 
7
8
  export type TMessage = {
8
9
  type: "user" | "assistant"
@@ -10,13 +11,17 @@ export type TMessage = {
10
11
  }
11
12
 
12
13
  export const Message: React.FC<TMessage> = ({ type, content }) => {
14
+ const { t } = useTranslation()
13
15
  const user = useStore((state) => state.auth.user)
14
16
  const isAI = type === "assistant"
15
17
 
16
18
  const isLoading = isAI && !content
17
19
 
18
20
  return isLoading ? (
19
- <RigoLoader text="Thinking..." svg={<img src="rigo-float.gif" />} />
21
+ <RigoLoader
22
+ text={t("loader.thinking")}
23
+ svg={<img src="rigo-float.gif" />}
24
+ />
20
25
  ) : (
21
26
  <div
22
27
  className={`flex items-start space-x-2 p-3 rounded-md border ${
@@ -242,7 +242,7 @@ export const ContentIndex = ({
242
242
  className="space-y-3 overflow-y-auto max-h-[78vh] pr-2 scrollbar-hide relative pb-20"
243
243
  >
244
244
  {isThinking ? (
245
- <Loader text="Thinking..." minheight="min-h-[69vh]" />
245
+ <Loader text="" minheight="min-h-[69vh]" />
246
246
  ) : (
247
247
  <>
248
248
  <ContentSecondaryHeader messages={messages} />
@@ -110,7 +110,7 @@ export const Sidebar = ({
110
110
  ref={inputRef}
111
111
  style={{ resize: "none" }}
112
112
  className="w-full h-full p-2 outline-blue rounded"
113
- placeholder="How can Learnpack help you?"
113
+ placeholder={t("sidebar.howCanLearnPackHelpYou")}
114
114
  onKeyUp={(e) => {
115
115
  if (e.key === "Enter" && !e.shiftKey) {
116
116
  e.preventDefault()
@@ -71,10 +71,12 @@
71
71
  }
72
72
  },
73
73
  "loader": {
74
- "text": "Learnpack is setting up your tutorial. It may take a moment..."
74
+ "text": "Learnpack is setting up your tutorial. It may take a moment...",
75
+ "thinking": "Thinking..."
75
76
  },
76
77
  "sidebar": {
77
- "chatWithMe": "Chat with me to update the course content"
78
+ "chatWithMe": "Chat with me to update the course content",
79
+ "howCanLearnPackHelpYou": "How can LearnPack help you?"
78
80
  },
79
81
  "contentIndex": {
80
82
  "subText": {
@@ -71,10 +71,12 @@
71
71
  }
72
72
  },
73
73
  "loader": {
74
- "text": "Learnpack está configurando tu tutorial. Puede que tarde un momento..."
74
+ "text": "Learnpack está configurando tu tutorial. Puede que tarde un momento...",
75
+ "thinking": "Pensando..."
75
76
  },
76
77
  "sidebar": {
77
- "chatWithMe": "Chatea conmigo para actualizar el contenido del curso"
78
+ "chatWithMe": "Chatea conmigo para actualizar el contenido del curso",
79
+ "howCanLearnPackHelpYou": "¿Cómo puede LearnPack ayudarte?"
78
80
  },
79
81
  "contentIndex": {
80
82
  "subText": {
@@ -20,6 +20,8 @@ export const publicInteractiveCreation = async (
20
20
  DEV_MODE
21
21
  ? "https://9cw5zmww-3000.use2.devtunnels.ms"
22
22
  : window.location.origin
23
+ // : window.location.origin
24
+ // "https://9cw5zmww-3000.use2.devtunnels.ms"
23
25
  }/notifications/${randomUID}`
24
26
 
25
27
  console.log("WEBHOOK URL to send to Rigo", webhookUrl)