Skip to content

Commit 4e9babc

Browse files
authored
Merge pull request #67 from celenium-io/hex
Hex
2 parents b5a8bc6 + c78cda9 commit 4e9babc

File tree

14 files changed

+1275
-110
lines changed

14 files changed

+1275
-110
lines changed

assets/styles/base.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,8 +280,8 @@ body {
280280
}
281281

282282
.dot {
283-
width: 3px;
284-
height: 3px;
283+
min-width: 3px;
284+
min-height: 3px;
285285

286286
border-radius: 50px;
287287
background: var(--txt-tertiary);

components/modals/BlobModal.vue

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,16 @@ const handlePreviewContent = () => {
344344
</Flex>
345345

346346
<Flex align="center" gap="8" :class="$style.buttons">
347+
<Button
348+
:link="`/blob?commitment=${cacheStore.selectedBlob.commitment}&hash=${cacheStore.selectedBlob.hash}&height=${cacheStore.selectedBlob.height}`"
349+
target="_blank"
350+
type="secondary"
351+
size="small"
352+
>
353+
Open Hex Viewer
354+
<Icon name="arrow-narrow-up-right" size="12" color="tertiary" />
355+
</Button>
356+
347357
<Button @click="handleDownload" type="secondary" size="small" :disabled="isLoading">
348358
<Icon name="download" size="14" color="secondary" />
349359

components/modals/ChangeBlobModal.vue

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<script setup>
2+
/** UI */
3+
import Modal from "@/components/ui/Modal.vue"
4+
import Input from "@/components/ui/Input.vue"
5+
import Button from "@/components/ui/Button.vue"
6+
7+
/** Store */
8+
import { useCacheStore } from "@/store/cache"
9+
const cacheStore = useCacheStore()
10+
11+
const emit = defineEmits(["onClose"])
12+
const props = defineProps({
13+
show: Boolean,
14+
})
15+
16+
const commitment = ref("")
17+
const hash = ref("")
18+
const height = ref("")
19+
20+
watch(
21+
() => props.show,
22+
() => {
23+
if (!props.show) return
24+
25+
commitment.value = cacheStore.current.blob.commitment
26+
hash.value = cacheStore.current.blob.hash
27+
height.value = cacheStore.current.blob.height
28+
},
29+
)
30+
31+
const handleChange = () => {
32+
if (!commitment.value.length || !hash.value.length || !height.value.length) return
33+
34+
cacheStore.current.blob = {
35+
commitment: commitment.value,
36+
hash: hash.value,
37+
height: height.value,
38+
}
39+
40+
emit("onClose")
41+
}
42+
</script>
43+
44+
<template>
45+
<Modal :show="show" @onClose="emit('onClose')" width="600" disable-trap>
46+
<Flex direction="column" gap="24">
47+
<Text size="14" weight="600" color="primary">Change blob</Text>
48+
49+
<Flex direction="column" gap="20">
50+
<Input v-model="commitment" label="Commitment" placeholder="" />
51+
<Input v-model="hash" label="Hash" placeholder="" />
52+
<Input v-model="height" label="Height" placeholder="" />
53+
</Flex>
54+
55+
<Button @click="handleChange" type="secondary" size="small" wide> Change </Button>
56+
</Flex>
57+
</Modal>
58+
</template>
59+
60+
<style module></style>

components/modals/ModalsManager.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
<script setup>
22
import AwaitingModal from "./AwaitingModal.vue"
33
import BlobModal from "./BlobModal.vue"
4-
import CommitmentModal from "./CommitmentModal.vue";
4+
import CommitmentModal from "./CommitmentModal.vue"
55
import ConfirmationModal from "./ConfirmationModal.vue"
66
import ConstantsModal from "./ConstantsModal.vue"
77
import EditBookmarkAliasModal from "./EditBookmarkAliasModal.vue"
88
import ImportBookmarksModal from "./ImportBookmarksModal.vue"
99
import ODSModal from "./ODSModal.vue";
1010
import PayForBlobModal from "./PayForBlobModal.vue"
11+
import ChangeBlobModal from "./ChangeBlobModal.vue"
1112
import QRCodeModal from "./QRCodeModal.vue"
1213
import RawDataModal from "./RawDataModal.vue"
1314
import SendModal from "./SendModal.vue"
@@ -29,6 +30,7 @@ const modalsStore = useModalsStore()
2930
<ImportBookmarksModal :show="modalsStore.modals.import" @onClose="modalsStore.close('import')" />
3031
<ODSModal :show="modalsStore.modals.ods" @onClose="modalsStore.close('ods')" />
3132
<PayForBlobModal :show="modalsStore.modals.pfb" @onClose="modalsStore.close('pfb')" />
33+
<ChangeBlobModal :show="modalsStore.modals.changeBlob" @onClose="modalsStore.close('changeBlob')" />
3234
<QRCodeModal :show="modalsStore.modals.qr" @onClose="modalsStore.close('qr')" />
3335
<RawDataModal :show="modalsStore.modals.rawData" @onClose="modalsStore.close('rawData')" />
3436
<SendModal :show="modalsStore.modals.send" @onClose="modalsStore.close('send')" />
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
<script setup>
2+
/** Vendor */
3+
import { DateTime } from "luxon"
4+
5+
const props = defineProps({
6+
bytes: {
7+
type: Array,
8+
},
9+
range: {
10+
type: Object,
11+
},
12+
})
13+
14+
const hexToUint8Array = (hex) => {
15+
const arr = []
16+
for (let i = 0; i < hex.length; i += 2) {
17+
arr.push(parseInt(hex.substr(i, 2), 16))
18+
}
19+
return new Uint8Array(arr)
20+
}
21+
22+
const isASCII = (str) => {
23+
return /^[\x00-\x7F]*$/.test(str)
24+
}
25+
</script>
26+
27+
<template>
28+
<Flex direction="column" gap="16" :class="$style.wrapper">
29+
<Flex align="center" justify="between" :class="$style.header">
30+
<Text size="13" weight="600" color="primary">Data Inspector</Text>
31+
</Flex>
32+
33+
<Flex direction="column" gap="8" :class="$style.content">
34+
<Flex direction="column" gap="8" :class="$style.field">
35+
<Flex align="center" justify="between">
36+
<Text size="12" weight="600" color="secondary">Binary</Text>
37+
<CopyButton v-if="range.start" :text="bytes[range.start - 1].toString(2).padStart(8, '0')" size="12" />
38+
</Flex>
39+
40+
<Text v-if="range.start" size="13" weight="600" color="primary" mono>
41+
{{ bytes[range.start - 1].toString(2).padStart(8, "0") }}
42+
</Text>
43+
<Text v-else size="13" weight="600" color="tertiary" mono>No bytes selected</Text>
44+
</Flex>
45+
46+
<Flex direction="column" gap="8" :class="$style.field">
47+
<Flex align="center" justify="between">
48+
<Text size="12" weight="600" color="secondary">uint8</Text>
49+
<CopyButton v-if="range.start" :text="hexToUint8Array(bytes[range.start - 1])" size="12" />
50+
</Flex>
51+
52+
<Text v-if="range.start" size="13" weight="600" color="primary" mono>
53+
{{ hexToUint8Array(bytes[range.start - 1]) }}
54+
</Text>
55+
<Text v-else size="13" weight="600" color="tertiary" mono>No bytes selected</Text>
56+
</Flex>
57+
58+
<Flex direction="column" gap="8" :class="$style.field">
59+
<Flex align="center" justify="between">
60+
<Text size="12" weight="600" color="secondary">Time</Text>
61+
<CopyButton v-if="range.start" :text="hexToUint8Array(bytes[range.start - 1])" size="12" />
62+
</Flex>
63+
64+
<Text v-if="range.start" size="13" weight="600" color="primary" mono>
65+
{{ DateTime.fromISO(parseInt(bytes[range.start - 1], 16)) }}
66+
</Text>
67+
<Text v-else size="13" weight="600" color="tertiary" mono>No bytes selected</Text>
68+
</Flex>
69+
70+
<Flex direction="column" gap="8" :class="$style.field">
71+
<Flex align="center" justify="between">
72+
<Text size="12" weight="600" color="secondary">ASCII Character</Text>
73+
<CopyButton
74+
v-if="range.start"
75+
:text="
76+
range.start < range.end
77+
? bytes
78+
.slice(range.start - 1, range.end)
79+
.map((byte) => String.fromCharCode(parseInt(byte, 16)))
80+
.join('')
81+
: bytes
82+
.slice(range.end - 1, range.start)
83+
.map((byte) => String.fromCharCode(parseInt(byte, 16)))
84+
.join('')
85+
"
86+
size="12"
87+
/>
88+
</Flex>
89+
90+
<Text v-if="range.start < range.end" size="13" weight="600" height="140" color="primary" mono :class="$style.ascii">
91+
{{
92+
bytes
93+
.slice(range.start - 1, range.end)
94+
.map((byte) => String.fromCharCode(parseInt(byte, 16)))
95+
.join("")
96+
}}
97+
</Text>
98+
<Text v-if="range.start > range.end" size="13" weight="600" height="140" color="primary" mono :class="$style.ascii">
99+
{{
100+
bytes
101+
.slice(range.end - 1, range.start)
102+
.map((byte) => String.fromCharCode(parseInt(byte, 16)))
103+
.join("")
104+
}}
105+
</Text>
106+
</Flex>
107+
</Flex>
108+
</Flex>
109+
</template>
110+
111+
<style module>
112+
.wrapper {
113+
border-radius: 8px;
114+
background: var(--card-background);
115+
overflow: hidden;
116+
117+
padding: 16px;
118+
}
119+
120+
.header {
121+
cursor: pointer;
122+
border-radius: 6px;
123+
124+
padding: 8px;
125+
margin: -8px;
126+
127+
transition: all 0.2s ease;
128+
129+
&:hover {
130+
background: var(--op-5);
131+
}
132+
}
133+
134+
.field {
135+
border-radius: 6px;
136+
background: var(--op-5);
137+
138+
padding: 8px;
139+
}
140+
141+
.value {
142+
cursor: pointer;
143+
144+
transition: all 0.2s ease;
145+
146+
&:hover {
147+
color: var(--txt-primary);
148+
background: var(--op-10);
149+
}
150+
151+
&:nth-child(9) {
152+
margin-right: 10px;
153+
}
154+
}
155+
156+
.ascii {
157+
overflow: hidden;
158+
text-overflow: ellipsis;
159+
}
160+
</style>

0 commit comments

Comments
 (0)