dmed-voice-assistant 1.2.2 → 1.2.4

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.
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = void 0;
8
+ var _react = _interopRequireDefault(require("react"));
9
+ var _material = require("@mui/material");
10
+ var _jsxRuntime = require("react/jsx-runtime");
11
+ const HistoryDropdownItem = _ref => {
12
+ let {
13
+ data,
14
+ setDate,
15
+ handlePopoverClose
16
+ } = _ref;
17
+ const handleClick = () => {
18
+ setDate(data.date);
19
+ handlePopoverClose();
20
+ };
21
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Box, {
22
+ className: "flex items-center justify-between rounded-[5px] px-[10px] py-[3px] cursor-pointer",
23
+ sx: {
24
+ '&:hover': {
25
+ background: '#F6F6F6'
26
+ }
27
+ },
28
+ onClick: handleClick,
29
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Box, {
30
+ className: "flex items-center space-x-1",
31
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
32
+ className: "!font-bold !text-[14px]",
33
+ color: "#494A48",
34
+ children: data.count
35
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
36
+ className: "!font-400 !text-[12px]",
37
+ color: "#494A48",
38
+ children: "words"
39
+ })]
40
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
41
+ className: "!font-400 !text-[14px]",
42
+ color: "#494A48",
43
+ children: data.date
44
+ })]
45
+ });
46
+ };
47
+ var _default = exports.default = HistoryDropdownItem;
@@ -20,7 +20,7 @@ const RecognitionListItem = _ref => {
20
20
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
21
21
  className: "!font-bold !text-[14px]",
22
22
  color: "#494A48",
23
- children: data.result.length
23
+ children: data.voice_words?.split(",").length
24
24
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
25
25
  className: "!font-400 !text-[12px]",
26
26
  color: "#494A48",
@@ -29,7 +29,7 @@ const RecognitionListItem = _ref => {
29
29
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
30
30
  className: "px-[4px] !font-400 !text-[14px]",
31
31
  color: "#494A48",
32
- children: data.date.toLocaleTimeString('en-US', {
32
+ children: new Date(data.created_at * 1000).toLocaleTimeString('en-US', {
33
33
  hour: '2-digit',
34
34
  minute: '2-digit',
35
35
  hour12: true
@@ -41,7 +41,7 @@ const RecognitionListItem = _ref => {
41
41
  maxWidth: "387px",
42
42
  overflow: "hidden"
43
43
  },
44
- children: data.result.map((item, index) => {
44
+ children: data.voice_words?.split(",").map((item, index) => {
45
45
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Box, {
46
46
  className: "flex items-center",
47
47
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
@@ -51,7 +51,7 @@ const RecognitionListItem = _ref => {
51
51
  fontFamily: "Space Grotesk !important"
52
52
  },
53
53
  children: item
54
- }), index !== data.result.length - 1 && /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
54
+ }), index !== data.voice_words?.split(",").length - 1 && /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
55
55
  className: "!font-400 !text-[16px]",
56
56
  color: "#494A4880",
57
57
  sx: {
@@ -9,6 +9,9 @@ var _react = _interopRequireWildcard(require("react"));
9
9
  var _material = require("@mui/material");
10
10
  var _svgs = require("./components/svgs");
11
11
  var _RecognitionListItem = _interopRequireDefault(require("./components/RecognitionListItem"));
12
+ var _recorderJs = _interopRequireDefault(require("recorder-js"));
13
+ var _recorder = require("./recorder");
14
+ var _HistoryDropdownItem = _interopRequireDefault(require("./components/HistoryDropdownItem"));
12
15
  var _jsxRuntime = require("react/jsx-runtime");
13
16
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
14
17
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
@@ -56,6 +59,14 @@ const StyledTypography = (0, _material.styled)(_material.Typography)(_ref3 => {
56
59
  lineHeight: '15.59px'
57
60
  };
58
61
  });
62
+ const formatDate = date => {
63
+ const day = date.getDate().toString().padStart(2, '0');
64
+ const month = date.toLocaleString('en-US', {
65
+ month: 'short'
66
+ });
67
+ const year = date.getFullYear();
68
+ return `${day}.${month}.${year}`;
69
+ };
59
70
  const Recognition = _ref4 => {
60
71
  let {
61
72
  mode = 'recorder',
@@ -73,12 +84,16 @@ const Recognition = _ref4 => {
73
84
  const [selectedVoice, setSelectedVoice] = (0, _react.useState)("");
74
85
  const [voiceList, setVoiceList] = (0, _react.useState)([]);
75
86
  const languageList = ['Auto-Detect', 'English', 'Chinese (Simplified)'];
76
- const [selectedLanguage, setSelectedLanguage] = (0, _react.useState)("");
87
+ const [selectedLanguage, setSelectedLanguage] = (0, _react.useState)(0);
77
88
  const recognitionRef = (0, _react.useRef)(null);
89
+ const mediaRecorderRef = (0, _react.useRef)(null);
78
90
  const [result, setResult] = (0, _react.useState)([]);
79
91
  const [historyList, setHistoryList] = (0, _react.useState)(recognitionHistoryList);
92
+ const [filterHistoryList, setFilterHistoryList] = (0, _react.useState)([]);
93
+ const [dropdownList, setDropdownList] = (0, _react.useState)([]);
80
94
  const [recordTime, setRecordTime] = (0, _react.useState)(0);
81
95
  const [intervalId, setIntervalId] = (0, _react.useState)(null);
96
+ const [selectedDate, setSelectedDate] = (0, _react.useState)(formatDate(new Date()));
82
97
  const handleClickOpen = () => {
83
98
  setOpen(true);
84
99
  };
@@ -118,34 +133,70 @@ const Recognition = _ref4 => {
118
133
  const handleLanguageChange = event => {
119
134
  setSelectedLanguage(event.target.value);
120
135
  };
121
- const startRecording = () => {
122
- if (recognitionRef.current) {
123
- setResult([]);
124
- setRecordTime(0);
125
- const id = setInterval(async () => {
126
- setRecordTime(prevCount => prevCount + 1);
127
- }, 1000);
128
- setIntervalId(id);
129
- recognitionRef.current.start();
136
+ const startRecording = async () => {
137
+ try {
138
+ if (recognitionRef.current) {
139
+ recognitionRef.current.lang = selectedLanguage === 0 || selectedLanguage === 1 ? "en-US" : "zh-TW";
140
+ if (!mediaRecorderRef.current) {
141
+ const stream = await navigator.mediaDevices.getUserMedia({
142
+ audio: true
143
+ });
144
+ const audioContext = new (window.AudioContext || window.webkitAudioContext)();
145
+ const newRecorder = new _recorderJs.default(audioContext);
146
+ await newRecorder.init(stream);
147
+ mediaRecorderRef.current = newRecorder;
148
+ }
149
+ mediaRecorderRef.current.start();
150
+ setResult([]);
151
+ setRecordTime(0);
152
+ const id = setInterval(async () => {
153
+ setRecordTime(prevCount => prevCount + 1);
154
+ }, 1000);
155
+ setIntervalId(id);
156
+ recognitionRef.current.start();
157
+ }
158
+ } catch (error) {
159
+ console.error("Error starting recording:", error);
130
160
  }
131
161
  };
132
162
  const stopRecording = () => {
133
- if (recognitionRef.current) {
163
+ if (recognitionRef.current && mediaRecorderRef.current) {
134
164
  recognitionRef.current.stop();
135
165
  clearInterval(intervalId);
136
- let temp = [...historyList];
137
- const newData = {
138
- result,
139
- date: new Date()
140
- };
141
- temp.push(newData);
142
- setHistoryList(temp);
143
- if (onNewRecognitionEvent) {
144
- onNewRecognitionEvent(newData);
145
- }
146
- if (onRecognitionDataChange) {
147
- onRecognitionDataChange(temp);
148
- }
166
+ mediaRecorderRef.current.stop().then(async _ref5 => {
167
+ let {
168
+ blob
169
+ } = _ref5;
170
+ if (result.length > 0) {
171
+ let temp = [...historyList];
172
+ const newData = {
173
+ created_at: Math.floor(new Date().getTime() / 1000),
174
+ file_name: (0, _recorder.getVoiceFileName)(new Date()),
175
+ link_id: "",
176
+ union_id: "",
177
+ voice_duration: "",
178
+ voice_file: URL.createObjectURL(blob),
179
+ voice_id: "",
180
+ voice_size: "",
181
+ voice_words: result.join(',')
182
+ };
183
+ temp.push(newData);
184
+ setHistoryList(temp);
185
+ setSelectedDate(formatDate(new Date()));
186
+ if (onNewRecognitionEvent) {
187
+ onNewRecognitionEvent({
188
+ fileName: (0, _recorder.getVoiceFileName)(new Date()),
189
+ audioBlob: blob,
190
+ result,
191
+ lang: selectedLanguage === 0 || selectedLanguage === 1 ? "en-US" : "zh-TW",
192
+ date: new Date()
193
+ });
194
+ }
195
+ if (onRecognitionDataChange) {
196
+ onRecognitionDataChange(temp);
197
+ }
198
+ }
199
+ });
149
200
  }
150
201
  };
151
202
  const startSpeechRecognition = () => {
@@ -154,9 +205,9 @@ const Recognition = _ref4 => {
154
205
  const recognition = new SpeechRecognition();
155
206
  recognition.continuous = true;
156
207
  recognition.interimResults = true;
157
- recognition.lang = 'en-US';
208
+ recognition.lang = selectedLanguage === 0 || selectedLanguage === 1 ? "en-US" : "zh-TW";
158
209
  recognition.onstart = () => {
159
- console.log('Recording started');
210
+ console.log('Speech recognition started');
160
211
  };
161
212
  recognition.onresult = event => {
162
213
  setResult(prevTranscript => {
@@ -183,6 +234,15 @@ const Recognition = _ref4 => {
183
234
  console.error('Speech recognition not supported');
184
235
  }
185
236
  };
237
+ function formatDateTimestamp(timestamp) {
238
+ const date = new Date(timestamp * 1000);
239
+ const day = date.getDate().toString().padStart(2, '0');
240
+ const month = date.toLocaleString('en-US', {
241
+ month: 'short'
242
+ });
243
+ const year = date.getFullYear();
244
+ return `${day}.${month}.${year}`;
245
+ }
186
246
  (0, _react.useEffect)(() => {
187
247
  const fetchAudioInputDevices = async () => {
188
248
  try {
@@ -205,6 +265,40 @@ const Recognition = _ref4 => {
205
265
  startSpeechRecognition();
206
266
  fetchAudioInputDevices();
207
267
  }, []);
268
+ (0, _react.useEffect)(() => {
269
+ const groupedData = historyList.reduce((acc, item) => {
270
+ const date = formatDateTimestamp(item.created_at);
271
+ if (!acc[date]) {
272
+ acc[date] = [];
273
+ }
274
+ acc[date].push(item);
275
+ return acc;
276
+ }, {});
277
+ const dropdown = Object.keys(groupedData).map(date => {
278
+ const totalCount = groupedData[date].reduce((sum, item) => {
279
+ if (item.voice_words) {
280
+ sum += item.voice_words.split(',').length;
281
+ }
282
+ return sum;
283
+ }, 0);
284
+ return {
285
+ date: date,
286
+ count: totalCount
287
+ };
288
+ });
289
+ setDropdownList(dropdown);
290
+ }, [historyList]);
291
+ (0, _react.useEffect)(() => {
292
+ const groupedData = historyList.reduce((acc, item) => {
293
+ const date = formatDateTimestamp(item.created_at);
294
+ if (!acc[date]) {
295
+ acc[date] = [];
296
+ }
297
+ acc[date].push(item);
298
+ return acc;
299
+ }, {});
300
+ setFilterHistoryList(groupedData[selectedDate] ? groupedData[selectedDate] : []);
301
+ }, [selectedDate, historyList]);
208
302
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Box, {
209
303
  className: "bg-white rounded-[5px] p-[20px] w-[440px]",
210
304
  sx: {
@@ -395,14 +489,14 @@ const Recognition = _ref4 => {
395
489
  textTransform: "none"
396
490
  },
397
491
  onClick: handlePopoverOpen,
398
- children: "02.July.2024"
492
+ children: selectedDate
399
493
  })]
400
494
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Box, {
401
495
  className: "flex flex-col scrollableBox mt-1",
402
496
  sx: {
403
497
  maxHeight: "160px"
404
498
  },
405
- children: historyList.map((history, index) => {
499
+ children: filterHistoryList.map((history, index) => {
406
500
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_RecognitionListItem.default, {
407
501
  data: history
408
502
  }, index);
@@ -935,47 +1029,18 @@ const Recognition = _ref4 => {
935
1029
  color: "#494A48B2",
936
1030
  children: "Data"
937
1031
  })
938
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Box, {
939
- className: "flex items-center justify-between rounded-[5px] px-[10px] py-[3px] cursor-pointer",
1032
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Box, {
1033
+ className: "flex flex-col scrollableBox mt-1",
940
1034
  sx: {
941
- '&:hover': {
942
- background: '#F6F6F6'
943
- }
1035
+ maxHeight: "110px"
944
1036
  },
945
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Box, {
946
- className: "flex items-center space-x-1",
947
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
948
- className: "!font-bold !text-[14px]",
949
- color: "#494A48",
950
- children: "7"
951
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
952
- className: "!font-400 !text-[12px]",
953
- color: "#494A48",
954
- children: "words"
955
- })]
956
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
957
- className: "!font-400 !text-[14px]",
958
- color: "#494A48",
959
- children: "02.July.2024"
960
- })]
961
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Box, {
962
- className: "flex items-center justify-between px-[10px] py-[3px]",
963
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Box, {
964
- className: "flex items-center space-x-1",
965
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
966
- className: "!font-bold !text-[14px]",
967
- color: "#494A48",
968
- children: "7"
969
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
970
- className: "!font-400 !text-[12px]",
971
- color: "#494A48",
972
- children: "words"
973
- })]
974
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
975
- className: "!font-400 !text-[14px]",
976
- color: "#494A48",
977
- children: "02.July.2024"
978
- })]
1037
+ children: dropdownList.map((dropdown, index) => {
1038
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_HistoryDropdownItem.default, {
1039
+ data: dropdown,
1040
+ setDate: setSelectedDate,
1041
+ handlePopoverClose: handlePopoverClose
1042
+ }, index);
1043
+ })
979
1044
  })]
980
1045
  })
981
1046
  })]
package/dist/recorder.js CHANGED
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.default = void 0;
7
+ exports.getVoiceFileName = exports.default = void 0;
8
8
  var _react = _interopRequireWildcard(require("react"));
9
9
  var _material = require("@mui/material");
10
10
  var _Grid = _interopRequireDefault(require("@mui/material/Grid2"));
@@ -15,7 +15,6 @@ var _recorderJs = _interopRequireDefault(require("recorder-js"));
15
15
  var _jsxRuntime = require("react/jsx-runtime");
16
16
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
17
17
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
18
- const apiUrl = 'https://api.origintechx.dev/qa/v1/diagnose/voice';
19
18
  const getVoiceFileName = date => {
20
19
  const year = date.getFullYear(); // Get the full year (YYYY)
21
20
  const month = String(date.getMonth() + 1).padStart(2, '0'); // Get the month (MM), pad with leading zero if necessary
@@ -23,6 +22,7 @@ const getVoiceFileName = date => {
23
22
 
24
23
  return `Voice${year}${month}${day}.wav`;
25
24
  };
25
+ exports.getVoiceFileName = getVoiceFileName;
26
26
  const getTimeValues = totalSeconds => {
27
27
  const hours = Math.floor(totalSeconds / 3600); // Get hours
28
28
  let minutes = Math.floor(totalSeconds % 3600 / 60); // Get minutes
@@ -63,7 +63,6 @@ const RecorderBox = _ref => {
63
63
  const [isRunning, setIsRunning] = (0, _react.useState)(false);
64
64
  const [intervalId, setIntervalId] = (0, _react.useState)(null);
65
65
  const [audioBlob, setAudioBlob] = (0, _react.useState)(null);
66
- const [audioUrl, setAudioUrl] = (0, _react.useState)('');
67
66
  const [audioSize, setAudioSize] = (0, _react.useState)(0);
68
67
  const mediaRecorderRef = (0, _react.useRef)(null);
69
68
  const handleVoiceChange = event => {
@@ -104,8 +103,6 @@ const RecorderBox = _ref => {
104
103
  blob
105
104
  } = _ref2;
106
105
  setAudioBlob(blob);
107
- setAudioUrl(URL.createObjectURL(blob));
108
- console.log(blob);
109
106
  let temp = [...recordList];
110
107
  const newVoice = {
111
108
  audioURL: URL.createObjectURL(blob),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dmed-voice-assistant",
3
- "version": "1.2.2",
3
+ "version": "1.2.4",
4
4
  "main": "dist/index.js",
5
5
  "files": [
6
6
  "dist"