diff --git a/packages/hoppscotch-app/assets/icons/arrow-down-left.svg b/packages/hoppscotch-app/assets/icons/arrow-down-left.svg
new file mode 100644
index 000000000..583988208
--- /dev/null
+++ b/packages/hoppscotch-app/assets/icons/arrow-down-left.svg
@@ -0,0 +1,4 @@
+
diff --git a/packages/hoppscotch-app/assets/icons/arrow-down.svg b/packages/hoppscotch-app/assets/icons/arrow-down.svg
new file mode 100644
index 000000000..ad365d5fc
--- /dev/null
+++ b/packages/hoppscotch-app/assets/icons/arrow-down.svg
@@ -0,0 +1,4 @@
+
\ No newline at end of file
diff --git a/packages/hoppscotch-app/assets/icons/arrow-up-right.svg b/packages/hoppscotch-app/assets/icons/arrow-up-right.svg
new file mode 100644
index 000000000..6ac911836
--- /dev/null
+++ b/packages/hoppscotch-app/assets/icons/arrow-up-right.svg
@@ -0,0 +1,4 @@
+
diff --git a/packages/hoppscotch-app/assets/icons/arrow-up.svg b/packages/hoppscotch-app/assets/icons/arrow-up.svg
new file mode 100644
index 000000000..9966fa544
--- /dev/null
+++ b/packages/hoppscotch-app/assets/icons/arrow-up.svg
@@ -0,0 +1,4 @@
+
\ No newline at end of file
diff --git a/packages/hoppscotch-app/assets/icons/chevrons-down.svg b/packages/hoppscotch-app/assets/icons/chevrons-down.svg
new file mode 100644
index 000000000..b46abe3a6
--- /dev/null
+++ b/packages/hoppscotch-app/assets/icons/chevrons-down.svg
@@ -0,0 +1,4 @@
+
\ No newline at end of file
diff --git a/packages/hoppscotch-app/assets/icons/chevrons-up.svg b/packages/hoppscotch-app/assets/icons/chevrons-up.svg
new file mode 100644
index 000000000..d79fc4952
--- /dev/null
+++ b/packages/hoppscotch-app/assets/icons/chevrons-up.svg
@@ -0,0 +1,4 @@
+
\ No newline at end of file
diff --git a/packages/hoppscotch-app/assets/icons/info-disconnect.svg b/packages/hoppscotch-app/assets/icons/info-disconnect.svg
new file mode 100644
index 000000000..ab55c86fd
--- /dev/null
+++ b/packages/hoppscotch-app/assets/icons/info-disconnect.svg
@@ -0,0 +1,5 @@
+
diff --git a/packages/hoppscotch-app/assets/icons/info-realtime.svg b/packages/hoppscotch-app/assets/icons/info-realtime.svg
new file mode 100644
index 000000000..ab55c86fd
--- /dev/null
+++ b/packages/hoppscotch-app/assets/icons/info-realtime.svg
@@ -0,0 +1,5 @@
+
diff --git a/packages/hoppscotch-app/components/realtime/Log.vue b/packages/hoppscotch-app/components/realtime/Log.vue
index 348a2fab7..e46dc21d0 100644
--- a/packages/hoppscotch-app/components/realtime/Log.vue
+++ b/packages/hoppscotch-app/components/realtime/Log.vue
@@ -1,77 +1,128 @@
-
+
-
-
-
+
+ {{ entry.ts }}{{ source(entry.source) }}{{ entry.payload }}
-
- {{ t("response.waiting_for_connection") }}
+ :entry="entry"
+ />
+
-
+
diff --git a/packages/hoppscotch-app/components/realtime/LogEntry.vue b/packages/hoppscotch-app/components/realtime/LogEntry.vue
new file mode 100644
index 000000000..941455294
--- /dev/null
+++ b/packages/hoppscotch-app/components/realtime/LogEntry.vue
@@ -0,0 +1,388 @@
+
+
+
+
+
+
+
+
+
+
+ {{ new Date(entry.ts).toLocaleTimeString() }}
+
+
+
+
+ {{ entry.payload }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ t("response.waiting_for_connection") }}
+
+
+
+
+
diff --git a/packages/hoppscotch-app/components/realtime/Mqtt.vue b/packages/hoppscotch-app/components/realtime/Mqtt.vue
index 6cd482c20..b04000091 100644
--- a/packages/hoppscotch-app/components/realtime/Mqtt.vue
+++ b/packages/hoppscotch-app/components/realtime/Mqtt.vue
@@ -48,7 +48,11 @@
-
+
@@ -216,8 +220,8 @@ export default defineComponent({
{
payload: this.$t("state.connecting_to", { name: this.url }),
source: "info",
- color: "var(--accent-color)",
- ts: new Date().toLocaleTimeString(),
+ event: "connecting",
+ ts: Date.now(),
},
]
const parseUrl = new URL(this.url)
@@ -253,8 +257,8 @@ export default defineComponent({
addMQTTLogLine({
payload: this.$t("error.something_went_wrong"),
source: "info",
- color: "#ff5555",
- ts: new Date().toLocaleTimeString(),
+ event: "error",
+ ts: Date.now(),
})
},
onConnectionSuccess() {
@@ -263,8 +267,8 @@ export default defineComponent({
addMQTTLogLine({
payload: this.$t("state.connected_to", { name: this.url }),
source: "info",
- color: "var(--accent-color)",
- ts: new Date().toLocaleTimeString(),
+ event: "connected",
+ ts: Date.now(),
})
this.$toast.success(this.$t("state.connected"))
},
@@ -272,8 +276,8 @@ export default defineComponent({
addMQTTLogLine({
payload: `Message: ${payloadString} arrived on topic: ${destinationName}`,
source: "info",
- color: "var(--accent-color)",
- ts: new Date().toLocaleTimeString(),
+ event: "info",
+ ts: Date.now(),
})
},
toggleConnection() {
@@ -288,9 +292,9 @@ export default defineComponent({
this.client.disconnect()
addMQTTLogLine({
payload: this.$t("state.disconnected_from", { name: this.url }),
- source: "info",
- color: "#ff5555",
- ts: new Date().toLocaleTimeString(),
+ source: "disconnected",
+ event: "disconnected",
+ ts: Date.now(),
})
},
onConnectionLost() {
@@ -309,9 +313,9 @@ export default defineComponent({
this.client.publish(this.pub_topic, this.msg, 0, false)
addMQTTLogLine({
payload: `Published message: ${this.msg} to topic: ${this.pub_topic}`,
- ts: new Date().toLocaleTimeString(),
+ ts: Date.now(),
source: "info",
- color: "var(--accent-color)",
+ event: "info",
})
} catch (e) {
addMQTTLogLine({
@@ -319,8 +323,8 @@ export default defineComponent({
this.$t("error.something_went_wrong") +
`while publishing msg: ${this.msg} to topic: ${this.pub_topic}`,
source: "info",
- color: "#ff5555",
- ts: new Date().toLocaleTimeString(),
+ event: "error",
+ ts: Date.now(),
})
}
},
@@ -343,8 +347,8 @@ export default defineComponent({
this.$t("error.something_went_wrong") +
`while subscribing to topic: ${this.sub_topic}`,
source: "info",
- color: "#ff5555",
- ts: new Date().toLocaleTimeString(),
+ event: "error",
+ ts: Date.now(),
})
}
},
@@ -356,8 +360,8 @@ export default defineComponent({
(this.subscriptionState ? "subscribed" : "unsubscribed") +
` to topic: ${this.sub_topic}`,
source: "info",
- color: "var(--accent-color)",
- ts: new Date().toLocaleTimeString(),
+ event: "info",
+ ts: Date.now(),
})
},
usubFailure() {
@@ -367,8 +371,8 @@ export default defineComponent({
(this.subscriptionState ? "unsubscribe" : "subscribe") +
` to topic: ${this.sub_topic}`,
source: "info",
- color: "#ff5555",
- ts: new Date().toLocaleTimeString(),
+ color: "error",
+ ts: Date.now(),
})
},
unsubscribe() {
@@ -377,6 +381,9 @@ export default defineComponent({
onFailure: this.usubFailure,
})
},
+ clearLogEntries() {
+ this.log = []
+ },
},
})
diff --git a/packages/hoppscotch-app/components/realtime/Socketio.vue b/packages/hoppscotch-app/components/realtime/Socketio.vue
index 358941160..79623d227 100644
--- a/packages/hoppscotch-app/components/realtime/Socketio.vue
+++ b/packages/hoppscotch-app/components/realtime/Socketio.vue
@@ -200,7 +200,11 @@
-
+
@@ -389,7 +393,8 @@ export default defineComponent({
{
payload: this.$t("state.connecting_to", { name: this.url }),
source: "info",
- color: "var(--accent-color)",
+ event: "connecting",
+ ts: Date.now(),
},
]
@@ -418,8 +423,8 @@ export default defineComponent({
{
payload: this.$t("state.connected_to", { name: this.url }),
source: "info",
- color: "var(--accent-color)",
- ts: new Date().toLocaleTimeString(),
+ event: "connected",
+ ts: Date.now(),
},
]
this.$toast.success(this.$t("state.connected"))
@@ -429,7 +434,7 @@ export default defineComponent({
addSIOLogLine({
payload: `[${eventName}] ${message ? JSON.stringify(message) : ""}`,
source: "server",
- ts: new Date().toLocaleTimeString(),
+ ts: Date.now(),
})
})
this.io.on("connect_error", (error) => {
@@ -446,9 +451,9 @@ export default defineComponent({
this.connectionState = false
addSIOLogLine({
payload: this.$t("state.disconnected_from", { name: this.url }),
- source: "info",
- color: "#ff5555",
- ts: new Date().toLocaleTimeString(),
+ source: "disconnected",
+ event: "disconnected",
+ ts: Date.now(),
})
this.$toast.error(this.$t("state.disconnected"))
})
@@ -471,15 +476,15 @@ export default defineComponent({
addSIOLogLine({
payload: this.$t("error.something_went_wrong"),
source: "info",
- color: "#ff5555",
- ts: new Date().toLocaleTimeString(),
+ event: "error",
+ ts: Date.now(),
})
if (error !== null)
addSIOLogLine({
payload: error,
source: "info",
- color: "#ff5555",
- ts: new Date().toLocaleTimeString(),
+ event: "error",
+ ts: Date.now(),
})
},
sendMessage() {
@@ -500,14 +505,14 @@ export default defineComponent({
addSIOLogLine({
payload: `[${eventName}] ${JSON.stringify(data)}`,
source: "server",
- ts: new Date().toLocaleTimeString(),
+ ts: Date.now(),
})
})
addSIOLogLine({
payload: `[${eventName}] ${JSON.stringify(messages)}`,
source: "client",
- ts: new Date().toLocaleTimeString(),
+ ts: Date.now(),
})
this.communication.inputs = [""]
}
@@ -516,6 +521,9 @@ export default defineComponent({
this.clientVersion = version
this.$refs.versionOptions.tippy().hide()
},
+ clearLogEntries() {
+ this.log = []
+ },
},
})
diff --git a/packages/hoppscotch-app/components/realtime/Sse.vue b/packages/hoppscotch-app/components/realtime/Sse.vue
index b5c5faf66..ac5ca388c 100644
--- a/packages/hoppscotch-app/components/realtime/Sse.vue
+++ b/packages/hoppscotch-app/components/realtime/Sse.vue
@@ -47,7 +47,11 @@
-
+
@@ -136,7 +140,8 @@ export default defineComponent({
{
payload: this.$t("state.connecting_to", { name: this.server }),
source: "info",
- color: "var(--accent-color)",
+ event: "connecting",
+ ts: Date.now(),
},
]
if (typeof EventSource !== "undefined") {
@@ -149,8 +154,8 @@ export default defineComponent({
{
payload: this.$t("state.connected_to", { name: this.server }),
source: "info",
- color: "var(--accent-color)",
- ts: new Date().toLocaleTimeString(),
+ event: "connected",
+ ts: Date.now(),
},
]
this.$toast.success(this.$t("state.connected"))
@@ -164,9 +169,9 @@ export default defineComponent({
payload: this.$t("state.disconnected_from", {
name: this.server,
}),
- source: "info",
- color: "#ff5555",
- ts: new Date().toLocaleTimeString(),
+ source: "disconnected",
+ event: "disconnected",
+ ts: Date.now(),
})
this.$toast.error(this.$t("state.disconnected"))
}
@@ -174,7 +179,7 @@ export default defineComponent({
addSSELogLine({
payload: data,
source: "server",
- ts: new Date().toLocaleTimeString(),
+ ts: Date.now(),
})
})
} catch (e) {
@@ -185,9 +190,9 @@ export default defineComponent({
this.log = [
{
payload: this.$t("error.browser_support_sse"),
- source: "info",
- color: "#ff5555",
- ts: new Date().toLocaleTimeString(),
+ source: "disconnected",
+ event: "error",
+ ts: Date.now(),
},
]
}
@@ -201,22 +206,25 @@ export default defineComponent({
this.connectionSSEState = false
addSSELogLine({
payload: this.$t("error.something_went_wrong"),
- source: "info",
- color: "#ff5555",
- ts: new Date().toLocaleTimeString(),
+ source: "disconnected",
+ event: "error",
+ ts: Date.now(),
})
if (error !== null)
addSSELogLine({
payload: error,
- source: "info",
- color: "#ff5555",
- ts: new Date().toLocaleTimeString(),
+ source: "disconnected",
+ event: "error",
+ ts: Date.now(),
})
},
stop() {
this.sse.close()
this.sse.onclose()
},
+ clearLogEntries() {
+ this.log = []
+ },
},
})
diff --git a/packages/hoppscotch-app/components/realtime/Websocket.vue b/packages/hoppscotch-app/components/realtime/Websocket.vue
index cd1ce8ee5..9ac8705a8 100644
--- a/packages/hoppscotch-app/components/realtime/Websocket.vue
+++ b/packages/hoppscotch-app/components/realtime/Websocket.vue
@@ -137,22 +137,23 @@
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
:alt="$t('empty.protocols')"
/>
-
- {{ $t("empty.protocols") }}
-
+ {{ $t("empty.protocols") }}
-
+
- {{ $t("websocket.communication") }}
-
=>
O.tryCatch(() => JSON.parse(str))
+
+/**
+ * Checks if given string is a JSON string
+ * @param str Raw string to be checked
+ * @returns If string is a JSON string
+ */
+export const isJSON = flow(safeParseJSON, O.isSome)
diff --git a/packages/hoppscotch-app/helpers/utils/string.ts b/packages/hoppscotch-app/helpers/utils/string.ts
deleted file mode 100644
index f23107591..000000000
--- a/packages/hoppscotch-app/helpers/utils/string.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-const sourceEmojis = {
- // Source used for info messages.
- info: "\tℹ️ [INFO]:\t",
- // Source used for client to server messages.
- client: "\t⬅️ [SENT]:\t",
- // Source used for server to client messages.
- server: "\t➡️ [RECEIVED]:\t",
-}
-
-export function getSourcePrefix(source: keyof typeof sourceEmojis) {
- return sourceEmojis[source]
-}
diff --git a/packages/hoppscotch-app/locales/en.json b/packages/hoppscotch-app/locales/en.json
index b7d058558..77b0759c1 100644
--- a/packages/hoppscotch-app/locales/en.json
+++ b/packages/hoppscotch-app/locales/en.json
@@ -1,5 +1,6 @@
{
"action": {
+ "autoscroll": "Autoscroll",
"cancel": "Cancel",
"choose_file": "Choose a file",
"clear": "Clear",
@@ -25,6 +26,8 @@
"remove": "Remove",
"restore": "Restore",
"save": "Save",
+ "scroll_to_bottom": "Scroll to bottom",
+ "scroll_to_top": "Scroll to top",
"search": "Search",
"send": "Send",
"start": "Start",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 7592a3c6b..155afd12b 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -3604,7 +3604,7 @@ packages:
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
dependencies:
callsites: 3.1.0
- graceful-fs: 4.2.9
+ graceful-fs: 4.2.10
source-map: 0.6.1
dev: true
@@ -3623,7 +3623,7 @@ packages:
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
dependencies:
'@jest/test-result': 27.5.1
- graceful-fs: 4.2.9
+ graceful-fs: 4.2.10
jest-haste-map: 27.5.1
jest-runtime: 27.5.1
transitivePeerDependencies:
@@ -3919,11 +3919,11 @@ packages:
ufo: 0.7.11
dev: false
- /@nuxt/kit-edge/3.0.0-rc.2-27525415.a8d42d5:
- resolution: {integrity: sha512-WfUj777D53SWprNmghE2JcgS/IAeU/NBLTsgJQf8EZG/GFjM62w/YCiY3zGcyVMsxHBSgnE9VUv5RZ5Gl8Os/A==}
+ /@nuxt/kit-edge/3.0.0-rc.2-27530889.9e5a3cd:
+ resolution: {integrity: sha512-D/Fm/7igO3/GE+5S8528frpJT25V+i4Y8ZcZ4MuO0i6karl4whwcSDkVOmrZBCtLa0IG+FD2f/6E4JJaB0BBHQ==}
engines: {node: ^14.16.0 || ^16.11.0 || ^17.0.0 || ^18.0.0}
dependencies:
- '@nuxt/schema': /@nuxt/schema-edge/3.0.0-rc.2-27525415.a8d42d5
+ '@nuxt/schema': /@nuxt/schema-edge/3.0.0-rc.2-27530889.9e5a3cd
c12: 0.2.7
consola: 2.15.3
defu: 6.0.0
@@ -3934,7 +3934,7 @@ packages:
knitwork: 0.1.1
lodash.template: 4.5.0
mlly: 0.5.2
- pathe: 0.2.0
+ pathe: 0.3.0
pkg-types: 0.3.2
scule: 0.2.1
semver: 7.3.7
@@ -3971,19 +3971,19 @@ packages:
- encoding
dev: false
- /@nuxt/schema-edge/3.0.0-rc.2-27525415.a8d42d5:
- resolution: {integrity: sha512-CrERM3lg+TXjBToAI/XmfLdJbGoQU600iUhZR9VIbUpNqq+nFPnIw1DxS6XioyBq/4rh/GmaHC+LxZFxNkigCA==}
+ /@nuxt/schema-edge/3.0.0-rc.2-27530889.9e5a3cd:
+ resolution: {integrity: sha512-Ac8bXC8nXYZKGJPLIMPKZwA5i7X/oaWGeSIJ5zruUt9XwLRP2BOgOTTrM+vy/KK44pWeweCgZkYMM6CD/XewBw==}
engines: {node: ^14.16.0 || ^16.11.0 || ^17.0.0 || ^18.0.0}
dependencies:
c12: 0.2.7
create-require: 1.1.1
defu: 6.0.0
jiti: 1.13.0
- pathe: 0.2.0
+ pathe: 0.3.0
postcss-import-resolver: 2.0.0
scule: 0.2.1
std-env: 3.1.1
- ufo: 0.8.3
+ ufo: 0.8.4
unimport: 0.1.8
transitivePeerDependencies:
- esbuild
@@ -12606,7 +12606,7 @@ packages:
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
dependencies:
'@types/node': 17.0.24
- graceful-fs: 4.2.9
+ graceful-fs: 4.2.10
dev: true
/jest-snapshot/27.5.1:
@@ -12887,7 +12887,7 @@ packages:
resolution: {integrity: sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==}
hasBin: true
dependencies:
- minimist: 1.2.5
+ minimist: 1.2.6
/json5/2.2.1:
resolution: {integrity: sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==}
@@ -13931,7 +13931,8 @@ packages:
resolution: {integrity: sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==}
hasBin: true
dependencies:
- minimist: 1.2.5
+ minimist: 1.2.6
+ dev: false
/mkdirp/0.5.6:
resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==}
@@ -14324,7 +14325,7 @@ packages:
/nuxt-windicss/2.2.11:
resolution: {integrity: sha512-xobq725D6vqpIgYOrLJ6CVlR4xLlFGwuq//gZikXKOdoVRpoK8C+NpHazPd4+f17urGQ4H0LqGBCIujTvV1V0g==}
dependencies:
- '@nuxt/kit': /@nuxt/kit-edge/3.0.0-rc.2-27525415.a8d42d5
+ '@nuxt/kit': /@nuxt/kit-edge/3.0.0-rc.2-27530889.9e5a3cd
'@windicss/plugin-utils': 1.8.4
consola: 2.15.3
defu: 6.0.0
@@ -14848,6 +14849,10 @@ packages:
resolution: {integrity: sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw==}
dev: true
+ /pathe/0.3.0:
+ resolution: {integrity: sha512-3vUjp552BJzCw9vqKsO5sttHkbYqqsZtH0x1PNtItgqx8BXEXzoY1SYRKcL6BTyVh4lGJGLj0tM42elUDMvcYA==}
+ dev: true
+
/pause-stream/0.0.11:
resolution: {integrity: sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=}
dependencies:
@@ -17808,7 +17813,7 @@ packages:
css-tree: 1.0.0-alpha.37
csso: 4.2.0
js-yaml: 3.14.1
- mkdirp: 0.5.5
+ mkdirp: 0.5.6
object.values: 1.1.5
sax: 1.2.4
stable: 0.1.8
@@ -18519,6 +18524,10 @@ packages:
/ufo/0.8.3:
resolution: {integrity: sha512-AIkk06G21y/P+NCatfU+1qldCmI0XCszZLn8AkuKotffF3eqCvlce0KuwM7ZemLE/my0GSYADOAeM5zDYWMB+A==}
+ /ufo/0.8.4:
+ resolution: {integrity: sha512-/+BmBDe8GvlB2nIflWasLLAInjYG0bC9HRnfEpNi4sw77J2AJNnEVnTDReVrehoh825+Q/evF3THXTAweyam2g==}
+ dev: true
+
/uglify-js/3.14.3:
resolution: {integrity: sha512-mic3aOdiq01DuSVx0TseaEzMIVqebMZ0Z3vaeDhFEh9bsc24hV1TFvN74reA2vs08D0ZWfNjAcJ3UbVLaBss+g==}
engines: {node: '>=0.8.0'}