@iobroker/adapter-react-v5 7.0.2 → 7.1.0
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/Components/404.d.ts +3 -2
- package/Components/404.js +3 -2
- package/Components/ColorPicker.d.ts +22 -8
- package/Components/ColorPicker.js +34 -17
- package/Components/ComplexCron.js +24 -24
- package/Components/CopyToClipboard.d.ts +10 -1
- package/Components/CopyToClipboard.js +17 -8
- package/Components/CustomModal.d.ts +1 -1
- package/Components/CustomModal.js +8 -8
- package/Components/FileBrowser.d.ts +11 -11
- package/Components/FileBrowser.js +135 -152
- package/Components/FileViewer.js +34 -23
- package/Components/Icon.d.ts +16 -2
- package/Components/Icon.js +19 -8
- package/Components/IconPicker.js +10 -14
- package/Components/IconSelector.d.ts +1 -1
- package/Components/IconSelector.js +64 -74
- package/Components/Image.d.ts +8 -4
- package/Components/Image.js +13 -32
- package/Components/Loader.d.ts +2 -2
- package/Components/Loader.js +21 -18
- package/Components/Loaders/MV.d.ts +6 -1
- package/Components/Loaders/MV.js +23 -7
- package/Components/Loaders/PT.d.ts +7 -2
- package/Components/Loaders/PT.js +20 -7
- package/Components/Loaders/Vendor.d.ts +2 -2
- package/Components/Loaders/Vendor.js +15 -7
- package/Components/Logo.js +16 -18
- package/Components/MDUtils.d.ts +1 -1
- package/Components/MDUtils.js +8 -4
- package/Components/ObjectBrowser.d.ts +40 -39
- package/Components/ObjectBrowser.js +550 -435
- package/Components/Router.d.ts +1 -3
- package/Components/Router.js +3 -1
- package/Components/SaveCloseButtons.d.ts +3 -3
- package/Components/SaveCloseButtons.js +3 -3
- package/Components/Schedule.d.ts +15 -15
- package/Components/Schedule.js +177 -154
- package/Components/SelectWithIcon.d.ts +2 -2
- package/Components/SelectWithIcon.js +45 -34
- package/Components/SimpleCron/index.js +83 -43
- package/Components/TabContainer.js +2 -2
- package/Components/TabContent.js +1 -1
- package/Components/TabHeader.js +1 -1
- package/Components/TableResize.d.ts +2 -2
- package/Components/TableResize.js +5 -5
- package/Components/TextWithIcon.d.ts +1 -1
- package/Components/TextWithIcon.js +10 -8
- package/Components/ToggleThemeMenu.d.ts +2 -2
- package/Components/ToggleThemeMenu.js +3 -3
- package/Components/TreeTable.d.ts +18 -18
- package/Components/TreeTable.js +76 -72
- package/Components/UploadImage.d.ts +2 -2
- package/Components/UploadImage.js +25 -21
- package/Components/Utils.d.ts +42 -22
- package/Components/Utils.js +66 -65
- package/Components/withWidth.d.ts +2 -2
- package/Components/withWidth.js +10 -6
- package/Dialogs/ComplexCron.d.ts +2 -2
- package/Dialogs/ComplexCron.js +3 -3
- package/Dialogs/Confirm.d.ts +4 -4
- package/Dialogs/Confirm.js +18 -8
- package/Dialogs/Cron.d.ts +3 -3
- package/Dialogs/Cron.js +21 -17
- package/Dialogs/Error.d.ts +3 -3
- package/Dialogs/Error.js +6 -4
- package/Dialogs/Message.d.ts +3 -3
- package/Dialogs/Message.js +6 -4
- package/Dialogs/SelectFile.d.ts +4 -4
- package/Dialogs/SelectFile.js +6 -4
- package/Dialogs/SelectID.d.ts +12 -10
- package/Dialogs/SelectID.js +12 -8
- package/Dialogs/SimpleCron.d.ts +2 -2
- package/Dialogs/SimpleCron.js +2 -2
- package/Dialogs/TextInput.d.ts +2 -2
- package/Dialogs/TextInput.js +3 -3
- package/GenericApp.d.ts +19 -13
- package/GenericApp.js +128 -85
- package/LegacyConnection.d.ts +240 -248
- package/LegacyConnection.js +500 -525
- package/README.md +1234 -1170
- package/Theme.d.ts +1 -1
- package/Theme.js +9 -12
- package/assets/devices.json +1 -0
- package/assets/rooms.json +1 -0
- package/craco-module-federation.js +3 -12
- package/i18n/de.json +434 -434
- package/i18n/en.json +434 -434
- package/i18n/es.json +434 -434
- package/i18n/fr.json +434 -434
- package/i18n/it.json +434 -434
- package/i18n/nl.json +434 -434
- package/i18n/pl.json +434 -434
- package/i18n/pt.json +434 -434
- package/i18n/ru.json +434 -434
- package/i18n/uk.json +434 -434
- package/i18n/zh-cn.json +434 -434
- package/i18n.d.ts +26 -19
- package/i18n.js +28 -22
- package/icons/IconAdapter.js +2 -2
- package/icons/IconAlias.js +2 -2
- package/icons/IconChannel.js +2 -2
- package/icons/IconClearFilter.js +2 -2
- package/icons/IconClosed.js +2 -2
- package/icons/IconCopy.js +2 -2
- package/icons/IconDevice.js +2 -2
- package/icons/IconDocument.js +2 -2
- package/icons/IconDocumentReadOnly.js +2 -2
- package/icons/IconExpert.js +2 -2
- package/icons/IconFx.js +2 -2
- package/icons/IconInstance.js +2 -2
- package/icons/IconLogout.js +2 -2
- package/icons/IconNoIcon.js +2 -2
- package/icons/IconOpen.d.ts +2 -2
- package/icons/IconOpen.js +2 -2
- package/icons/IconProps.d.ts +4 -3
- package/icons/IconState.d.ts +2 -2
- package/icons/IconState.js +2 -2
- package/index.css +3 -2
- package/package.json +1 -1
- package/src/Components/404.tsx +32 -31
- package/src/Components/ColorPicker.tsx +142 -114
- package/src/Components/ComplexCron.tsx +174 -137
- package/src/Components/CopyToClipboard.tsx +22 -9
- package/src/Components/CustomModal.tsx +76 -69
- package/src/Components/FileBrowser.tsx +959 -852
- package/src/Components/FileViewer.tsx +146 -127
- package/src/Components/Icon.tsx +80 -52
- package/src/Components/IconPicker.tsx +83 -67
- package/src/Components/IconSelector.tsx +159 -141
- package/src/Components/Image.tsx +43 -26
- package/src/Components/Loader.tsx +56 -32
- package/src/Components/Logo.tsx +62 -52
- package/src/Components/MDUtils.tsx +10 -6
- package/src/Components/ObjectBrowser.tsx +3198 -2478
- package/src/Components/Router.tsx +11 -11
- package/src/Components/SaveCloseButtons.tsx +43 -39
- package/src/Components/Schedule.tsx +1091 -853
- package/src/Components/SelectWithIcon.tsx +135 -93
- package/src/Components/TabContainer.tsx +21 -19
- package/src/Components/TabContent.tsx +13 -12
- package/src/Components/TabHeader.tsx +10 -9
- package/src/Components/TableResize.tsx +52 -37
- package/src/Components/TextWithIcon.tsx +30 -19
- package/src/Components/ToggleThemeMenu.tsx +31 -13
- package/src/Components/TreeTable.tsx +468 -385
- package/src/Components/UploadImage.tsx +153 -121
- package/src/Components/Utils.tsx +135 -127
- package/src/Components/loader.css +40 -31
- package/src/Components/withWidth.tsx +23 -12
- package/src/Connection.tsx +1 -3
- package/src/Dialogs/ComplexCron.tsx +55 -61
- package/src/Dialogs/Confirm.tsx +88 -65
- package/src/Dialogs/Cron.tsx +122 -112
- package/src/Dialogs/Error.tsx +37 -42
- package/src/Dialogs/Message.tsx +39 -37
- package/src/Dialogs/SelectFile.tsx +95 -85
- package/src/Dialogs/SelectID.tsx +141 -129
- package/src/Dialogs/SimpleCron.tsx +44 -44
- package/src/Dialogs/TextInput.tsx +60 -68
- package/src/GenericApp.tsx +342 -242
- package/src/LegacyConnection.tsx +972 -842
- package/src/Prompt.tsx +3 -1
- package/src/Theme.tsx +19 -26
- package/src/icons/IconAdapter.tsx +16 -14
- package/src/icons/IconAlias.tsx +16 -14
- package/src/icons/IconChannel.tsx +55 -16
- package/src/icons/IconClearFilter.tsx +17 -15
- package/src/icons/IconClosed.tsx +16 -11
- package/src/icons/IconCopy.tsx +16 -11
- package/src/icons/IconDevice.tsx +121 -22
- package/src/icons/IconDocument.tsx +16 -11
- package/src/icons/IconDocumentReadOnly.tsx +21 -12
- package/src/icons/IconExpert.tsx +20 -12
- package/src/icons/IconFx.tsx +16 -14
- package/src/icons/IconInstance.tsx +16 -14
- package/src/icons/IconLogout.tsx +20 -18
- package/src/icons/IconNoIcon.tsx +16 -14
- package/src/icons/IconOpen.tsx +17 -12
- package/src/icons/IconProps.tsx +4 -3
- package/src/icons/IconState.tsx +34 -13
- package/src/index.css +3 -2
- package/tasks.js +91 -0
- package/types.d.ts +141 -0
- package/Components/Loaders/PT.css +0 -109
- package/Components/Loaders/Vendor.css +0 -13
- package/Components/loader.css +0 -222
- package/Components/types.d.ts +0 -82
- package/assets/devices/Alarm Systems.svg +0 -19
- package/assets/devices/Amplifier.svg +0 -22
- package/assets/devices/Awnings.svg +0 -5
- package/assets/devices/Battery Status.svg +0 -5
- package/assets/devices/Ceiling Spotlights.svg +0 -16
- package/assets/devices/Chandelier.svg +0 -7
- package/assets/devices/Climate.svg +0 -12
- package/assets/devices/Coffee Makers.svg +0 -6
- package/assets/devices/Cold Water.svg +0 -31
- package/assets/devices/Computer.svg +0 -21
- package/assets/devices/Consumption.svg +0 -8
- package/assets/devices/Curtains.svg +0 -43
- package/assets/devices/Dishwashers.svg +0 -12
- package/assets/devices/Doors.svg +0 -6
- package/assets/devices/Doorstep.svg +0 -35
- package/assets/devices/Dryer.svg +0 -14
- package/assets/devices/Fan.svg +0 -20
- package/assets/devices/Floor Lamps.svg +0 -5
- package/assets/devices/Garage Doors.svg +0 -9
- package/assets/devices/Gates.svg +0 -32
- package/assets/devices/Hairdryer.svg +0 -23
- package/assets/devices/Handle.svg +0 -6
- package/assets/devices/Hanging Lamps.svg +0 -9
- package/assets/devices/Heater.svg +0 -44
- package/assets/devices/Hoods.svg +0 -12
- package/assets/devices/Hot Water.svg +0 -10
- package/assets/devices/Humidity.svg +0 -41
- package/assets/devices/Iron.svg +0 -5
- package/assets/devices/Irrigation.svg +0 -23
- package/assets/devices/Led Strip.svg +0 -31
- package/assets/devices/Light.svg +0 -30
- package/assets/devices/Lightings.svg +0 -46
- package/assets/devices/Lock.svg +0 -19
- package/assets/devices/Louvre.svg +0 -7
- package/assets/devices/Mowing Machine.svg +0 -9
- package/assets/devices/Music.svg +0 -13
- package/assets/devices/Outdoor Blinds.svg +0 -7
- package/assets/devices/People.svg +0 -19
- package/assets/devices/Pool.svg +0 -8
- package/assets/devices/Power Consumption.svg +0 -13
- package/assets/devices/Printer.svg +0 -10
- package/assets/devices/Pump.svg +0 -10
- package/assets/devices/Receiver.svg +0 -19
- package/assets/devices/Sconces.svg +0 -10
- package/assets/devices/Security.svg +0 -34
- package/assets/devices/Shading.svg +0 -5
- package/assets/devices/Shutters.svg +0 -11
- package/assets/devices/SmokeDetector.svg +0 -13
- package/assets/devices/Sockets.svg +0 -13
- package/assets/devices/Speaker.svg +0 -35
- package/assets/devices/Stove.svg +0 -12
- package/assets/devices/Table Lamps.svg +0 -12
- package/assets/devices/Temperature Sensors.svg +0 -28
- package/assets/devices/Tv.svg +0 -8
- package/assets/devices/Vacuum Cleaner.svg +0 -16
- package/assets/devices/Ventilation.svg +0 -12
- package/assets/devices/Washing Machines.svg +0 -16
- package/assets/devices/Water Consumption.svg +0 -6
- package/assets/devices/Water Heater.svg +0 -8
- package/assets/devices/Water.svg +0 -40
- package/assets/devices/Weather.svg +0 -28
- package/assets/devices/Window.svg +0 -8
- package/assets/rooms/Anteroom.svg +0 -53
- package/assets/rooms/Attic.svg +0 -21
- package/assets/rooms/Balcony.svg +0 -13
- package/assets/rooms/Barn.svg +0 -6
- package/assets/rooms/Basement.svg +0 -5
- package/assets/rooms/Bathroom.svg +0 -38
- package/assets/rooms/Bedroom.svg +0 -5
- package/assets/rooms/Boiler Room.svg +0 -13
- package/assets/rooms/Carport.svg +0 -17
- package/assets/rooms/Cellar.svg +0 -89
- package/assets/rooms/Chamber.svg +0 -9
- package/assets/rooms/Corridor.svg +0 -53
- package/assets/rooms/Dining Area.svg +0 -37
- package/assets/rooms/Dining Room.svg +0 -37
- package/assets/rooms/Dining.svg +0 -37
- package/assets/rooms/Dressing Room.svg +0 -5
- package/assets/rooms/Driveway.svg +0 -15
- package/assets/rooms/Entrance.svg +0 -44
- package/assets/rooms/Equipment Room.svg +0 -15
- package/assets/rooms/Front Yard.svg +0 -64
- package/assets/rooms/Gallery.svg +0 -14
- package/assets/rooms/Garage.svg +0 -20
- package/assets/rooms/Garden.svg +0 -13
- package/assets/rooms/Ground Floor.svg +0 -95
- package/assets/rooms/Guest Bathroom.svg +0 -33
- package/assets/rooms/Guest Room.svg +0 -5
- package/assets/rooms/Gym.svg +0 -5
- package/assets/rooms/Hall.svg +0 -19
- package/assets/rooms/Home Theater.svg +0 -8
- package/assets/rooms/Kitchen.svg +0 -18
- package/assets/rooms/Laundry Room.svg +0 -12
- package/assets/rooms/Living Area.svg +0 -11
- package/assets/rooms/Living Room.svg +0 -10
- package/assets/rooms/Locker Room.svg +0 -17
- package/assets/rooms/Nursery.svg +0 -5
- package/assets/rooms/Office.svg +0 -8
- package/assets/rooms/Outdoors.svg +0 -7
- package/assets/rooms/Playroom.svg +0 -6
- package/assets/rooms/Pool.svg +0 -8
- package/assets/rooms/Rear Wall.svg +0 -30
- package/assets/rooms/Second Floor.svg +0 -95
- package/assets/rooms/Shed.svg +0 -16
- package/assets/rooms/Sleeping Area.svg +0 -22
- package/assets/rooms/Stairway.svg +0 -5
- package/assets/rooms/Stairwell.svg +0 -15
- package/assets/rooms/Storeroom.svg +0 -5
- package/assets/rooms/Summer House.svg +0 -27
- package/assets/rooms/Swimming Pool.svg +0 -21
- package/assets/rooms/Terrace.svg +0 -7
- package/assets/rooms/Toilet.svg +0 -10
- package/assets/rooms/Upstairs.svg +0 -6
- package/assets/rooms/Wardrobe.svg +0 -60
- package/assets/rooms/Washroom.svg +0 -20
- package/assets/rooms/Wc.svg +0 -10
- package/assets/rooms/Windscreen.svg +0 -60
- package/assets/rooms/Workshop.svg +0 -23
- package/assets/rooms/Workspace.svg +0 -8
|
@@ -2,30 +2,18 @@
|
|
|
2
2
|
// import { Buffer } from 'buffer';
|
|
3
3
|
import React, { Component } from 'react';
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
TextField,
|
|
7
|
-
Button,
|
|
8
|
-
Dialog,
|
|
9
|
-
DialogActions,
|
|
10
|
-
DialogContent,
|
|
11
|
-
DialogTitle,
|
|
12
|
-
IconButton,
|
|
13
|
-
} from '@mui/material';
|
|
5
|
+
import { TextField, Button, Dialog, DialogActions, DialogContent, DialogTitle, IconButton } from '@mui/material';
|
|
14
6
|
|
|
15
7
|
// Icons
|
|
16
8
|
import { FaCopy as CopyIcon } from 'react-icons/fa';
|
|
17
|
-
import {
|
|
18
|
-
Close as CloseIcon,
|
|
19
|
-
Save as SaveIcon,
|
|
20
|
-
Brightness6 as Brightness5Icon,
|
|
21
|
-
} from '@mui/icons-material';
|
|
9
|
+
import { Close as CloseIcon, Save as SaveIcon, Brightness6 as Brightness5Icon } from '@mui/icons-material';
|
|
22
10
|
|
|
23
11
|
import type { Connection } from '@iobroker/socket-client';
|
|
24
12
|
|
|
25
13
|
import IconNoIcon from '../icons/IconNoIcon';
|
|
26
14
|
import withWidth from './withWidth';
|
|
27
15
|
import Utils from './Utils';
|
|
28
|
-
import { Translate } from '../types';
|
|
16
|
+
import type { Translate } from '../types';
|
|
29
17
|
import Icon from './Icon';
|
|
30
18
|
// File viewer in adapter-react does not use ace editor
|
|
31
19
|
// import * as ace from 'ace-builds';
|
|
@@ -61,13 +49,13 @@ const styles: Record<string, React.CSSProperties> = {
|
|
|
61
49
|
|
|
62
50
|
export const EXTENSIONS = {
|
|
63
51
|
images: ['png', 'jpg', 'svg', 'jpeg', 'bmp', 'gif', 'apng', 'avif', 'webp'],
|
|
64
|
-
code:
|
|
65
|
-
txt:
|
|
66
|
-
audio:
|
|
67
|
-
video:
|
|
52
|
+
code: ['js', 'json', 'json5', 'md'],
|
|
53
|
+
txt: ['log', 'txt', 'html', 'css', 'xml', 'ics'],
|
|
54
|
+
audio: ['mp3', 'wav', 'ogg', 'acc'],
|
|
55
|
+
video: ['mp4', 'mov', 'avi'],
|
|
68
56
|
};
|
|
69
57
|
|
|
70
|
-
function bufferToBase64(buffer: Buffer, isFull?: boolean) {
|
|
58
|
+
function bufferToBase64(buffer: Buffer, isFull?: boolean): string {
|
|
71
59
|
let binary = '';
|
|
72
60
|
const bytes = new Uint8Array(buffer);
|
|
73
61
|
const len = bytes.byteLength;
|
|
@@ -126,21 +114,25 @@ class FileViewer extends Component<FileViewerProps, FileViewerState> {
|
|
|
126
114
|
};
|
|
127
115
|
}
|
|
128
116
|
|
|
129
|
-
readFile() {
|
|
117
|
+
readFile(): void {
|
|
130
118
|
if (this.props.href) {
|
|
131
119
|
const parts = this.props.href.split('/');
|
|
132
120
|
parts.splice(0, 2);
|
|
133
121
|
const adapter = parts[0];
|
|
134
122
|
const name = parts.splice(1).join('/');
|
|
135
123
|
|
|
136
|
-
this.props.socket
|
|
124
|
+
this.props.socket
|
|
125
|
+
.readFile(adapter, name)
|
|
137
126
|
.then((data: { data: Buffer; type: string } | { file: string; mimeType: string }) => {
|
|
138
|
-
let fileData
|
|
127
|
+
let fileData = '';
|
|
139
128
|
if ((data as { file: string; mimeType: string }).file !== undefined) {
|
|
140
129
|
fileData = (data as { file: string; mimeType: string }).file;
|
|
141
130
|
}
|
|
142
131
|
|
|
143
|
-
const newState: Partial<FileViewerState> = {
|
|
132
|
+
const newState: Partial<FileViewerState> = {
|
|
133
|
+
copyPossible: this.state.copyPossible,
|
|
134
|
+
ext: this.state.ext,
|
|
135
|
+
};
|
|
144
136
|
// try to detect valid extension
|
|
145
137
|
if ((data as { data: Buffer; type: string }).type === 'Buffer') {
|
|
146
138
|
if (name.toLowerCase().endsWith('.json5')) {
|
|
@@ -153,7 +145,9 @@ class FileViewer extends Component<FileViewerProps, FileViewerState> {
|
|
|
153
145
|
fileData = '';
|
|
154
146
|
}
|
|
155
147
|
} else {
|
|
156
|
-
const ext = Utils.detectMimeType(
|
|
148
|
+
const ext = Utils.detectMimeType(
|
|
149
|
+
bufferToBase64((data as { data: Buffer; type: string }).data),
|
|
150
|
+
);
|
|
157
151
|
if (ext) {
|
|
158
152
|
newState.ext = ext;
|
|
159
153
|
newState.copyPossible = EXTENSIONS.code.includes(ext) || EXTENSIONS.txt.includes(ext);
|
|
@@ -177,7 +171,7 @@ class FileViewer extends Component<FileViewerProps, FileViewerState> {
|
|
|
177
171
|
}
|
|
178
172
|
}
|
|
179
173
|
|
|
180
|
-
componentDidMount() {
|
|
174
|
+
componentDidMount(): void {
|
|
181
175
|
this.readFile();
|
|
182
176
|
|
|
183
177
|
const parts = this.props.href.split('/');
|
|
@@ -186,11 +180,13 @@ class FileViewer extends Component<FileViewerProps, FileViewerState> {
|
|
|
186
180
|
const name = parts.splice(1).join('/');
|
|
187
181
|
|
|
188
182
|
if (this.props.supportSubscribes) {
|
|
189
|
-
this.props.socket
|
|
183
|
+
this.props.socket
|
|
184
|
+
.subscribeFiles(adapter, name, this.onFileChanged)
|
|
185
|
+
.catch(e => window.alert(`Cannot subscribe on file: ${e}`));
|
|
190
186
|
}
|
|
191
187
|
}
|
|
192
188
|
|
|
193
|
-
componentWillUnmount() {
|
|
189
|
+
componentWillUnmount(): void {
|
|
194
190
|
if (this.timeout) {
|
|
195
191
|
clearTimeout(this.timeout);
|
|
196
192
|
this.timeout = null;
|
|
@@ -200,11 +196,13 @@ class FileViewer extends Component<FileViewerProps, FileViewerState> {
|
|
|
200
196
|
const adapter = parts[0];
|
|
201
197
|
const name = parts.splice(1).join('/');
|
|
202
198
|
if (this.props.supportSubscribes) {
|
|
203
|
-
this.props.socket
|
|
199
|
+
this.props.socket
|
|
200
|
+
.subscribeFiles(adapter, name, this.onFileChanged)
|
|
201
|
+
.catch(e => window.alert(`Cannot subscribe on file: ${e}`));
|
|
204
202
|
}
|
|
205
203
|
}
|
|
206
204
|
|
|
207
|
-
onFileChanged = (
|
|
205
|
+
onFileChanged = (_id: string, _fileName: string, size: number | null): void => {
|
|
208
206
|
if (!this.state.changed) {
|
|
209
207
|
if (this.timeout) {
|
|
210
208
|
clearTimeout(this.timeout);
|
|
@@ -223,7 +221,7 @@ class FileViewer extends Component<FileViewerProps, FileViewerState> {
|
|
|
223
221
|
};
|
|
224
222
|
|
|
225
223
|
// eslint-disable-next-line class-methods-use-this
|
|
226
|
-
writeFile64 = () => {
|
|
224
|
+
writeFile64 = (): void => {
|
|
227
225
|
/*
|
|
228
226
|
// File viewer in adapter-react does not support write
|
|
229
227
|
const parts = this.props.href.split('/');
|
|
@@ -237,7 +235,7 @@ class FileViewer extends Component<FileViewerProps, FileViewerState> {
|
|
|
237
235
|
*/
|
|
238
236
|
};
|
|
239
237
|
|
|
240
|
-
static getEditFile(ext: string | null) {
|
|
238
|
+
static getEditFile(ext: string | null): 'json' | 'json5' | 'javascript' | 'html' | 'text' {
|
|
241
239
|
switch (ext) {
|
|
242
240
|
case 'json':
|
|
243
241
|
return 'json';
|
|
@@ -255,38 +253,41 @@ class FileViewer extends Component<FileViewerProps, FileViewerState> {
|
|
|
255
253
|
}
|
|
256
254
|
}
|
|
257
255
|
|
|
258
|
-
getContent() {
|
|
256
|
+
getContent(): React.JSX.Element | null {
|
|
259
257
|
if (this.state.ext && EXTENSIONS.images.includes(this.state.ext)) {
|
|
260
258
|
if (this.state.imgError) {
|
|
261
259
|
return <IconNoIcon style={{ ...styles.img, ...this.props.getStyleBackgroundImage() }} />;
|
|
262
260
|
}
|
|
263
|
-
return
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
261
|
+
return (
|
|
262
|
+
<Icon
|
|
263
|
+
onError={e => {
|
|
264
|
+
(e.target as HTMLImageElement).onerror = null;
|
|
265
|
+
this.setState({ imgError: true });
|
|
266
|
+
}}
|
|
267
|
+
style={{ ...styles.img, ...this.props.getStyleBackgroundImage() }}
|
|
268
|
+
src={`${this.props.href}?ts=${this.state.forceUpdate}`}
|
|
269
|
+
alt={this.props.href}
|
|
270
|
+
/>
|
|
271
|
+
);
|
|
272
272
|
}
|
|
273
273
|
if (this.state.ext && EXTENSIONS.audio.includes(this.state.ext)) {
|
|
274
|
-
return
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
274
|
+
return (
|
|
275
|
+
<div
|
|
276
|
+
style={{
|
|
277
|
+
width: '100%',
|
|
278
|
+
height: '100%',
|
|
279
|
+
display: 'flex',
|
|
280
|
+
justifyContent: 'center',
|
|
281
|
+
alignItems: 'center',
|
|
282
|
+
}}
|
|
283
|
+
>
|
|
284
|
+
<audio
|
|
285
|
+
style={{ width: '100%' }}
|
|
286
|
+
src={this.props.href}
|
|
287
|
+
controls
|
|
288
|
+
></audio>
|
|
289
|
+
</div>
|
|
290
|
+
);
|
|
290
291
|
}
|
|
291
292
|
if (this.state.ext && EXTENSIONS.video.includes(this.state.ext)) {
|
|
292
293
|
return (
|
|
@@ -299,9 +300,14 @@ class FileViewer extends Component<FileViewerProps, FileViewerState> {
|
|
|
299
300
|
alignItems: 'center',
|
|
300
301
|
}}
|
|
301
302
|
>
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
303
|
+
<video
|
|
304
|
+
style={{ width: '100%', height: '100%' }}
|
|
305
|
+
controls
|
|
306
|
+
>
|
|
307
|
+
<source
|
|
308
|
+
src={this.props.href}
|
|
309
|
+
type={`video/${this.state.ext}}`}
|
|
310
|
+
/>
|
|
305
311
|
</video>
|
|
306
312
|
</div>
|
|
307
313
|
);
|
|
@@ -314,79 +320,92 @@ class FileViewer extends Component<FileViewerProps, FileViewerState> {
|
|
|
314
320
|
// value={this.state.editingValue || this.state.code || this.state.text}
|
|
315
321
|
// onChange={this.state.editing ? newValue => this.setState({ editingValue: newValue, changed: true }) : undefined}
|
|
316
322
|
// />;
|
|
317
|
-
return
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
323
|
+
return (
|
|
324
|
+
<TextField
|
|
325
|
+
variant="standard"
|
|
326
|
+
style={styles.textarea}
|
|
327
|
+
multiline
|
|
328
|
+
value={this.state.editingValue || this.state.code || this.state.text}
|
|
329
|
+
// onChange={newValue => this.setState({ editingValue: newValue, changed: true })}
|
|
330
|
+
slotProps={{
|
|
331
|
+
htmlInput: {
|
|
332
|
+
readOnly: !this.state.editing,
|
|
333
|
+
},
|
|
334
|
+
}}
|
|
335
|
+
/>
|
|
336
|
+
);
|
|
325
337
|
}
|
|
326
338
|
return null;
|
|
327
339
|
}
|
|
328
340
|
|
|
329
|
-
render() {
|
|
330
|
-
return
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
<
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
e
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
341
|
+
render(): React.JSX.Element {
|
|
342
|
+
return (
|
|
343
|
+
<Dialog
|
|
344
|
+
sx={{
|
|
345
|
+
'&.MuiDialog-scrollPaper': styles.dialog,
|
|
346
|
+
'& .MuiDialog-paper': styles.paper,
|
|
347
|
+
}}
|
|
348
|
+
scroll="paper"
|
|
349
|
+
open={!!this.props.href}
|
|
350
|
+
onClose={() => this.props.onClose()}
|
|
351
|
+
fullWidth
|
|
352
|
+
maxWidth="xl"
|
|
353
|
+
aria-labelledby="ar_dialog_file_view_title"
|
|
354
|
+
>
|
|
355
|
+
<div style={styles.dialogTitle}>
|
|
356
|
+
<DialogTitle id="ar_dialog_file_view_title">{`${this.props.t(this.state.editing ? 'Edit' : 'View')}: ${this.props.href}`}</DialogTitle>
|
|
357
|
+
{this.state.ext && EXTENSIONS.images.includes(this.state.ext) && (
|
|
358
|
+
<div>
|
|
359
|
+
<IconButton
|
|
360
|
+
size="large"
|
|
361
|
+
color="inherit"
|
|
362
|
+
onClick={this.props.setStateBackgroundImage}
|
|
363
|
+
>
|
|
364
|
+
<Brightness5Icon />
|
|
365
|
+
</IconButton>
|
|
366
|
+
</div>
|
|
367
|
+
)}
|
|
368
|
+
</div>
|
|
369
|
+
<DialogContent style={styles.content}>{this.getContent()}</DialogContent>
|
|
370
|
+
<DialogActions>
|
|
371
|
+
{this.state.copyPossible ? (
|
|
372
|
+
<Button
|
|
373
|
+
color="grey"
|
|
374
|
+
onClick={e => {
|
|
375
|
+
e.stopPropagation();
|
|
376
|
+
e.preventDefault();
|
|
377
|
+
Utils.copyToClipboard(this.state.text || this.state.code || '');
|
|
378
|
+
}}
|
|
379
|
+
startIcon={<CopyIcon />}
|
|
380
|
+
>
|
|
381
|
+
{this.props.t('Copy content')}
|
|
382
|
+
</Button>
|
|
383
|
+
) : null}
|
|
384
|
+
{this.state.editing ? (
|
|
385
|
+
<Button
|
|
386
|
+
color="grey"
|
|
387
|
+
disabled={
|
|
388
|
+
this.state.editingValue === this.state.code ||
|
|
389
|
+
this.state.editingValue === this.state.text
|
|
390
|
+
}
|
|
391
|
+
variant="contained"
|
|
392
|
+
onClick={this.writeFile64}
|
|
393
|
+
startIcon={<SaveIcon />}
|
|
394
|
+
>
|
|
395
|
+
{this.props.t('Save')}
|
|
396
|
+
</Button>
|
|
397
|
+
) : null}
|
|
371
398
|
<Button
|
|
372
|
-
color="grey"
|
|
373
|
-
disabled={this.state.editingValue === this.state.code || this.state.editingValue === this.state.text}
|
|
374
399
|
variant="contained"
|
|
375
|
-
onClick={this.
|
|
376
|
-
|
|
400
|
+
onClick={() => this.props.onClose()}
|
|
401
|
+
color="primary"
|
|
402
|
+
startIcon={<CloseIcon />}
|
|
377
403
|
>
|
|
378
|
-
{this.props.t('
|
|
379
|
-
</Button>
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
color="primary"
|
|
384
|
-
startIcon={<CloseIcon />}
|
|
385
|
-
>
|
|
386
|
-
{this.props.t('Close')}
|
|
387
|
-
</Button>
|
|
388
|
-
</DialogActions>
|
|
389
|
-
</Dialog>;
|
|
404
|
+
{this.props.t('Close')}
|
|
405
|
+
</Button>
|
|
406
|
+
</DialogActions>
|
|
407
|
+
</Dialog>
|
|
408
|
+
);
|
|
390
409
|
}
|
|
391
410
|
}
|
|
392
411
|
|
package/src/Components/Icon.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { ReactEventHandler } from 'react';
|
|
1
|
+
import React, { type ReactEventHandler } from 'react';
|
|
2
2
|
import SVG from 'react-inlinesvg';
|
|
3
3
|
|
|
4
4
|
import { Box } from '@mui/material';
|
|
@@ -17,6 +17,11 @@ import {
|
|
|
17
17
|
import IconAlias from '../icons/IconAlias';
|
|
18
18
|
import Utils from './Utils';
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Get icon by object type (state, channel, device, ...).
|
|
22
|
+
*
|
|
23
|
+
* @param obj Object
|
|
24
|
+
*/
|
|
20
25
|
export function getSystemIcon(obj: ioBroker.Object | null): React.JSX.Element | null {
|
|
21
26
|
let icon;
|
|
22
27
|
const id = obj?._id;
|
|
@@ -26,7 +31,7 @@ export function getSystemIcon(obj: ioBroker.Object | null): React.JSX.Element |
|
|
|
26
31
|
}
|
|
27
32
|
|
|
28
33
|
// system or design has special icons
|
|
29
|
-
if (id.startsWith('_design/') ||
|
|
34
|
+
if (id.startsWith('_design/') || id === 'system') {
|
|
30
35
|
icon = <IconSystem className="iconOwn" />;
|
|
31
36
|
} else if (id === '0_userdata' || id === '0_userdata.0') {
|
|
32
37
|
icon = <IconPhoto className="iconOwn" />;
|
|
@@ -51,6 +56,12 @@ export function getSystemIcon(obj: ioBroker.Object | null): React.JSX.Element |
|
|
|
51
56
|
return icon || null;
|
|
52
57
|
}
|
|
53
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Get icon from the object.
|
|
61
|
+
*
|
|
62
|
+
* @param obj Object
|
|
63
|
+
* @param imagePrefix Prefix for image
|
|
64
|
+
*/
|
|
54
65
|
export function getSelectIdIcon(obj: ioBroker.Object | null, imagePrefix?: string): string | null {
|
|
55
66
|
imagePrefix = imagePrefix || '.'; // http://localhost:8081';
|
|
56
67
|
let src = '';
|
|
@@ -63,7 +74,7 @@ export function getSelectIdIcon(obj: ioBroker.Object | null, imagePrefix?: strin
|
|
|
63
74
|
if (cIcon.includes('.')) {
|
|
64
75
|
let instance;
|
|
65
76
|
if (obj.type === 'instance' || obj.type === 'adapter') {
|
|
66
|
-
src = `${imagePrefix}/adapter/${common.name}/${cIcon}`;
|
|
77
|
+
src = `${imagePrefix}/adapter/${common.name as string}/${cIcon}`;
|
|
67
78
|
} else if (obj._id && obj._id.startsWith('system.adapter.')) {
|
|
68
79
|
instance = obj._id.split('.', 3);
|
|
69
80
|
if (cIcon[0] === '/') {
|
|
@@ -101,12 +112,15 @@ interface IconProps {
|
|
|
101
112
|
className?: string;
|
|
102
113
|
/** Style for image */
|
|
103
114
|
style?: React.CSSProperties;
|
|
115
|
+
/** Styles for mui */
|
|
104
116
|
sx?: Record<string, any>;
|
|
105
117
|
/** Tooltip */
|
|
106
118
|
title?: string;
|
|
107
119
|
/** Styles for utf-8 characters */
|
|
108
120
|
styleUTF8?: React.CSSProperties;
|
|
121
|
+
/** On error handler */
|
|
109
122
|
onError?: ReactEventHandler<HTMLImageElement>;
|
|
123
|
+
/** Reference to image */
|
|
110
124
|
ref?: React.RefObject<HTMLImageElement>;
|
|
111
125
|
/** Alternative text for image */
|
|
112
126
|
alt?: string;
|
|
@@ -115,39 +129,45 @@ interface IconProps {
|
|
|
115
129
|
const REMOTE_SERVER = window.location.hostname.endsWith('iobroker.in');
|
|
116
130
|
const REMOTE_PREFIX = window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/') + 1);
|
|
117
131
|
|
|
118
|
-
export default function Icon(props: IconProps) {
|
|
132
|
+
export default function Icon(props: IconProps): React.JSX.Element | null {
|
|
119
133
|
if (props.src) {
|
|
120
134
|
if (typeof props.src === 'string') {
|
|
121
135
|
if (props.src.length < 3) {
|
|
122
136
|
// utf-8 char
|
|
123
137
|
if (props.sx) {
|
|
124
|
-
return
|
|
125
|
-
|
|
126
|
-
|
|
138
|
+
return (
|
|
139
|
+
<Box
|
|
140
|
+
component="span"
|
|
141
|
+
sx={props.sx}
|
|
142
|
+
title={props.title || undefined}
|
|
143
|
+
style={{ height: 27, marginTop: -8, ...(props.styleUTF8 || props.style) }}
|
|
144
|
+
className={Utils.clsx(props.className, 'iconOwn')}
|
|
145
|
+
>
|
|
146
|
+
{props.src}
|
|
147
|
+
</Box>
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
return (
|
|
151
|
+
<span
|
|
127
152
|
title={props.title || undefined}
|
|
128
153
|
style={{ height: 27, marginTop: -8, ...(props.styleUTF8 || props.style) }}
|
|
129
154
|
className={Utils.clsx(props.className, 'iconOwn')}
|
|
130
155
|
>
|
|
131
156
|
{props.src}
|
|
132
|
-
</
|
|
133
|
-
|
|
134
|
-
return <span
|
|
135
|
-
title={props.title || undefined}
|
|
136
|
-
style={{ height: 27, marginTop: -8, ...(props.styleUTF8 || props.style) }}
|
|
137
|
-
className={Utils.clsx(props.className, 'iconOwn')}
|
|
138
|
-
>
|
|
139
|
-
{props.src}
|
|
140
|
-
</span>;
|
|
157
|
+
</span>
|
|
158
|
+
);
|
|
141
159
|
}
|
|
142
160
|
if (props.src.startsWith('data:image/svg')) {
|
|
143
|
-
return
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
161
|
+
return (
|
|
162
|
+
<SVG
|
|
163
|
+
title={props.title || undefined}
|
|
164
|
+
src={props.src}
|
|
165
|
+
className={Utils.clsx(props.className, 'iconOwn')}
|
|
166
|
+
width={props.style?.width || 28}
|
|
167
|
+
height={props.style?.height || props.style?.width || 28}
|
|
168
|
+
style={props.style || {}}
|
|
169
|
+
/>
|
|
170
|
+
);
|
|
151
171
|
}
|
|
152
172
|
if (REMOTE_SERVER && !props.src.startsWith('http://') && !props.src.startsWith('https://')) {
|
|
153
173
|
let src = props.src;
|
|
@@ -158,9 +178,22 @@ export default function Icon(props: IconProps) {
|
|
|
158
178
|
}
|
|
159
179
|
|
|
160
180
|
if (props.sx) {
|
|
161
|
-
return
|
|
162
|
-
|
|
163
|
-
|
|
181
|
+
return (
|
|
182
|
+
<Box
|
|
183
|
+
component="img"
|
|
184
|
+
sx={props.sx}
|
|
185
|
+
title={props.title || undefined}
|
|
186
|
+
style={props.style || {}}
|
|
187
|
+
className={Utils.clsx(props.className, 'iconOwn')}
|
|
188
|
+
src={`https://remote-files.iobroker.in${src}`}
|
|
189
|
+
alt={props.alt || undefined}
|
|
190
|
+
ref={props.ref}
|
|
191
|
+
onError={e => props.onError && props.onError(e)}
|
|
192
|
+
/>
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
return (
|
|
196
|
+
<img
|
|
164
197
|
title={props.title || undefined}
|
|
165
198
|
style={props.style || {}}
|
|
166
199
|
className={Utils.clsx(props.className, 'iconOwn')}
|
|
@@ -168,22 +201,26 @@ export default function Icon(props: IconProps) {
|
|
|
168
201
|
alt={props.alt || undefined}
|
|
169
202
|
ref={props.ref}
|
|
170
203
|
onError={e => props.onError && props.onError(e)}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
return <img
|
|
174
|
-
title={props.title || undefined}
|
|
175
|
-
style={props.style || {}}
|
|
176
|
-
className={Utils.clsx(props.className, 'iconOwn')}
|
|
177
|
-
src={`https://remote-files.iobroker.in${src}`}
|
|
178
|
-
alt={props.alt || undefined}
|
|
179
|
-
ref={props.ref}
|
|
180
|
-
onError={e => props.onError && props.onError(e)}
|
|
181
|
-
/>;
|
|
204
|
+
/>
|
|
205
|
+
);
|
|
182
206
|
}
|
|
183
207
|
if (props.sx) {
|
|
184
|
-
return
|
|
185
|
-
|
|
186
|
-
|
|
208
|
+
return (
|
|
209
|
+
<Box
|
|
210
|
+
component="img"
|
|
211
|
+
sx={props.sx}
|
|
212
|
+
title={props.title || undefined}
|
|
213
|
+
style={props.style || {}}
|
|
214
|
+
className={Utils.clsx(props.className, 'iconOwn')}
|
|
215
|
+
src={props.src}
|
|
216
|
+
alt={props.alt || undefined}
|
|
217
|
+
ref={props.ref}
|
|
218
|
+
onError={props.onError}
|
|
219
|
+
/>
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
return (
|
|
223
|
+
<img
|
|
187
224
|
title={props.title || undefined}
|
|
188
225
|
style={props.style || {}}
|
|
189
226
|
className={Utils.clsx(props.className, 'iconOwn')}
|
|
@@ -191,17 +228,8 @@ export default function Icon(props: IconProps) {
|
|
|
191
228
|
alt={props.alt || undefined}
|
|
192
229
|
ref={props.ref}
|
|
193
230
|
onError={props.onError}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
return <img
|
|
197
|
-
title={props.title || undefined}
|
|
198
|
-
style={props.style || {}}
|
|
199
|
-
className={Utils.clsx(props.className, 'iconOwn')}
|
|
200
|
-
src={props.src}
|
|
201
|
-
alt={props.alt || undefined}
|
|
202
|
-
ref={props.ref}
|
|
203
|
-
onError={props.onError}
|
|
204
|
-
/>;
|
|
231
|
+
/>
|
|
232
|
+
);
|
|
205
233
|
}
|
|
206
234
|
|
|
207
235
|
return props.src;
|