thelounge/client/components/MessageCondensed.vue

158 lines
3.7 KiB
Vue
Raw Normal View History

2018-07-09 12:14:44 +00:00
<template>
2019-12-15 11:46:43 +00:00
<div :class="['msg', {closed: isCollapsed}]" data-type="condensed">
2018-07-13 07:43:31 +00:00
<div class="condensed-summary">
2018-07-29 17:57:14 +00:00
<span class="time" />
<span class="from" />
2019-07-17 09:33:59 +00:00
<span class="content" @click="onCollapseClick"
>{{ condensedText
}}<button class="toggle-button" aria-label="Toggle status messages"
/></span>
2018-07-09 12:14:44 +00:00
</div>
<Message
v-for="message in messages"
2018-07-29 17:57:14 +00:00
:key="message.id"
2018-07-19 17:44:24 +00:00
:network="network"
:message="message"
/>
2018-07-09 12:14:44 +00:00
</div>
</template>
<script lang="ts">
import {computed, defineComponent, PropType, ref} from "vue";
import constants from "../js/constants";
import {ClientMessage, ClientNetwork} from "../js/types";
2018-07-09 12:14:44 +00:00
import Message from "./Message.vue";
export default defineComponent({
2018-07-09 12:14:44 +00:00
name: "MessageCondensed",
components: {
Message,
2018-07-09 12:14:44 +00:00
},
props: {
network: {type: Object as PropType<ClientNetwork>, required: true},
messages: {
type: Array as PropType<ClientMessage[]>,
required: true,
},
keepScrollPosition: {
type: Function as PropType<() => void>,
required: true,
},
focused: Boolean,
2018-07-09 12:14:44 +00:00
},
setup(props) {
const isCollapsed = ref(true);
const onCollapseClick = () => {
isCollapsed.value = !isCollapsed.value;
props.keepScrollPosition();
};
const condensedText = computed(() => {
const obj: Record<string, number> = {};
2018-07-09 12:14:44 +00:00
constants.condensedTypes.forEach((type) => {
obj[type] = 0;
});
for (const message of props.messages) {
// special case since one MODE message can change multiple modes
if (message.type === "mode") {
// syntax: +vv-t maybe-some targets
// we want the number of mode changes in the message, so count the
// number of chars other than + and - before the first space
const modeChangesCount = message.text
.split(" ")[0]
.split("")
.filter((char) => char !== "+" && char !== "-").length;
obj[message.type] += modeChangesCount;
} else {
obj[message.type]++;
}
2018-07-09 12:14:44 +00:00
}
// Count quits as parts in condensed messages to reduce information density
obj.part += obj.quit;
const strings: string[] = [];
2018-07-09 12:14:44 +00:00
constants.condensedTypes.forEach((type) => {
if (obj[type]) {
switch (type) {
2019-07-17 09:33:59 +00:00
case "chghost":
strings.push(
String(obj[type]) +
2019-07-17 09:33:59 +00:00
(obj[type] > 1
? " users have changed hostname"
: " user has changed hostname")
);
break;
case "join":
strings.push(
String(obj[type]) +
2019-07-17 09:33:59 +00:00
(obj[type] > 1 ? " users have joined" : " user has joined")
);
break;
case "part":
strings.push(
String(obj[type]) +
(obj[type] > 1 ? " users have left" : " user has left")
2019-07-17 09:33:59 +00:00
);
break;
case "nick":
strings.push(
String(obj[type]) +
2019-07-17 09:33:59 +00:00
(obj[type] > 1
? " users have changed nick"
: " user has changed nick")
);
break;
case "kick":
strings.push(
String(obj[type]) +
2019-07-17 09:33:59 +00:00
(obj[type] > 1 ? " users were kicked" : " user was kicked")
);
break;
case "mode":
strings.push(
String(obj[type]) +
(obj[type] > 1 ? " modes were set" : " mode was set")
2019-07-17 09:33:59 +00:00
);
break;
case "away":
strings.push(
"marked away " +
(obj[type] > 1 ? String(obj[type]) + " times" : "once")
);
break;
case "back":
strings.push(
"marked back " +
(obj[type] > 1 ? String(obj[type]) + " times" : "once")
);
break;
2018-07-09 12:14:44 +00:00
}
}
});
if (strings.length) {
let text = strings.pop();
if (strings.length) {
text = strings.join(", ") + ", and " + text!;
}
return text;
2018-07-09 12:14:44 +00:00
}
return "";
});
return {
isCollapsed,
condensedText,
onCollapseClick,
};
},
});
2018-07-09 12:14:44 +00:00
</script>