Beginning with the new dark design and the new chat functionality
parent
9d00228a2a
commit
724317e6c3
|
@ -1,4 +1,8 @@
|
|||
# Changelog:
|
||||
* **XX.XX.XX**
|
||||
- Removed icon size restriction for SVGs
|
||||
- Fixed permission editor icon select for not granted icon permissions
|
||||
|
||||
* **22.06.19**
|
||||
- Fixed channel create not working issue
|
||||
- Added BB-Code support for pokes
|
||||
|
|
|
@ -34,6 +34,22 @@
|
|||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
|
||||
&.server, > .container-channel, &.client {
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
|
||||
&:hover {
|
||||
background-color: $channel_tree_entry_hovered;
|
||||
}
|
||||
|
||||
&.selected {
|
||||
background-color: $channel_tree_entry_selected;
|
||||
.channel-name {
|
||||
color: whitesmoke;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.server {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
@ -54,20 +70,13 @@
|
|||
flex-shrink: 1;
|
||||
|
||||
align-self: center;
|
||||
color: $channel_tree_entry_text_color;
|
||||
}
|
||||
|
||||
.icon_property {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
&.selected {
|
||||
background-color: $channel_tree_entry_selected;
|
||||
|
||||
.name {
|
||||
color: whitesmoke;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.channel {
|
||||
|
@ -115,6 +124,7 @@
|
|||
|
||||
.channel-name {
|
||||
align-self: center;
|
||||
color: $channel_tree_entry_text_color;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,13 +140,6 @@
|
|||
border-bottom: 1px solid black;
|
||||
}
|
||||
|
||||
&.selected {
|
||||
background-color: $channel_tree_entry_selected;
|
||||
.channel-name {
|
||||
color: whitesmoke;
|
||||
}
|
||||
}
|
||||
|
||||
.show-channel-normal-only {
|
||||
display: none;
|
||||
|
||||
|
@ -181,13 +184,14 @@
|
|||
flex-shrink: 1;
|
||||
|
||||
min-width: 75px;
|
||||
color: $channel_tree_entry_text_color;
|
||||
}
|
||||
|
||||
.container-icons {
|
||||
margin-right: 0; /* override from previous thing */
|
||||
|
||||
position: absolute;
|
||||
right: 0;
|
||||
right: 5px;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
@ -207,11 +211,7 @@
|
|||
}
|
||||
|
||||
&.selected {
|
||||
background-color: $channel_tree_entry_selected;
|
||||
|
||||
.client-name {
|
||||
color: whitesmoke;
|
||||
|
||||
&:focus {
|
||||
color: black;
|
||||
|
||||
|
|
|
@ -1,11 +1,18 @@
|
|||
|
||||
.container-connection-handlers {
|
||||
height: 35px;
|
||||
background-color: lightgray;
|
||||
$animation_length: .25s;
|
||||
|
||||
border: 4px solid lightgray;
|
||||
border-top: 1px dotted gray;
|
||||
border-bottom-width: 0;
|
||||
margin-top: 0;
|
||||
height: 0;
|
||||
|
||||
transition: all $animation_length ease-in-out;
|
||||
&.shown {
|
||||
margin-top: -4px;
|
||||
height: 24px;
|
||||
|
||||
transition: all $animation_length ease-in-out;
|
||||
}
|
||||
|
||||
background-color: transparent;
|
||||
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
|
@ -22,20 +29,22 @@
|
|||
flex-direction: row;
|
||||
justify-content: left;
|
||||
|
||||
overflow-x: auto;
|
||||
overflow-y: visible;
|
||||
|
||||
.connection-container {
|
||||
padding-top: 4px;
|
||||
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
|
||||
margin-top: 5px;
|
||||
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
|
||||
border: 1px #2222223b solid;
|
||||
border-radius: 2px 2px 0 0;
|
||||
height: 24px;
|
||||
|
||||
.server-icon {
|
||||
align-self: center;
|
||||
|
@ -43,6 +52,8 @@
|
|||
}
|
||||
|
||||
.server-name {
|
||||
color: #a8a8a8;
|
||||
|
||||
align-self: center;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
@ -51,21 +62,27 @@
|
|||
align-self: center;
|
||||
|
||||
&:hover {
|
||||
background-color: #e7e7e7;
|
||||
background-color: #212121;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #242425;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: #FFFFFF33;
|
||||
background-color: #2d2f32;
|
||||
border-bottom: 1px solid #0d9cfd;
|
||||
|
||||
//-webkit-box-shadow: inset 4px -17px 50px -30px #0d9cfd99;
|
||||
//-moz-box-shadow: inset 4px -17px 50px -30px #0d9cfd99;
|
||||
//box-shadow: inset 4px -17px 50px -30px #0d9cfd99;
|
||||
}
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
overflow-x: auto;
|
||||
overflow-y: visible;
|
||||
}
|
||||
|
||||
.container-scroll {
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
$border_color_activated: rgba(255, 255, 255, .75);
|
||||
$background_activated: rgba(0,0,0,0.25);
|
||||
$background:lightgray;
|
||||
|
||||
.control_bar {
|
||||
display: flex;
|
||||
|
@ -11,83 +9,114 @@ $background:lightgray;
|
|||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
|
||||
/* tmp fix for ultra small devices */
|
||||
overflow-y: visible;
|
||||
|
||||
.divider {
|
||||
border-left:2px solid gray;
|
||||
height: auto;
|
||||
margin-left: 5px;
|
||||
margin-right: 5px
|
||||
border-left:2px solid #393838;
|
||||
height: calc(100% - 3px);
|
||||
margin: 3px;
|
||||
}
|
||||
|
||||
.button {
|
||||
cursor: pointer;
|
||||
background-color: lightgray;
|
||||
border-radius: 5px;
|
||||
align-items: center;
|
||||
border: 2px solid rgba(0, 0, 0, 0);
|
||||
height: 36px;
|
||||
width: 36px;
|
||||
margin-right: 5px;
|
||||
margin-left: 5px;
|
||||
/* border etc */
|
||||
.button, .dropdown-arrow {
|
||||
text-align: center;
|
||||
|
||||
border: 1px solid rgba(0, 0, 0, 0);
|
||||
border-radius: 3px;
|
||||
|
||||
background-color: #454545;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(0,0,0,0.4);
|
||||
border-color: rgba(255, 255, 255, .75);
|
||||
background-color: #393c43;
|
||||
border-color: #4a4c55;
|
||||
/*box-shadow: 0 12px 16px 0 rgba(0,0,0,0.24), 0 17px 50px 0 rgba(0,0,0,0.19);*/
|
||||
}
|
||||
|
||||
&.activated {
|
||||
background-color: rgba(0,0,0,0.25);
|
||||
border-color: rgba(255, 255, 255, .75);
|
||||
background-color: #2f3841;
|
||||
border-color: #005fa1;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(0,0,0,0.4);
|
||||
border-color: rgba(255, 255, 255, .75);
|
||||
background-color: #263340;
|
||||
border-color: #005fa1;
|
||||
}
|
||||
|
||||
&.button-red {
|
||||
background-color: #412f2f;
|
||||
border-color: #a10000;
|
||||
|
||||
&:hover {
|
||||
background-color: #402626;
|
||||
border-color: #a10000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> .icon_x24 {
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.button {
|
||||
cursor: pointer;
|
||||
align-items: center;
|
||||
|
||||
margin-right: 5px;
|
||||
margin-left: 5px;
|
||||
|
||||
&:not(.icon_x24) {
|
||||
min-width: 28px;
|
||||
max-width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
.button-dropdown {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
|
||||
.buttons {
|
||||
margin-top: 1px;
|
||||
height: 28px;
|
||||
|
||||
align-items: center;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
.button {
|
||||
margin-right: 0;
|
||||
}
|
||||
.dropdown-arrow {
|
||||
height: 28px;
|
||||
|
||||
.button-dropdown {
|
||||
display: inline-flex;
|
||||
justify-content: space-around;
|
||||
width: 18px;
|
||||
cursor: pointer;
|
||||
|
||||
border-radius: 0 5px 5px 0;
|
||||
border-radius: 0 3px 3px 0;
|
||||
align-items: center;
|
||||
border: 2px solid rgba(0, 0, 0, 0);
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.button {
|
||||
border-right: 1px;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
.button {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
background-color: rgba(0,0,0,0.4);
|
||||
border-color: rgba(255, 255, 255, .75);
|
||||
/*box-shadow: 0 12px 16px 0 rgba(0,0,0,0.24), 0 17px 50px 0 rgba(0,0,0,0.19);*/
|
||||
&:hover {
|
||||
.button, .dropdown-arrow {
|
||||
background-color: #393c43;
|
||||
border-color: #4a4c55;
|
||||
}
|
||||
|
||||
.button-dropdown {
|
||||
background-color: rgba(0,0,0,0.4);
|
||||
border-color: rgba(255, 255, 255, .75);
|
||||
/*box-shadow: 0 12px 16px 0 rgba(0,0,0,0.24), 0 17px 50px 0 rgba(0,0,0,0.19);*/
|
||||
border-left: 2px solid rgba(255, 255, 255, .75);
|
||||
.button {
|
||||
padding-right: 1px;
|
||||
border-right: 0;
|
||||
|
||||
border-bottom-right-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -98,10 +127,13 @@ $background:lightgray;
|
|||
position: absolute;
|
||||
margin-left: 5px;
|
||||
|
||||
background-color: $background;
|
||||
border-radius: 5px;
|
||||
color: #c4c5c5;
|
||||
|
||||
background-color: #2d3032;
|
||||
align-items: center;
|
||||
border: 2px solid $border_color_activated;
|
||||
border: 1px solid #2c2525;
|
||||
border-radius: 0 5px 5px 5px;
|
||||
|
||||
width: 230px;
|
||||
|
||||
z-index: 1000;
|
||||
|
@ -122,7 +154,7 @@ $background:lightgray;
|
|||
padding: 1px 2px 1px 4px;
|
||||
|
||||
&:hover {
|
||||
background-color: $background_activated;
|
||||
background-color: #252729;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,7 +167,8 @@ $background:lightgray;
|
|||
}
|
||||
|
||||
&.display_left {
|
||||
margin-left: -165px;
|
||||
margin-left: -179px;
|
||||
border-radius: 5px 0 5px 5px;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -143,6 +176,22 @@ $background:lightgray;
|
|||
.dropdown {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.button, .dropdown-arrow {
|
||||
background-color: #393c43;
|
||||
border-color: #4a4c55;
|
||||
|
||||
border-bottom-right-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
.button {
|
||||
padding-right: 1px;
|
||||
border-right: 0;
|
||||
|
||||
border-bottom-right-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,410 @@
|
|||
.container-chat-frame {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: stretch;
|
||||
|
||||
.container-info {
|
||||
user-select: none;
|
||||
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
|
||||
height: 9em;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-evenly;
|
||||
|
||||
background-color: #2e2e2e;
|
||||
border-top-left-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
|
||||
-moz-box-shadow: inset 0 0 5px #00000040;
|
||||
-webkit-box-shadow: inset 0 0 5px #00000040;
|
||||
box-shadow: inset 0 0 5px #00000040;
|
||||
|
||||
.lane {
|
||||
padding-right: 10px;
|
||||
padding-left: 10px;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: stretch;
|
||||
|
||||
.block {
|
||||
flex-shrink: 1;
|
||||
flex-grow: 1;
|
||||
|
||||
min-width: 0;
|
||||
|
||||
&.right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
&.left {
|
||||
text-align: left;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.title, .value, .small-value {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.title {
|
||||
display: block;
|
||||
color: #8b8b8b;
|
||||
|
||||
.container-indicator {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
|
||||
background: #ca3e22;
|
||||
border: 1px solid #6a0e0e;
|
||||
border-radius: 4px;
|
||||
|
||||
text-align: center;
|
||||
|
||||
vertical-align: text-top;
|
||||
|
||||
color: #dab8b4;
|
||||
|
||||
font-size: .66em;
|
||||
height: .9em;
|
||||
min-width: .9em;
|
||||
|
||||
padding-right: 2px;
|
||||
padding-left: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.value {
|
||||
color: #5a5a5a;
|
||||
background-color: #373737;
|
||||
|
||||
display: inline-block;
|
||||
|
||||
border-radius: 3px;
|
||||
padding-right: 5px;
|
||||
padding-left: 5px;
|
||||
|
||||
> div {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.icon-container {
|
||||
margin-right: 5px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.small-value {
|
||||
display: inline-block;
|
||||
color: #5a5a5a;
|
||||
font-size: .66em;
|
||||
vertical-align: top;
|
||||
margin-top: -.2em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.container-chat {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
|
||||
border-bottom-left-radius: 5px;
|
||||
border-bottom-right-radius: 5px;
|
||||
|
||||
min-width: 350px;
|
||||
min-height: 200px;
|
||||
|
||||
.container-private-conversations {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: stretch;
|
||||
|
||||
.conversation-list {
|
||||
margin-right: -2px; /* the fix for the seperator with of 3px */
|
||||
user-select: none;
|
||||
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
|
||||
width: 25%;
|
||||
min-width: 100px;
|
||||
|
||||
position: relative;
|
||||
|
||||
.no-chats {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
|
||||
> div {
|
||||
display: inline-block;
|
||||
color: #5a5a5a;
|
||||
}
|
||||
}
|
||||
|
||||
//Avatar within cat 40x40
|
||||
.conversation-entry {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: stretch;
|
||||
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid #313132;
|
||||
|
||||
.container-avatar {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
|
||||
position: relative;
|
||||
|
||||
display: inline-block;
|
||||
margin: 5px 10px 5px 5px;
|
||||
|
||||
.avatar {
|
||||
overflow: hidden;
|
||||
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.chat-unread {
|
||||
display: none;
|
||||
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
background-color: #a81414;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
|
||||
border-radius: 50%;
|
||||
|
||||
-webkit-box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.20);
|
||||
-moz-box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.20);
|
||||
box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.20);
|
||||
}
|
||||
}
|
||||
|
||||
&.unread {
|
||||
.chat-unread {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
min-width: 50px;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
> * {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.client-name {
|
||||
color: #bebebe;
|
||||
font-weight: bold;
|
||||
|
||||
margin-bottom: -.4em;
|
||||
}
|
||||
|
||||
.last-message {
|
||||
color: #555353;
|
||||
|
||||
display: inline-block;
|
||||
font-size: .66em;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #393939;
|
||||
}
|
||||
|
||||
&.selected {
|
||||
background-color: #2c2c2c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.conversation {
|
||||
min-width: 250px;
|
||||
width: 75%;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: stretch;
|
||||
|
||||
.messages {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
|
||||
min-height: 100px;
|
||||
}
|
||||
|
||||
.chatbox {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 1;
|
||||
|
||||
display: flex;
|
||||
justify-content: stretch;
|
||||
flex-direction: column;
|
||||
|
||||
min-height: 2em;
|
||||
}
|
||||
}
|
||||
|
||||
.container-seperator {
|
||||
z-index: 100;
|
||||
height: unset!important;
|
||||
width: 3px;
|
||||
background-color: transparent;
|
||||
border-right: 1px solid #292a2c;
|
||||
}
|
||||
}
|
||||
|
||||
.container-chatbox {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
min-height: calc(1.5em + 10px);
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: stretch;
|
||||
|
||||
width: 100%;
|
||||
padding: 5px;
|
||||
|
||||
.container-emojis {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
|
||||
margin-right: 5px;
|
||||
|
||||
.button-emoji {
|
||||
border-radius: 5px;
|
||||
padding: 2px;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: #393939;
|
||||
}
|
||||
|
||||
.container-icon {
|
||||
display: flex;
|
||||
|
||||
width: calc(1.5em - 4px);
|
||||
height: calc(1.5em - 4px);
|
||||
|
||||
> img {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.container-input {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: stretch;
|
||||
min-height: 1.5em;
|
||||
|
||||
width: 100%;
|
||||
background-color: #464646;
|
||||
padding: 0 5px;
|
||||
|
||||
overflow: hidden;
|
||||
border-radius: 5px;
|
||||
|
||||
textarea {
|
||||
-webkit-user-select: text;
|
||||
-moz-user-select: text;
|
||||
-ms-user-select: text;
|
||||
user-select: text;
|
||||
|
||||
width: 100%;
|
||||
resize: vertical;
|
||||
|
||||
min-height: 1.5em;
|
||||
max-height: 6em;
|
||||
height: 1.5em;
|
||||
|
||||
background-color: transparent;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: none;
|
||||
outline: none;
|
||||
|
||||
color: #a9a9a9;
|
||||
}
|
||||
|
||||
textarea::-webkit-input-placeholder {
|
||||
color: #363535;
|
||||
font-style: oblique;
|
||||
}
|
||||
textarea:-moz-placeholder {
|
||||
color: #363535;
|
||||
font-style: oblique;
|
||||
}
|
||||
textarea::-moz-placeholder {
|
||||
color: #363535;
|
||||
font-style: oblique;
|
||||
}
|
||||
textarea:-ms-input-placeholder {
|
||||
color: #363535;
|
||||
font-style: oblique;
|
||||
}
|
||||
textarea::-ms-input-placeholder {
|
||||
color: #363535;
|
||||
font-style: oblique;
|
||||
}
|
||||
textarea::placeholder {
|
||||
color: #363535;
|
||||
font-style: oblique;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -212,249 +212,6 @@ code {
|
|||
padding: 2px;
|
||||
}
|
||||
|
||||
footer {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
bottom: 0px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
height: 25px;
|
||||
background-color: lightgray;
|
||||
|
||||
display: flex;
|
||||
}
|
||||
|
||||
footer .container {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
position: relative;
|
||||
vertical-align: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
$separator_thickness: 4px;
|
||||
$small_device: 650px;
|
||||
$animation_length: .5s;
|
||||
|
||||
.app {
|
||||
min-width: 350px;
|
||||
min-height: 330px;
|
||||
|
||||
.container-app-main {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: stretch;
|
||||
|
||||
min-height: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
|
||||
border: $separator_thickness solid lightgray;
|
||||
border-top-width: 0;
|
||||
}
|
||||
|
||||
.container-control-bar {
|
||||
flex-shrink: 0;
|
||||
|
||||
height: 45px;
|
||||
width: 100%;
|
||||
border-radius: 2px 2px 0 0;
|
||||
border-bottom-width: 0;
|
||||
background-color: lightgrey;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.container-channel-chat {
|
||||
min-width: 100px;
|
||||
width: 60%;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: stretch;
|
||||
|
||||
.container-channel-tree {
|
||||
background: white;
|
||||
|
||||
display: flex;
|
||||
justify-content: stretch;
|
||||
height: calc(100% - 250px);
|
||||
min-height: 100px;
|
||||
|
||||
/*
|
||||
overflow: auto;
|
||||
overflow-x: visible;
|
||||
*/
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.container-chat {
|
||||
background: white;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: stretch;
|
||||
|
||||
//max-height: 400px;
|
||||
height: 250px;
|
||||
min-height: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
.container-info {
|
||||
background: white;
|
||||
|
||||
min-width: 100px;
|
||||
width: 40%;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: stretch;
|
||||
}
|
||||
|
||||
|
||||
.hide-small {
|
||||
opacity: 1;
|
||||
transition: opacity $animation_length linear;
|
||||
}
|
||||
|
||||
.show-small {
|
||||
display: none;
|
||||
|
||||
opacity: 0;
|
||||
transition: opacity $animation_length linear;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 400px), only screen and (max-height: 400px) {
|
||||
.app-container {
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $small_device) {
|
||||
.app-container {
|
||||
right: 0!important;
|
||||
left: 0!important;;
|
||||
top: 0!important;;
|
||||
|
||||
transition: all $animation_length linear;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.app {
|
||||
.container-app-main {
|
||||
|
||||
.container-info {
|
||||
display: none;
|
||||
position: absolute;
|
||||
|
||||
width: 100% !important; /* override the seperator property */
|
||||
height: 100%;
|
||||
|
||||
z-index: 1000;
|
||||
|
||||
&.shown {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.select_info {
|
||||
> .close {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.container-channel-chat + .container-seperator {
|
||||
display: none;
|
||||
animation: fadeout $animation_length linear;
|
||||
}
|
||||
|
||||
.container-channel-chat {
|
||||
width: 100% !important; /* override the seperator property */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.hide-small {
|
||||
display: none;
|
||||
opacity: 0;
|
||||
transition: opacity $animation_length linear;
|
||||
}
|
||||
|
||||
.show-small {
|
||||
display: block !important;
|
||||
|
||||
opacity: 1 !important;
|
||||
transition: opacity $animation_length linear;
|
||||
}
|
||||
}
|
||||
|
||||
.container-seperator {
|
||||
background: lightgray;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
|
||||
&.horizontal {
|
||||
height: $separator_thickness;
|
||||
width: 100%;
|
||||
|
||||
cursor: row-resize;
|
||||
}
|
||||
|
||||
&.vertical {
|
||||
width: $separator_thickness;
|
||||
height: 100%;
|
||||
|
||||
cursor: col-resize;
|
||||
}
|
||||
|
||||
&.seperator-selected {
|
||||
background-color: #00000011;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-container {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
|
||||
> img {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
#mouse-move {
|
||||
display: none;
|
||||
position: absolute;
|
||||
z-index: 10000;
|
||||
|
||||
.container {
|
||||
position: relative;
|
||||
display: block;
|
||||
|
||||
border: 2px solid gray;
|
||||
-webkit-border-radius: 2px;
|
||||
-moz-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
html, body {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
body {
|
||||
padding: 8px;
|
||||
background: darkgray !important;
|
||||
}
|
||||
|
||||
.icon-playlist-manage {
|
||||
&.icon {
|
||||
width: 16px;
|
||||
|
@ -472,6 +229,14 @@ body {
|
|||
background-size: 50px;
|
||||
}
|
||||
|
||||
&.icon_x24 {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
|
||||
background-position: -11px -9px;
|
||||
background-size: 50px;
|
||||
}
|
||||
|
||||
display: inline-block;
|
||||
background: url('../../img/music/playlist.svg') no-repeat;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,260 @@
|
|||
$separator_thickness: 5px;
|
||||
$small_device: 650px;
|
||||
$animation_length: .5s;
|
||||
|
||||
|
||||
.app {
|
||||
min-width: 350px;
|
||||
min-height: 330px;
|
||||
|
||||
.container-app-main {
|
||||
margin-top: 5px;
|
||||
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: stretch;
|
||||
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
.container-channel-chat {
|
||||
min-height: 200px;
|
||||
min-width: 100px;
|
||||
width: 100%;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: stretch;
|
||||
|
||||
& > * {
|
||||
height: 100%;
|
||||
min-height: 250px;
|
||||
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.container-channel-tree {
|
||||
background: #353535;
|
||||
min-width: 200px;
|
||||
|
||||
display: flex;
|
||||
justify-content: stretch;
|
||||
height: 100%;
|
||||
min-height: 100px;
|
||||
|
||||
padding-top: 5px;
|
||||
/*
|
||||
overflow: auto;
|
||||
overflow-x: visible;
|
||||
*/
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.container-chat {
|
||||
background: #353535;
|
||||
min-width: 350px;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: stretch;
|
||||
}
|
||||
}
|
||||
|
||||
.container-server-log {
|
||||
min-height: 0;
|
||||
height: 250px;
|
||||
width: 100%;
|
||||
|
||||
border-radius: 5px;
|
||||
padding-right: 5px;
|
||||
padding-left: 5px;
|
||||
|
||||
background: #353535;
|
||||
}
|
||||
}
|
||||
|
||||
.container-control-bar {
|
||||
z-index: 200;
|
||||
|
||||
flex-shrink: 0;
|
||||
|
||||
border-radius: 5px;
|
||||
|
||||
height: 30px;
|
||||
width: 100%;
|
||||
|
||||
background-color: #454545;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.hide-small {
|
||||
opacity: 1;
|
||||
transition: opacity $animation_length linear;
|
||||
}
|
||||
|
||||
.show-small {
|
||||
display: none;
|
||||
|
||||
opacity: 0;
|
||||
transition: opacity $animation_length linear;
|
||||
}
|
||||
}
|
||||
|
||||
.app-container {
|
||||
right: 0;
|
||||
left: 0;
|
||||
top: 0;
|
||||
|
||||
overflow: auto;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 400px), only screen and (max-height: 400px) {
|
||||
.app-container {
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $small_device) {
|
||||
.app {
|
||||
.container-app-main {
|
||||
.container-info {
|
||||
display: none;
|
||||
position: absolute;
|
||||
|
||||
width: 100% !important; /* override the seperator property */
|
||||
height: 100%;
|
||||
|
||||
z-index: 1000;
|
||||
|
||||
&.shown {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.select_info {
|
||||
> .close {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.container-channel-chat + .container-seperator {
|
||||
display: none;
|
||||
animation: fadeout $animation_length linear;
|
||||
}
|
||||
|
||||
.container-channel-chat {
|
||||
width: 100% !important; /* override the seperator property */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.hide-small {
|
||||
display: none;
|
||||
opacity: 0;
|
||||
transition: opacity $animation_length linear;
|
||||
}
|
||||
|
||||
.show-small {
|
||||
display: block !important;
|
||||
|
||||
opacity: 1 !important;
|
||||
transition: opacity $animation_length linear;
|
||||
}
|
||||
}
|
||||
|
||||
$animation_seperator_length: .1s;
|
||||
.container-seperator {
|
||||
-moz-transition: all $animation_seperator_length ease-in;
|
||||
-o-transition: all $animation_seperator_length ease-in;
|
||||
-webkit-transition: all $animation_seperator_length ease-in;
|
||||
transition: all $animation_seperator_length ease-in;
|
||||
|
||||
background: #1e1e1e;
|
||||
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
|
||||
&.horizontal {
|
||||
height: $separator_thickness;
|
||||
width: 100%;
|
||||
|
||||
cursor: row-resize;
|
||||
}
|
||||
|
||||
&.vertical {
|
||||
width: $separator_thickness;
|
||||
height: 100%;
|
||||
|
||||
cursor: col-resize;
|
||||
}
|
||||
|
||||
&.seperator-selected {
|
||||
-moz-transition: all $animation_seperator_length ease-in;
|
||||
-o-transition: all $animation_seperator_length ease-in;
|
||||
-webkit-transition: all $animation_seperator_length ease-in;
|
||||
transition: all $animation_seperator_length ease-in;
|
||||
|
||||
background-color: #707070;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-container {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
|
||||
> img {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
#mouse-move {
|
||||
display: none;
|
||||
position: absolute;
|
||||
z-index: 10000;
|
||||
|
||||
.container {
|
||||
position: relative;
|
||||
display: block;
|
||||
|
||||
border: 2px solid gray;
|
||||
-webkit-border-radius: 2px;
|
||||
-moz-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
html, body {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #1e1e1e !important;
|
||||
}
|
||||
|
||||
footer {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
bottom: 0px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
height: 25px;
|
||||
background-color: lightgray;
|
||||
|
||||
display: flex;
|
||||
}
|
||||
|
||||
footer .container {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
position: relative;
|
||||
vertical-align: center;
|
||||
justify-content: center;
|
||||
}
|
|
@ -1 +1,4 @@
|
|||
$channel_tree_entry_selected: blue;
|
||||
$channel_tree_entry_selected: #2d2d2d;
|
||||
$channel_tree_entry_hovered: #393939;
|
||||
|
||||
$channel_tree_entry_text_color: #828282;
|
|
@ -0,0 +1,56 @@
|
|||
.container-log {
|
||||
display: block;
|
||||
overflow-y: auto;
|
||||
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
.container-messages {
|
||||
width: 100%;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.log-message {
|
||||
flex-shrink: 0;
|
||||
flex-grow: 0;
|
||||
|
||||
color: #6e6e6e;
|
||||
|
||||
overflow-x: hidden;
|
||||
overflow-y: hidden;
|
||||
|
||||
display: block;
|
||||
|
||||
&, > * {
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
> * {
|
||||
display: inline-block;
|
||||
|
||||
font-family: sans-serif;
|
||||
font-size: 13px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
> .timestamp {
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
|
||||
.log-error {
|
||||
color: rgba(230, 34, 34, 1);
|
||||
|
||||
&:hover {
|
||||
color: rgba(230, 34, 34, 1);
|
||||
}
|
||||
}
|
||||
|
||||
.htmltag-client, .htmltag-channel {
|
||||
color: #d8d8d8;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -928,7 +928,7 @@
|
|||
background-position: calc(-128px * 2) calc(-192px * 2);
|
||||
}
|
||||
.icon_x32.client-message_info {
|
||||
background-position: calc(-160px * 2)pe the key you wish calc(-192px * 2);
|
||||
background-position: calc(-160px * 2) calc(-192px * 2);
|
||||
}
|
||||
.icon_x32.client-message_outgoing {
|
||||
background-position: calc(-192px * 2) calc(-192px * 2);
|
||||
|
@ -969,7 +969,7 @@
|
|||
.icon_x32.client-permission_overview {
|
||||
background-position: calc(-64px * 2) calc(-224px * 2);
|
||||
}
|
||||
.icon_x32.client-permission_server_groups pe the key you wish{
|
||||
.icon_x32.client-permission_server_groups {
|
||||
background-position: calc(-96px * 2) calc(-224px * 2);
|
||||
}
|
||||
.icon_x32.client-phoneticsnickname {
|
||||
|
@ -1220,4 +1220,615 @@
|
|||
}
|
||||
.icon_x32.client-home {
|
||||
background-position: calc(-192px * 2) calc(-384px * 2);
|
||||
}
|
||||
|
||||
|
||||
/* replace pattern: "background-position: calc\(((\-?[0-9]{1,3})(px)? \* 2)\) calc\(((\-?[0-9]{1,3})(px)? \* 2)\);" */
|
||||
/* replace with: "background-position: calc\($2px * 1.5) calc($5px * 1.5);" */
|
||||
/* Icons x24 */
|
||||
|
||||
.icon_x24 {
|
||||
display: inline-block;
|
||||
background: url('../../../img/client_icon_sprite.svg'), url('../../img/client_icon_sprite.svg') no-repeat;
|
||||
background-size: calc(496px * 1.5) calc(400px * 1.5);
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
}
|
||||
|
||||
.icon_x24.client-d_sound {
|
||||
background-position: calc(0px * 1.5) calc(0px * 1.5);
|
||||
}
|
||||
.icon_x24.client-d_sound_me {
|
||||
background-position: calc(-32px * 1.5) calc(0px * 1.5);
|
||||
}
|
||||
.icon_x24.client-d_sound_user {
|
||||
background-position: calc(-64px * 1.5) calc(0px * 1.5);
|
||||
}
|
||||
.icon_x24.client-about {
|
||||
background-position: calc(-96px * 1.5) calc(0px * 1.5);
|
||||
}
|
||||
.icon_x24.client-activate_microphone {
|
||||
background-position: calc(-128px * 1.5) calc(0px * 1.5);
|
||||
}
|
||||
.icon_x24.client-add {
|
||||
background-position: calc(-160px * 1.5) calc(0px * 1.5);
|
||||
}
|
||||
.icon_x24.client-add_foe {
|
||||
background-position: calc(-192px * 1.5) calc(0px * 1.5);
|
||||
}
|
||||
.icon_x24.client-add_folder {
|
||||
background-position: calc(-224px * 1.5) calc(0px * 1.5);
|
||||
}
|
||||
.icon_x24.client-add_friend {
|
||||
background-position: calc(-256px * 1.5) calc(0px * 1.5);
|
||||
}
|
||||
.icon_x24.client-addon {
|
||||
background-position: calc(-288px * 1.5) calc(0px * 1.5);
|
||||
}
|
||||
.icon_x24.client-addon-collection {
|
||||
background-position: calc(-320px * 1.5) calc(0px * 1.5);
|
||||
}
|
||||
.icon_x24.client-apply {
|
||||
background-position: calc(-352px * 1.5) calc(0px * 1.5);
|
||||
}
|
||||
.icon_x24.client-arrow_down {
|
||||
background-position: calc(-384px * 1.5) calc(0px * 1.5);
|
||||
}
|
||||
.icon_x24.client-arrow_left {
|
||||
background-position: calc(-416px * 1.5) calc(0px * 1.5);
|
||||
}
|
||||
.icon_x24.client-arrow_right {
|
||||
background-position: calc(-448px * 1.5) calc(0px * 1.5);
|
||||
}
|
||||
.icon_x24.client-arrow_up {
|
||||
background-position: calc(-480px * 1.5) calc(0px * 1.5);
|
||||
}
|
||||
.icon_x24.client-away {
|
||||
background-position: calc(0px * 1.5) calc(-32px * 1.5);
|
||||
}
|
||||
.icon_x24.client-ban_client {
|
||||
background-position: calc(-32px * 1.5) calc(-32px * 1.5);
|
||||
}
|
||||
.icon_x24.client-ban_list {
|
||||
background-position: calc(-64px * 1.5) calc(-32px * 1.5);
|
||||
}
|
||||
.icon_x24.client-bookmark_add {
|
||||
background-position: calc(-96px * 1.5) calc(-32px * 1.5);
|
||||
}
|
||||
.icon_x24.client-bookmark_add_folder {
|
||||
background-position: calc(-128px * 1.5) calc(-32px * 1.5);
|
||||
}
|
||||
.icon_x24.client-bookmark_duplicate {
|
||||
background-position: calc(-160px * 1.5) calc(-32px * 1.5);
|
||||
}
|
||||
.icon_x24.client-bookmark_manager {
|
||||
background-position: calc(-192px * 1.5) calc(-32px * 1.5);
|
||||
}
|
||||
.icon_x24.client-bookmark_remove {
|
||||
background-position: calc(-224px * 1.5) calc(-32px * 1.5);
|
||||
}
|
||||
.icon_x24.client-broken_image {
|
||||
background-position: calc(-256px * 1.5) calc(-32px * 1.5);
|
||||
}
|
||||
.icon_x24.client-browse-addon-online {
|
||||
background-position: calc(-288px * 1.5) calc(-32px * 1.5);
|
||||
}
|
||||
.icon_x24.client-capture {
|
||||
background-position: calc(-320px * 1.5) calc(-32px * 1.5);
|
||||
}
|
||||
.icon_x24.client-changelog {
|
||||
background-position: calc(-352px * 1.5) calc(-32px * 1.5);
|
||||
}
|
||||
.icon_x24.client-change_nickname {
|
||||
background-position: calc(-384px * 1.5) calc(-32px * 1.5);
|
||||
}
|
||||
.icon_x24.client-channel_chat {
|
||||
background-position: calc(-416px * 1.5) calc(-32px * 1.5);
|
||||
}
|
||||
.icon_x24.client-channel_collapse_all {
|
||||
background-position: calc(-448px * 1.5) calc(-32px * 1.5);
|
||||
}
|
||||
.icon_x24.client-channel_commander {
|
||||
background-position: calc(-480px * 1.5) calc(-32px * 1.5);
|
||||
}
|
||||
.icon_x24.client-channel_create {
|
||||
background-position: calc(0px * 1.5) calc(-64px * 1.5);
|
||||
}
|
||||
.icon_x24.client-channel_create_sub {
|
||||
background-position: calc(-32px * 1.5) calc(-64px * 1.5);
|
||||
}
|
||||
.icon_x24.client-channel_default {
|
||||
background-position: calc(-64px * 1.5) calc(-64px * 1.5);
|
||||
}
|
||||
.icon_x24.client-channel_delete {
|
||||
background-position: calc(-96px * 1.5) calc(-64px * 1.5);
|
||||
}
|
||||
.icon_x24.client-channel_edit {
|
||||
background-position: calc(-128px * 1.5) calc(-64px * 1.5);
|
||||
}
|
||||
.icon_x24.client-channel_expand_all {
|
||||
background-position: calc(-160px * 1.5) calc(-64px * 1.5);
|
||||
}
|
||||
.icon_x24.client-channel_green {
|
||||
background-position: calc(-192px * 1.5) calc(-64px * 1.5);
|
||||
}
|
||||
.icon_x24.client-channel_green_subscribed {
|
||||
background-position: calc(-224px * 1.5) calc(-64px * 1.5);
|
||||
}
|
||||
.icon_x24.client-channel_private {
|
||||
background-position: calc(-256px * 1.5) calc(-64px * 1.5);
|
||||
}
|
||||
.icon_x24.client-channel_red {
|
||||
background-position: calc(-288px * 1.5) calc(-64px * 1.5);
|
||||
}
|
||||
.icon_x24.client-channel_red_subscribed {
|
||||
background-position: calc(-320px * 1.5) calc(-64px * 1.5);
|
||||
}
|
||||
.icon_x24.client-channel_switch {
|
||||
background-position: calc(-352px * 1.5) calc(-64px * 1.5);
|
||||
}
|
||||
.icon_x24.client-channel_unsubscribed {
|
||||
background-position: calc(-384px * 1.5) calc(-64px * 1.5);
|
||||
}
|
||||
.icon_x24.client-channel_yellow {
|
||||
background-position: calc(-416px * 1.5) calc(-64px * 1.5);
|
||||
}
|
||||
.icon_x24.client-channel_yellow_subscribed {
|
||||
background-position: calc(-448px * 1.5) calc(-64px * 1.5);
|
||||
}
|
||||
.icon_x24.client-check_update {
|
||||
background-position: calc(-480px * 1.5) calc(-64px * 1.5);
|
||||
}
|
||||
.icon_x24.client-client_hide {
|
||||
background-position: calc(0px * 1.5) calc(-96px * 1.5);
|
||||
}
|
||||
.icon_x24.client-client_show {
|
||||
background-position: calc(-32px * 1.5) calc(-96px * 1.5);
|
||||
}
|
||||
.icon_x24.client-close_button {
|
||||
background-position: calc(-64px * 1.5) calc(-96px * 1.5);
|
||||
}
|
||||
.icon_x24.client-complaint_list {
|
||||
background-position: calc(-96px * 1.5) calc(-96px * 1.5);
|
||||
}
|
||||
.icon_x24.client-conflict-icon {
|
||||
background-position: calc(-128px * 1.5) calc(-96px * 1.5);
|
||||
}
|
||||
.icon_x24.client-connect {
|
||||
background-position: calc(-160px * 1.5) calc(-96px * 1.5);
|
||||
}
|
||||
.icon_x24.client-contact {
|
||||
background-position: calc(-192px * 1.5) calc(-96px * 1.5);
|
||||
}
|
||||
.icon_x24.client-copy {
|
||||
background-position: calc(-224px * 1.5) calc(-96px * 1.5);
|
||||
}
|
||||
.icon_x24.client-copy_url {
|
||||
background-position: calc(-256px * 1.5) calc(-96px * 1.5);
|
||||
}
|
||||
.icon_x24.client-default {
|
||||
background-position: calc(-288px * 1.5) calc(-96px * 1.5);
|
||||
}
|
||||
.icon_x24.client-default_for_all_bookmarks {
|
||||
background-position: calc(-320px * 1.5) calc(-96px * 1.5);
|
||||
}
|
||||
.icon_x24.client-delete {
|
||||
background-position: calc(-352px * 1.5) calc(-96px * 1.5);
|
||||
}
|
||||
.icon_x24.client-delete_avatar {
|
||||
background-position: calc(-384px * 1.5) calc(-96px * 1.5);
|
||||
}
|
||||
.icon_x24.client-disconnect {
|
||||
background-position: calc(-416px * 1.5) calc(-96px * 1.5);
|
||||
}
|
||||
.icon_x24.client-down {
|
||||
background-position: calc(-448px * 1.5) calc(-96px * 1.5);
|
||||
}
|
||||
.icon_x24.client-download {
|
||||
background-position: calc(-480px * 1.5) calc(-96px * 1.5);
|
||||
}
|
||||
.icon_x24.client-edit {
|
||||
background-position: calc(0px * 1.5) calc(-128px * 1.5);
|
||||
}
|
||||
.icon_x24.client-edit_friend_foe_status {
|
||||
background-position: calc(-32px * 1.5) calc(-128px * 1.5);
|
||||
}
|
||||
.icon_x24.client-emoticon {
|
||||
background-position: calc(-64px * 1.5) calc(-128px * 1.5);
|
||||
}
|
||||
.icon_x24.client-error {
|
||||
background-position: calc(-96px * 1.5) calc(-128px * 1.5);
|
||||
}
|
||||
.icon_x24.client-file_home {
|
||||
background-position: calc(-128px * 1.5) calc(-128px * 1.5);
|
||||
}
|
||||
.icon_x24.client-file_refresh {
|
||||
background-position: calc(-160px * 1.5) calc(-128px * 1.5);
|
||||
}
|
||||
.icon_x24.client-filetransfer {
|
||||
background-position: calc(-192px * 1.5) calc(-128px * 1.5);
|
||||
}
|
||||
.icon_x24.client-find {
|
||||
background-position: calc(-224px * 1.5) calc(-128px * 1.5);
|
||||
}
|
||||
.icon_x24.client-folder {
|
||||
background-position: calc(-256px * 1.5) calc(-128px * 1.5);
|
||||
}
|
||||
.icon_x24.client-folder_up {
|
||||
background-position: calc(-288px * 1.5) calc(-128px * 1.5);
|
||||
}
|
||||
.icon_x24.client-group_100 {
|
||||
background-position: calc(-320px * 1.5) calc(-128px * 1.5);
|
||||
}
|
||||
.icon_x24.client-group_200 {
|
||||
background-position: calc(-352px * 1.5) calc(-128px * 1.5);
|
||||
}
|
||||
.icon_x24.client-group_300 {
|
||||
background-position: calc(-384px * 1.5) calc(-128px * 1.5);
|
||||
}
|
||||
.icon_x24.client-group_500 {
|
||||
background-position: calc(-416px * 1.5) calc(-128px * 1.5);
|
||||
}
|
||||
.icon_x24.client-group_600 {
|
||||
background-position: calc(-448px * 1.5) calc(-128px * 1.5);
|
||||
}
|
||||
.icon_x24.client-guisetup {
|
||||
background-position: calc(-480px * 1.5) calc(-128px * 1.5);
|
||||
}
|
||||
.icon_x24.client-hardware_input_muted {
|
||||
background-position: calc(0px * 1.5) calc(-160px * 1.5);
|
||||
}
|
||||
.icon_x24.client-hardware_output_muted {
|
||||
background-position: calc(-32px * 1.5) calc(-160px * 1.5);
|
||||
}
|
||||
.icon_x24.client-hoster_button {
|
||||
background-position: calc(-64px * 1.5) calc(-160px * 1.5);
|
||||
}
|
||||
.icon_x24.client-hotkeys {
|
||||
background-position: calc(-96px * 1.5) calc(-160px * 1.5);
|
||||
}
|
||||
.icon_x24.client-icon-pack {
|
||||
background-position: calc(-128px * 1.5) calc(-160px * 1.5);
|
||||
}
|
||||
.icon_x24.client-iconsview {
|
||||
background-position: calc(-160px * 1.5) calc(-160px * 1.5);
|
||||
}
|
||||
.icon_x24.client-iconviewer {
|
||||
background-position: calc(-192px * 1.5) calc(-160px * 1.5);
|
||||
}
|
||||
.icon_x24.client-identity_default {
|
||||
background-position: calc(-224px * 1.5) calc(-160px * 1.5);
|
||||
}
|
||||
.icon_x24.client-identity_export {
|
||||
background-position: calc(-256px * 1.5) calc(-160px * 1.5);
|
||||
}
|
||||
.icon_x24.client-identity_import {
|
||||
background-position: calc(-288px * 1.5) calc(-160px * 1.5);
|
||||
}
|
||||
.icon_x24.client-identity_manager {
|
||||
background-position: calc(-320px * 1.5) calc(-160px * 1.5);
|
||||
}
|
||||
.icon_x24.client-info {
|
||||
background-position: calc(-352px * 1.5) calc(-160px * 1.5);
|
||||
}
|
||||
.icon_x24.client-input_muted {
|
||||
background-position: calc(-384px * 1.5) calc(-160px * 1.5);
|
||||
}
|
||||
.icon_x24.client-input_muted_local {
|
||||
background-position: calc(-416px * 1.5) calc(-160px * 1.5);
|
||||
}
|
||||
.icon_x24.client-invite_buddy {
|
||||
background-position: calc(-448px * 1.5) calc(-160px * 1.5);
|
||||
}
|
||||
.icon_x24.client-is_talker {
|
||||
background-position: calc(-480px * 1.5) calc(-160px * 1.5);
|
||||
}
|
||||
.icon_x24.client-kick_channel {
|
||||
background-position: calc(0px * 1.5) calc(-192px * 1.5);
|
||||
}
|
||||
.icon_x24.client-kick_server {
|
||||
background-position: calc(-32px * 1.5) calc(-192px * 1.5);
|
||||
}
|
||||
.icon_x24.client-listview {
|
||||
background-position: calc(-64px * 1.5) calc(-192px * 1.5);
|
||||
}
|
||||
.icon_x24.client-loading_image {
|
||||
background-position: calc(-96px * 1.5) calc(-192px * 1.5);
|
||||
}
|
||||
.icon_x24.client-message_incoming {
|
||||
background-position: calc(-128px * 1.5) calc(-192px * 1.5);
|
||||
}
|
||||
.icon_x24.client-message_info {
|
||||
background-position: calc(-160px * 1.5) calc(-192px * 1.5);
|
||||
}
|
||||
.icon_x24.client-message_outgoing {
|
||||
background-position: calc(-192px * 1.5) calc(-192px * 1.5);
|
||||
}
|
||||
.icon_x24.client-messages {
|
||||
background-position: calc(-224px * 1.5) calc(-192px * 1.5);
|
||||
}
|
||||
.icon_x24.client-moderated {
|
||||
background-position: calc(-256px * 1.5) calc(-192px * 1.5);
|
||||
}
|
||||
.icon_x24.client-move_client_to_own_channel {
|
||||
background-position: calc(-288px * 1.5) calc(-192px * 1.5);
|
||||
}
|
||||
.icon_x24.client-music {
|
||||
background-position: calc(-320px * 1.5) calc(-192px * 1.5);
|
||||
}
|
||||
.icon_x24.client-new_chat {
|
||||
background-position: calc(-352px * 1.5) calc(-192px * 1.5);
|
||||
}
|
||||
.icon_x24.client-notifications {
|
||||
background-position: calc(-384px * 1.5) calc(-192px * 1.5);
|
||||
}
|
||||
.icon_x24.client-offline_messages {
|
||||
background-position: calc(-416px * 1.5) calc(-192px * 1.5);
|
||||
}
|
||||
.icon_x24.client-on_whisperlist {
|
||||
background-position: calc(-448px * 1.5) calc(-192px * 1.5);
|
||||
}
|
||||
.icon_x24.client-output_muted {
|
||||
background-position: calc(-480px * 1.5) calc(-192px * 1.5);
|
||||
}
|
||||
.icon_x24.client-permission_channel {
|
||||
background-position: calc(0px * 1.5) calc(-224px * 1.5);
|
||||
}
|
||||
.icon_x24.client-permission_client {
|
||||
background-position: calc(-32px * 1.5) calc(-224px * 1.5);
|
||||
}
|
||||
.icon_x24.client-permission_overview {
|
||||
background-position: calc(-64px * 1.5) calc(-224px * 1.5);
|
||||
}
|
||||
.icon_x24.client-permission_server_groups {
|
||||
background-position: calc(-96px * 1.5) calc(-224px * 1.5);
|
||||
}
|
||||
.icon_x24.client-phoneticsnickname {
|
||||
background-position: calc(-128px * 1.5) calc(-224px * 1.5);
|
||||
}
|
||||
.icon_x24.client-ping_1 {
|
||||
background-position: calc(-160px * 1.5) calc(-224px * 1.5);
|
||||
}
|
||||
.icon_x24.client-ping_2 {
|
||||
background-position: calc(-192px * 1.5) calc(-224px * 1.5);
|
||||
}
|
||||
.icon_x24.client-ping_3 {
|
||||
background-position: calc(-224px * 1.5) calc(-224px * 1.5);
|
||||
}
|
||||
.icon_x24.client-ping_4 {
|
||||
background-position: calc(-256px * 1.5) calc(-224px * 1.5);
|
||||
}
|
||||
.icon_x24.client-ping_calculating {
|
||||
background-position: calc(-288px * 1.5) calc(-224px * 1.5);
|
||||
}
|
||||
.icon_x24.client-ping_disconnected {
|
||||
background-position: calc(-320px * 1.5) calc(-224px * 1.5);
|
||||
}
|
||||
.icon_x24.client-play {
|
||||
background-position: calc(-352px * 1.5) calc(-224px * 1.5);
|
||||
}
|
||||
.icon_x24.client-player_chat {
|
||||
background-position: calc(-384px * 1.5) calc(-224px * 1.5);
|
||||
}
|
||||
.icon_x24.client-player_commander_off {
|
||||
background-position: calc(-416px * 1.5) calc(-224px * 1.5);
|
||||
}
|
||||
.icon_x24.client-player_commander_on {
|
||||
background-position: calc(-448px * 1.5) calc(-224px * 1.5);
|
||||
}
|
||||
.icon_x24.client-player_off {
|
||||
background-position: calc(-480px * 1.5) calc(-224px * 1.5);
|
||||
}
|
||||
.icon_x24.client-player_on {
|
||||
background-position: calc(0px * 1.5) calc(-256px * 1.5);
|
||||
}
|
||||
.icon_x24.client-player_whisper {
|
||||
background-position: calc(-32px * 1.5) calc(-256px * 1.5);
|
||||
}
|
||||
.icon_x24.client-plugins {
|
||||
background-position: calc(-64px * 1.5) calc(-256px * 1.5);
|
||||
}
|
||||
.icon_x24.client-poke {
|
||||
background-position: calc(-96px * 1.5) calc(-256px * 1.5);
|
||||
}
|
||||
.icon_x24.client-present {
|
||||
background-position: calc(-128px * 1.5) calc(-256px * 1.5);
|
||||
}
|
||||
.icon_x24.client-recording_start {
|
||||
background-position: calc(-160px * 1.5) calc(-256px * 1.5);
|
||||
}
|
||||
.icon_x24.client-recording_stop {
|
||||
background-position: calc(-192px * 1.5) calc(-256px * 1.5);
|
||||
}
|
||||
.icon_x24.client-refresh {
|
||||
background-position: calc(-224px * 1.5) calc(-256px * 1.5);
|
||||
}
|
||||
.icon_x24.client-register {
|
||||
background-position: calc(-256px * 1.5) calc(-256px * 1.5);
|
||||
}
|
||||
.icon_x24.client-reload {
|
||||
background-position: calc(-288px * 1.5) calc(-256px * 1.5);
|
||||
}
|
||||
.icon_x24.client-remove_foe {
|
||||
background-position: calc(-320px * 1.5) calc(-256px * 1.5);
|
||||
}
|
||||
.icon_x24.client-remove_friend {
|
||||
background-position: calc(-352px * 1.5) calc(-256px * 1.5);
|
||||
}
|
||||
.icon_x24.client-security {
|
||||
background-position: calc(-384px * 1.5) calc(-256px * 1.5);
|
||||
}
|
||||
.icon_x24.client-selectfolder {
|
||||
background-position: calc(-416px * 1.5) calc(-256px * 1.5);
|
||||
}
|
||||
.icon_x24.client-send_complaint {
|
||||
background-position: calc(-448px * 1.5) calc(-256px * 1.5);
|
||||
}
|
||||
.icon_x24.client-server_green {
|
||||
background-position: calc(-480px * 1.5) calc(-256px * 1.5);
|
||||
}
|
||||
.icon_x24.client-server_log {
|
||||
background-position: calc(0px * 1.5) calc(-288px * 1.5);
|
||||
}
|
||||
.icon_x24.client-server_query {
|
||||
background-position: calc(-32px * 1.5) calc(-288px * 1.5);
|
||||
}
|
||||
.icon_x24.client-settings {
|
||||
background-position: calc(-64px * 1.5) calc(-288px * 1.5);
|
||||
}
|
||||
.icon_x24.client-sort_by_name {
|
||||
background-position: calc(-96px * 1.5) calc(-288px * 1.5);
|
||||
}
|
||||
.icon_x24.client-soundpack {
|
||||
background-position: calc(-128px * 1.5) calc(-288px * 1.5);
|
||||
}
|
||||
.icon_x24.client-sound-pack {
|
||||
background-position: calc(-160px * 1.5) calc(-288px * 1.5);
|
||||
}
|
||||
.icon_x24.client-stop {
|
||||
background-position: calc(-192px * 1.5) calc(-288px * 1.5);
|
||||
}
|
||||
.icon_x24.client-subscribe_mode {
|
||||
background-position: calc(-224px * 1.5) calc(-288px * 1.5);
|
||||
}
|
||||
.icon_x24.client-subscribe_to_all_channels {
|
||||
background-position: calc(-256px * 1.5) calc(-288px * 1.5);
|
||||
}
|
||||
.icon_x24.client-subscribe_to_channel {
|
||||
background-position: calc(-288px * 1.5) calc(-288px * 1.5);
|
||||
}
|
||||
.icon_x24.client-subscribe_to_channel_family {
|
||||
background-position: calc(-320px * 1.5) calc(-288px * 1.5);
|
||||
}
|
||||
.icon_x24.client-switch_advanced {
|
||||
background-position: calc(-352px * 1.5) calc(-288px * 1.5);
|
||||
}
|
||||
.icon_x24.client-switch_standard {
|
||||
background-position: calc(-384px * 1.5) calc(-288px * 1.5);
|
||||
}
|
||||
.icon_x24.client-sync-disable {
|
||||
background-position: calc(-416px * 1.5) calc(-288px * 1.5);
|
||||
}
|
||||
.icon_x24.client-sync-enable {
|
||||
background-position: calc(-448px * 1.5) calc(-288px * 1.5);
|
||||
}
|
||||
.icon_x24.client-sync-icon {
|
||||
background-position: calc(-480px * 1.5) calc(-288px * 1.5);
|
||||
}
|
||||
.icon_x24.client-tab_close_button {
|
||||
background-position: calc(0px * 1.5) calc(-320px * 1.5);
|
||||
}
|
||||
.icon_x24.client-talk_power_grant {
|
||||
background-position: calc(-32px * 1.5) calc(-320px * 1.5);
|
||||
}
|
||||
.icon_x24.client-talk_power_grant_next {
|
||||
background-position: calc(-64px * 1.5) calc(-320px * 1.5);
|
||||
}
|
||||
.icon_x24.client-talk_power_request {
|
||||
background-position: calc(-96px * 1.5) calc(-320px * 1.5);
|
||||
}
|
||||
.icon_x24.client-talk_power_request_cancel {
|
||||
background-position: calc(-128px * 1.5) calc(-320px * 1.5);
|
||||
}
|
||||
.icon_x24.client-talk_power_revoke {
|
||||
background-position: calc(-160px * 1.5) calc(-320px * 1.5);
|
||||
}
|
||||
.icon_x24.client-talk_power_revoke_all_grant_next {
|
||||
background-position: calc(-192px * 1.5) calc(-320px * 1.5);
|
||||
}
|
||||
.icon_x24.client-temp_server_password {
|
||||
background-position: calc(-224px * 1.5) calc(-320px * 1.5);
|
||||
}
|
||||
.icon_x24.client-temp_server_password_add {
|
||||
background-position: calc(-256px * 1.5) calc(-320px * 1.5);
|
||||
}
|
||||
.icon_x24.client-textformat {
|
||||
background-position: calc(-288px * 1.5) calc(-320px * 1.5);
|
||||
}
|
||||
.icon_x24.client-textformat_bold {
|
||||
background-position: calc(-320px * 1.5) calc(-320px * 1.5);
|
||||
}
|
||||
.icon_x24.client-textformat_foreground {
|
||||
background-position: calc(-352px * 1.5) calc(-320px * 1.5);
|
||||
}
|
||||
.icon_x24.client-textformat_italic {
|
||||
background-position: calc(-384px * 1.5) calc(-320px * 1.5);
|
||||
}
|
||||
.icon_x24.client-textformat_underline {
|
||||
background-position: calc(-416px * 1.5) calc(-320px * 1.5);
|
||||
}
|
||||
.icon_x24.client-theme {
|
||||
background-position: calc(-448px * 1.5) calc(-320px * 1.5);
|
||||
}
|
||||
.icon_x24.client-toggle_server_query_clients {
|
||||
background-position: calc(-480px * 1.5) calc(-320px * 1.5);
|
||||
}
|
||||
.icon_x24.client-toggle_whisper {
|
||||
background-position: calc(0px * 1.5) calc(-352px * 1.5);
|
||||
}
|
||||
.icon_x24.client-token {
|
||||
background-position: calc(-32px * 1.5) calc(-352px * 1.5);
|
||||
}
|
||||
.icon_x24.client-token_use {
|
||||
background-position: calc(-64px * 1.5) calc(-352px * 1.5);
|
||||
}
|
||||
.icon_x24.client-translation {
|
||||
background-position: calc(-96px * 1.5) calc(-352px * 1.5);
|
||||
}
|
||||
.icon_x24.client-unsubscribe_from_all_channels {
|
||||
background-position: calc(-128px * 1.5) calc(-352px * 1.5);
|
||||
}
|
||||
.icon_x24.client-unsubscribe_from_channel_family {
|
||||
background-position: calc(-160px * 1.5) calc(-352px * 1.5);
|
||||
}
|
||||
.icon_x24.client-unsubscribe_mode {
|
||||
background-position: calc(-192px * 1.5) calc(-352px * 1.5);
|
||||
}
|
||||
.icon_x24.client-up {
|
||||
background-position: calc(-224px * 1.5) calc(-352px * 1.5);
|
||||
}
|
||||
.icon_x24.client-upload {
|
||||
background-position: calc(-256px * 1.5) calc(-352px * 1.5);
|
||||
}
|
||||
.icon_x24.client-upload_avatar {
|
||||
background-position: calc(-288px * 1.5) calc(-352px * 1.5);
|
||||
}
|
||||
.icon_x24.client-urlcatcher {
|
||||
background-position: calc(-320px * 1.5) calc(-352px * 1.5);
|
||||
}
|
||||
.icon_x24.client-user-account {
|
||||
background-position: calc(-352px * 1.5) calc(-352px * 1.5);
|
||||
}
|
||||
.icon_x24.client-virtualserver_edit {
|
||||
background-position: calc(-384px * 1.5) calc(-352px * 1.5);
|
||||
}
|
||||
.icon_x24.client-volume {
|
||||
background-position: calc(-416px * 1.5) calc(-352px * 1.5);
|
||||
}
|
||||
.icon_x24.client-warning {
|
||||
background-position: calc(-448px * 1.5) calc(-352px * 1.5);
|
||||
}
|
||||
.icon_x24.client-warning_external_link {
|
||||
background-position: calc(-480px * 1.5) calc(-352px * 1.5);
|
||||
}
|
||||
.icon_x24.client-warning_info {
|
||||
background-position: calc(0px * 1.5) calc(-384px * 1.5);
|
||||
}
|
||||
.icon_x24.client-warning_question {
|
||||
background-position: calc(-32px * 1.5) calc(-384px * 1.5);
|
||||
}
|
||||
.icon_x24.client-weblist {
|
||||
background-position: calc(-64px * 1.5) calc(-384px * 1.5);
|
||||
}
|
||||
.icon_x24.client-whisper {
|
||||
background-position: calc(-96px * 1.5) calc(-384px * 1.5);
|
||||
}
|
||||
.icon_x24.client-whisperlists {
|
||||
background-position: calc(-128px * 1.5) calc(-384px * 1.5);
|
||||
}
|
||||
.icon_x24.client-channel_green_subscribed2 {
|
||||
background-position: calc(-160px * 1.5) calc(-384px * 1.5);
|
||||
}
|
||||
.icon_x24.client-home {
|
||||
background-position: calc(-192px * 1.5) calc(-384px * 1.5);
|
||||
}
|
|
@ -170,9 +170,10 @@
|
|||
</div>
|
||||
|
||||
<div id="spoiler-style" style="z-index: 1000000; position: absolute; display: block; background: white; right: 5px; left: 5px; top: 34px;">
|
||||
<img src="img/style/default.png">
|
||||
<!-- <img src="img/style/default.png"> -->
|
||||
<img src="img/style/user-selected.png">
|
||||
</div>
|
||||
<button class="toggle-spoiler-style" style="height: 30px; width: 100px; z-index: 100000000; position: absolute; top: 2px;">toggle style</button>
|
||||
<button class="toggle-spoiler-style" style="height: 30px; width: 100px; z-index: 100000000; position: absolute; bottom: 2px;">toggle style</button>
|
||||
<script>
|
||||
setTimeout(() => {
|
||||
$("#spoiler-style").hide();
|
||||
|
|
|
@ -13,13 +13,13 @@
|
|||
<div class="container-control-bar">
|
||||
<div id="control_bar" class="control_bar">
|
||||
<div class="button btn_connect container-connect" title="{{tr 'Connect to a server' /}}">
|
||||
<div class="icon_x32 client-connect"></div>
|
||||
<div class="icon_x24 client-connect"></div>
|
||||
</div>
|
||||
|
||||
<div class="button-dropdown container-disconnect" title="{{tr 'Disconnect from server' /}}" style="display: none">
|
||||
<div class="buttons">
|
||||
<div class="button icon_x32 client-disconnect btn_disconnect"></div>
|
||||
<div class="button-dropdown">
|
||||
<div class="button icon_x24 client-disconnect btn_disconnect"></div>
|
||||
<div class="dropdown-arrow">
|
||||
<div class="arrow down"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -28,16 +28,13 @@
|
|||
<div class="btn_connect"><div class="icon client-connect"></div><a>{{tr "Connect to a server" /}}</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<!--
|
||||
<div class="button btn_disconnect" title="{{tr 'Disconnect from server' /}}" style="display: none">
|
||||
<div class="icon_x32 client-disconnect"></div>
|
||||
</div>
|
||||
-->
|
||||
|
||||
<div class="button-dropdown btn_bookmark" title="{{tr 'Bookmarks' /}}">
|
||||
<div class="buttons">
|
||||
<div class="button icon_x32 client-bookmark_manager btn_bookmark_list"></div>
|
||||
<div class="button-dropdown">
|
||||
<div class="button btn_bookmark_list">
|
||||
<div class="icon_x24 client-bookmark_manager"></div>
|
||||
</div>
|
||||
<div class="dropdown-arrow">
|
||||
<div class="arrow down"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -54,8 +51,10 @@
|
|||
|
||||
<div class="hide-small button-dropdown btn_away" title="{{tr 'Toggle away status' /}}">
|
||||
<div class="buttons">
|
||||
<div class="button icon_x32 client-away btn_away_toggle"></div>
|
||||
<div class="button-dropdown">
|
||||
<div class="button btn_away_toggle">
|
||||
<div class="icon_x24 client-away"></div>
|
||||
</div>
|
||||
<div class="dropdown-arrow">
|
||||
<div class="arrow down"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -69,17 +68,19 @@
|
|||
<div class="btn_away_disable_global"><div class="icon client-present"></div><a>{{tr "Go online for all servers" /}}</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hide-small button btn_mute_input">
|
||||
<div class="icon_x32 client-input_muted" title="{{tr 'Mute/unmute microphone' /}}"></div>
|
||||
<div class="hide-small button button-red btn_mute_input">
|
||||
<div class="icon_x24 client-input_muted" title="{{tr 'Mute/unmute microphone' /}}"></div>
|
||||
</div>
|
||||
<div class="hide-small button btn_mute_output">
|
||||
<div class="icon_x32 client-output_muted" title="{{tr 'Mute/unmute headphones' /}}"></div>
|
||||
<div class="hide-small button button-red btn_mute_output">
|
||||
<div class="icon_x24 client-output_muted" title="{{tr 'Mute/unmute headphones' /}}"></div>
|
||||
</div>
|
||||
|
||||
<div class="show-small button-dropdown dropdown-audio" title="{{tr 'Audio settings' /}}">
|
||||
<div class="buttons">
|
||||
<div class="button button-display icon_x32 client-music"></div>
|
||||
<div class="button-dropdown">
|
||||
<div class="button button-display">
|
||||
<div class="icon_x24 client-music"></div>
|
||||
</div>
|
||||
<div class="dropdown-arrow">
|
||||
<div class="arrow down"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -96,12 +97,14 @@
|
|||
</div>
|
||||
<div class="divider"></div>
|
||||
<div class="button button-subscribe-mode">
|
||||
<div class="icon_x32" title="{{tr 'Toggle channel subscribe mode' /}}"></div>
|
||||
<div class="icon_x24" title="{{tr 'Toggle channel subscribe mode' /}}"></div>
|
||||
</div>
|
||||
<div class="hide-small button-dropdown btn_token" title="{{tr 'Use token' /}}">
|
||||
<div class="buttons">
|
||||
<div class="button icon_x32 client-token btn_token_use"></div>
|
||||
<div class="button-dropdown">
|
||||
<div class="button btn_token_use">
|
||||
<div class="icon_x24 client-token"></div>
|
||||
</div>
|
||||
<div class="dropdown-arrow">
|
||||
<div class="arrow down"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -115,8 +118,10 @@
|
|||
|
||||
<div class="show-small button-dropdown dropdown-servertools" title="{{tr 'Server tools' /}}">
|
||||
<div class="buttons">
|
||||
<div class="button button-display icon_x32 client-virtualserver_edit"></div>
|
||||
<div class="button-dropdown">
|
||||
<div class="button button-display">
|
||||
<div class="icon_x24 client-virtualserver_edit"></div>
|
||||
</div>
|
||||
<div class="dropdown-arrow">
|
||||
<div class="arrow down"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -145,20 +150,22 @@
|
|||
</div>
|
||||
|
||||
<div class="hide-small button button-playlist-manage" title="{{tr 'Playlists' /}}">
|
||||
<div class="icon_x32 icon-playlist-manage"></div>
|
||||
<div class="icon_x24 icon-playlist-manage"></div>
|
||||
</div>
|
||||
<div class="hide-small button btn_banlist" title="{{tr 'Banlist' /}}">
|
||||
<div class="icon_x32 client-ban_list"></div>
|
||||
<div class="icon_x24 client-ban_list"></div>
|
||||
</div>
|
||||
<div class="hide-small button btn_permissions" title="{{tr 'View/edit permissions' /}}">
|
||||
<div class="icon_x32 client-permission_overview"></div>
|
||||
<div class="icon_x24 client-permission_overview"></div>
|
||||
</div>
|
||||
|
||||
<!-- the query button -->
|
||||
<div class="hide-small button-dropdown btn_query" title="{{tr 'Show/hide server queries' /}}">
|
||||
<div class="buttons">
|
||||
<div class="button icon_x32 client-server_query btn_query_toggle"></div>
|
||||
<div class="button-dropdown">
|
||||
<div class="button btn_query_toggle">
|
||||
<div class="icon_x24 client-server_query"></div>
|
||||
</div>
|
||||
<div class="dropdown-arrow">
|
||||
<div class="arrow down"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -170,7 +177,7 @@
|
|||
</div>
|
||||
<div class="divider"></div>
|
||||
<div class="button btn_open_settings" title="{{tr 'Edit global client settings' /}}">
|
||||
<div class="icon_x32 client-settings"></div>
|
||||
<div class="icon_x24 client-settings"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -189,22 +196,102 @@
|
|||
<div class="container-app-main">
|
||||
<div class="container-channel-chat">
|
||||
<!-- Channel tree -->
|
||||
<div class="container-channel-tree main_container">
|
||||
<div class="container-channel-tree">
|
||||
<div class="channel-tree" id="channelTree"></div>
|
||||
</div>
|
||||
|
||||
<div class="container-seperator horizontal" seperator-id="seperator-channel-chat"></div>
|
||||
<div class="container-seperator vertical" seperator-id="seperator-channel-chat"></div>
|
||||
<!-- Chat window -->
|
||||
<div class="main_container container-chat" id="chat"> </div>
|
||||
<div class="container-chat" id="chat"> </div>
|
||||
</div>
|
||||
<div class="container-seperator vertical" seperator-id="seperator-main-info"></div>
|
||||
<div id="select_info" class="main_container container-info"> </div> <!-- Selection info -->
|
||||
<div class="container-seperator horizontal" seperator-id="seperator-main-log"></div>
|
||||
<div id="server-log" class="container-server-log"> </div> <!-- Selection info -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="contextMenu" class="context-menu"></div>
|
||||
</script>
|
||||
|
||||
<script class="jsrender-template" id="tmpl_frame_chat" type="text/html">
|
||||
<div class="container-chat-frame">
|
||||
<div class="container-info"></div>
|
||||
<div class="container-chat"></div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script class="jsrender-template" id="tmpl_frame_chat_info" type="text/html">
|
||||
<div class="lane">
|
||||
<div class="block left">
|
||||
<div class="title">{{tr "You're talking in Channel" /}}</div>
|
||||
<div class="value value-voice-channel"></div>
|
||||
<div class="small-value value-voice-limit"></div>
|
||||
</div>
|
||||
<div class="block right">
|
||||
<div class="title">{{tr "Your ping" /}}</div>
|
||||
<div class="value value-ping">11 ms</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="lane">
|
||||
<div class="block left">
|
||||
<div class="title">{{tr "You're chatting in Channel" /}}</div>
|
||||
<div class="value value-text-channel">XXXXXY</div>
|
||||
<div class="small-value value-limit">0 / Unlimited</div>
|
||||
</div>
|
||||
<div class="block right">
|
||||
<div class="title">{{tr "Private chats" /}} <div class="container-indicator"><div class="chat-counter">2</div></div></div>
|
||||
<div class="value value-ping">12 conversations</div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script class="jsrender-template" id="tmpl_frame_chat_private" type="text/html">
|
||||
<div class="container-private-conversations">
|
||||
<div class="conversation-list">
|
||||
<div class="no-chats">
|
||||
<div>{{tr "You dont have any chats yet!" /}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-seperator vertical" seperator-id="seperator-conversation-list-messages"></div>
|
||||
<div class="conversation">
|
||||
<div class="messages"></div>
|
||||
<div class="chatbox"></div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script class="jsrender-template" id="tmpl_frame_chat_private_entry" type="text/html">
|
||||
<div class="conversation-entry">
|
||||
<div class="container-avatar">
|
||||
<div class="avatar" style="display: flex">
|
||||
<img style="width: 100%; height: 100%" src="img/style/avatar.png">
|
||||
</div>
|
||||
<div class="chat-unread"></div>
|
||||
</div>
|
||||
<div class="info">
|
||||
<a class="client-name">{{>client_name}}</a>
|
||||
<a class="last-message">Today at 12:59 AM</a>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script class="jsrender-template" id="tmpl_frame_chat_chatbox" type="text/html">
|
||||
<div class="container-chatbox">
|
||||
{{if emojy_support}}
|
||||
<div class="container-emojis">
|
||||
<div class="button-emoji">
|
||||
<div class="container-icon">
|
||||
<img src="img/smiley-smile.svg">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
<div class="container-input">
|
||||
<textarea placeholder="{{tr 'Type your message here...' /}}"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
||||
<script class="jsrender-template" id="tmpl_select_info" type="text/html">
|
||||
<div class="select_info" style="width: 100%; max-width: 100%">
|
||||
<button type="button" class="close button-modal-close" aria-label="Close">
|
||||
|
@ -216,26 +303,6 @@
|
|||
</div>
|
||||
</script>
|
||||
|
||||
<script class="jsrender-template" id="tmpl_frame_chat" type="text/html">
|
||||
<div class="container-frame-chat">
|
||||
<div class="messages">
|
||||
<div class="message_box"></div>
|
||||
</div>
|
||||
<div class="chats"></div>
|
||||
<div class="input">
|
||||
<!--<div contentEditable="true" class="input_box"></div>-->
|
||||
<div class="form-group">
|
||||
<textarea id="input-chat-input"
|
||||
type="text"
|
||||
class="form-control input-message client-chat-box-field"
|
||||
placeholder="{{tr 'enter a chat message...' /}}"
|
||||
autocomplete="off"></textarea>
|
||||
</div>
|
||||
<button class="btn btn-primary button-send">{{tr "Send" /}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script class="jsrender-template" id="tmpl_modal" type="text/html">
|
||||
<div class="modal fade" tabindex="-1" role="dialog" style="padding-right: 8%; padding-left: 8%;" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered" role="document" style="max-width: unset;">
|
||||
|
@ -1334,7 +1401,7 @@
|
|||
</div>
|
||||
<div class="property">
|
||||
<div class="key muted-sounds">
|
||||
Mute sounds when output is muted:
|
||||
{{tr "Mute sounds when output is muted:" /}}
|
||||
</div>
|
||||
<div class="value muted-sounds">
|
||||
<div class="switch">
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="300" height="300" viewBox="0 0 300 300">
|
||||
<!-- https://dennism.de/wp-content/uploads/smiley-smile.svg -->
|
||||
<path fill="#262626" d="M0,149.993333 C0,67.2933333 67.2866667,2.84217094e-14 149.993333,2.84217094e-14 C232.696667,2.84217094e-14 299.986667,67.2933333 299.986667,149.993333 C299.986667,232.703333 232.696667,300 149.993333,300 C67.2866667,300 0,232.703333 0,149.993333 Z M284.986667,149.993333 C284.986667,75.56 224.426667,15 149.993333,15 C75.5466667,15 15,75.56 15,149.993333 C15,224.44 75.5466667,285 149.993333,285 C224.426667,285 284.986667,224.44 284.986667,149.993333 Z M194.993333,121.866667 C185.666667,121.866667 178.12,114.306667 178.12,104.993333 C178.12,95.6866667 185.67,88.12 194.993333,88.12 C204.3,88.1233333 211.866667,95.6866667 211.866667,104.993333 C211.866667,114.31 204.3,121.866667 194.993333,121.866667 Z M104.993333,121.866667 C95.67,121.866667 88.12,114.306667 88.12,104.993333 C88.12,95.6866667 95.67,88.12 104.993333,88.12 C114.303333,88.1233333 121.866667,95.6866667 121.866667,104.993333 C121.866667,114.31 114.3,121.866667 104.993333,121.866667 Z M79.189449,191.903171 C77.0341864,188.693693 77.8887964,184.344712 81.098274,182.189449 C84.3077516,180.034186 88.6567329,180.888796 90.8119956,184.098274 C105.18258,205.498018 124.671916,216.000722 150.000722,216.000722 C175.329705,216.000722 194.820479,205.497839 209.193591,184.097834 C211.349096,180.88852 215.698142,180.034239 218.907457,182.189745 C222.116771,184.34525 222.971052,188.694296 220.815546,191.903611 C203.845419,217.17029 180.000273,230.000722 150.000722,230.000722 C120.000994,230.000722 96.1569752,217.170112 79.189449,191.903171 Z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
After Width: | Height: | Size: 249 KiB |
|
@ -88,6 +88,7 @@ class ConnectionHandler {
|
|||
permissions: PermissionManager;
|
||||
groups: GroupManager;
|
||||
|
||||
chat_frame: chat.Frame;
|
||||
select_info: InfoBar;
|
||||
chat: ChatBox;
|
||||
|
||||
|
@ -117,13 +118,16 @@ class ConnectionHandler {
|
|||
};
|
||||
|
||||
invoke_resized_on_activate: boolean = false;
|
||||
log: log.ServerLog;
|
||||
|
||||
constructor() {
|
||||
this.settings = new ServerSettings();
|
||||
|
||||
this.log = new log.ServerLog(this);
|
||||
this.select_info = new InfoBar(this);
|
||||
this.channelTree = new ChannelTree(this);
|
||||
this.chat = new ChatBox(this);
|
||||
this.chat_frame = new chat.Frame(this);
|
||||
this.sound = new sound.SoundManager(this);
|
||||
|
||||
this.serverConnection = connection.spawn_server_connection(this);
|
||||
|
@ -178,7 +182,13 @@ class ConnectionHandler {
|
|||
}
|
||||
}
|
||||
console.log(tr("Start connection to %s:%d"), server_address.host, server_address.port);
|
||||
this.chat.serverChat().appendMessage(tr("Initializing connection to {0}{1}"), true, server_address.host, server_address.port == 9987 ? "" : ":" + server_address.port);
|
||||
this.log.log(log.server.Type.CONNECTION_BEGIN, {
|
||||
address: {
|
||||
server_hostname: server_address.host,
|
||||
server_port: server_address.port
|
||||
},
|
||||
client_nickname: parameters.nickname
|
||||
});
|
||||
this.channelTree.initialiseHead(addr, server_address);
|
||||
|
||||
if(parameters.password && !parameters.password.hashed){
|
||||
|
@ -196,7 +206,7 @@ class ConnectionHandler {
|
|||
|
||||
if(dns.supported() && !server_address.host.match(Modals.Regex.IP_V4) && !server_address.host.match(Modals.Regex.IP_V6)) {
|
||||
const id = ++this._connect_initialize_id;
|
||||
this.chat.serverChat().appendMessage(tr("Resolving hostname..."));
|
||||
this.log.log(log.server.Type.CONNECTION_HOSTNAME_RESOLVE, {});
|
||||
try {
|
||||
const resolved = await dns.resolve_address(server_address.host, { timeout: 5000 }) || {} as any;
|
||||
if(id != this._connect_initialize_id)
|
||||
|
@ -204,7 +214,12 @@ class ConnectionHandler {
|
|||
|
||||
server_address.port = resolved.target_port || server_address.port;
|
||||
server_address.host = resolved.target_ip || server_address.host;
|
||||
this.chat.serverChat().appendMessage(tr("Hostname successfully resolved to {0}{1}"), true, server_address.host, server_address.port);
|
||||
this.log.log(log.server.Type.CONNECTION_HOSTNAME_RESOLVED, {
|
||||
address: {
|
||||
server_port: server_address.port,
|
||||
server_hostname: server_address.host
|
||||
}
|
||||
});
|
||||
} catch(error) {
|
||||
if(id != this._connect_initialize_id)
|
||||
return; /* we're old */
|
||||
|
@ -375,13 +390,15 @@ class ConnectionHandler {
|
|||
break;
|
||||
case DisconnectReason.DNS_FAILED:
|
||||
console.error(tr("Failed to resolve hostname: %o"), data);
|
||||
this.chat.serverChat().appendError(tr("Failed to resolve hostname: {0}"), data);
|
||||
this.log.log(log.server.Type.CONNECTION_HOSTNAME_RESOLVE_ERROR, {
|
||||
message: data as any
|
||||
});
|
||||
this.sound.play(Sound.CONNECTION_REFUSED);
|
||||
break;
|
||||
case DisconnectReason.CONNECT_FAILURE:
|
||||
if(this._reconnect_attempt) {
|
||||
auto_reconnect = true;
|
||||
this.chat.serverChat().appendError(tr("Connect failed"));
|
||||
this.log.log(log.server.Type.CONNECTION_FAILED, {});
|
||||
break;
|
||||
}
|
||||
console.error(tr("Could not connect to remote host! Error: %o"), data);
|
||||
|
@ -514,7 +531,7 @@ class ConnectionHandler {
|
|||
console.log(tr("Allowed to auto reconnect but cant reconnect because we dont have any information left..."));
|
||||
return;
|
||||
}
|
||||
this.chat.serverChat().appendMessage(tr("Reconnecting in 5 seconds"));
|
||||
this.log.log(log.server.Type.RECONNECT_SCHEDULED, {timeout: 50000});
|
||||
|
||||
console.log(tr("Allowed to auto reconnect. Reconnecting in 5000ms"));
|
||||
const server_address = this.serverConnection.remote_address();
|
||||
|
@ -522,7 +539,7 @@ class ConnectionHandler {
|
|||
|
||||
this._reconnect_timer = setTimeout(() => {
|
||||
this._reconnect_timer = undefined;
|
||||
this.chat.serverChat().appendMessage(tr("Reconnecting..."));
|
||||
this.log.log(log.server.Type.RECONNECT_CANCELED, {});
|
||||
log.info(LogCategory.NETWORKING, tr("Reconnecting..."));
|
||||
|
||||
this.startConnection(server_address.host + ":" + server_address.port, profile, this.reconnect_properties(profile));
|
||||
|
@ -533,7 +550,7 @@ class ConnectionHandler {
|
|||
|
||||
cancel_reconnect() {
|
||||
if(this._reconnect_timer) {
|
||||
this.chat.serverChat().appendMessage(tr("Reconnect canceled"));
|
||||
this.log.log(log.server.Type.RECONNECT_CANCELED, {});
|
||||
clearTimeout(this._reconnect_timer);
|
||||
this._reconnect_timer = undefined;
|
||||
}
|
||||
|
@ -581,7 +598,7 @@ class ConnectionHandler {
|
|||
if(Object.keys(property_update).length > 0) {
|
||||
this.serverConnection.send_command("clientupdate", property_update).catch(error => {
|
||||
log.warn(LogCategory.GENERAL, tr("Failed to update client audio hardware properties. Error: %o"), error);
|
||||
this.chat.serverChat().appendError(tr("Failed to update audio hardware properties."));
|
||||
this.log.log(log.server.Type.ERROR_CUSTOM, {message: tr("Failed to update audio hardware properties.")});
|
||||
|
||||
/* Update these properties anyways (for case the server fails to handle the command) */
|
||||
const updates = [];
|
||||
|
@ -640,7 +657,7 @@ class ConnectionHandler {
|
|||
client_output_hardware: this.client_status.sound_playback_supported
|
||||
}).catch(error => {
|
||||
log.warn(LogCategory.GENERAL, tr("Failed to sync handler state with server. Error: %o"), error);
|
||||
this.chat.serverChat().appendError(tr("Failed to sync handler state with server."));
|
||||
this.log.log(log.server.Type.ERROR_CUSTOM, {message: tr("Failed to sync handler state with server.")});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -654,7 +671,7 @@ class ConnectionHandler {
|
|||
client_away_message: typeof(this.client_status.away) === "string" ? this.client_status.away : "",
|
||||
}).catch(error => {
|
||||
log.warn(LogCategory.GENERAL, tr("Failed to update away status. Error: %o"), error);
|
||||
this.chat.serverChat().appendError(tr("Failed to update away status."));
|
||||
this.log.log(log.server.Type.ERROR_CUSTOM, {message: tr("Failed to update away status.")});
|
||||
});
|
||||
|
||||
control_bar.update_button_away();
|
||||
|
|
|
@ -58,10 +58,14 @@ namespace connection {
|
|||
if(!res.success) {
|
||||
if(res.id == 2568) { //Permission error
|
||||
res.message = tr("Insufficient client permissions. Failed on permission ") + this.connection_handler.permissions.resolveInfo(res.json["failed_permid"] as number).name;
|
||||
this.connection_handler.chat.serverChat().appendError(tr("Insufficient client permissions. Failed on permission {}"), this.connection_handler.permissions.resolveInfo(res.json["failed_permid"] as number).name);
|
||||
this.connection_handler.log.log(log.server.Type.ERROR_PERMISSION, {
|
||||
permission: this.connection_handler.permissions.resolveInfo(res.json["failed_permid"] as number)
|
||||
});
|
||||
this.connection_handler.sound.play(Sound.ERROR_INSUFFICIENT_PERMISSIONS);
|
||||
} else {
|
||||
this.connection_handler.chat.serverChat().appendError(res.extra_message.length == 0 ? res.message : res.extra_message);
|
||||
this.connection_handler.log.log(log.server.Type.ERROR_CUSTOM, {
|
||||
message: res.extra_message.length == 0 ? res.message : res.extra_message
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if(typeof(ex) === "string") {
|
||||
|
@ -144,7 +148,9 @@ namespace connection {
|
|||
|
||||
|
||||
this.connection_handler.chat.serverChat().name = this.connection.client.channelTree.server.properties["virtualserver_name"];
|
||||
this.connection_handler.chat.serverChat().appendMessage(tr("Connected as {0}"), true, this.connection.client.getClient().createChatTag(true));
|
||||
this.connection_handler.log.log(log.server.Type.CONNECTION_CONNECTED, {
|
||||
own_client: this.connection_handler.getClient().log_data()
|
||||
});
|
||||
this.connection_handler.sound.play(Sound.CONNECTION_CONNECTED);
|
||||
this.connection.client.onConnected();
|
||||
}
|
||||
|
@ -283,38 +289,32 @@ namespace connection {
|
|||
|
||||
if(this.connection_handler.client_status.queries_visible || client.properties.client_type != ClientType.CLIENT_QUERY) {
|
||||
const own_channel = this.connection.client.getClient().currentChannel();
|
||||
this.connection_handler.log.log(log.server.Type.CLIENT_VIEW_ENTER, {
|
||||
channel_from: old_channel ? old_channel.log_data() : undefined,
|
||||
channel_to: channel ? channel.log_data() : undefined,
|
||||
client: client.log_data(),
|
||||
invoker: invokeruid ? {
|
||||
client_id: invokerid,
|
||||
client_name: invokername,
|
||||
client_unique_id: invokeruid
|
||||
} : undefined,
|
||||
message:reason_msg,
|
||||
reason: parseInt(reason_id),
|
||||
own_channel: channel == own_channel
|
||||
});
|
||||
|
||||
if(reason_id == ViewReasonId.VREASON_USER_ACTION) {
|
||||
if(own_channel == channel)
|
||||
if(old_channel)
|
||||
this.connection_handler.sound.play(Sound.USER_ENTERED);
|
||||
else
|
||||
this.connection_handler.sound.play(Sound.USER_ENTERED_CONNECT);
|
||||
if(old_channel) {
|
||||
this.connection_handler.chat.serverChat().appendMessage(tr("{0} appeared from {1} to {2}"), true, client.createChatTag(true), old_channel.generate_tag(true), channel.generate_tag(true));
|
||||
} else {
|
||||
this.connection_handler.chat.serverChat().appendMessage(tr("{0} connected to channel {1}"), true, client.createChatTag(true), channel.generate_tag(true));
|
||||
}
|
||||
} else if(reason_id == ViewReasonId.VREASON_MOVED) {
|
||||
if(own_channel == channel)
|
||||
this.connection_handler.sound.play(Sound.USER_ENTERED_MOVED);
|
||||
|
||||
this.connection_handler.chat.serverChat().appendMessage(tr("{0} appeared from {1} to {2}, moved by {3}"), true,
|
||||
client.createChatTag(true),
|
||||
old_channel ? old_channel.generate_tag(true) : undefined,
|
||||
channel.generate_tag(true),
|
||||
ClientEntry.chatTag(invokerid, invokername, invokeruid),
|
||||
);
|
||||
} else if(reason_id == ViewReasonId.VREASON_CHANNEL_KICK) {
|
||||
if(own_channel == channel)
|
||||
this.connection_handler.sound.play(Sound.USER_ENTERED_KICKED);
|
||||
|
||||
this.connection_handler.chat.serverChat().appendMessage(tr("{0} appeared from {1} to {2}, kicked by {3}{4}"), true,
|
||||
client.createChatTag(true),
|
||||
old_channel ? old_channel.generate_tag(true) : undefined,
|
||||
channel.generate_tag(true),
|
||||
ClientEntry.chatTag(invokerid, invokername, invokeruid),
|
||||
reason_msg.length > 0 ? " (" + entry["msg"] + ")" : ""
|
||||
);
|
||||
} else {
|
||||
console.warn(tr("Unknown reasonid for %o"), reason_id);
|
||||
}
|
||||
|
@ -363,6 +363,7 @@ namespace connection {
|
|||
|
||||
if(client instanceof LocalClientEntry) {
|
||||
this.connection_handler.update_voice_status();
|
||||
this.connection_handler.chat_frame.info_frame().update_channel_talk();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -389,6 +390,7 @@ namespace connection {
|
|||
this.connection.client.handleDisconnect(DisconnectReason.SERVER_CLOSED, entry);
|
||||
} else
|
||||
this.connection.client.handleDisconnect(DisconnectReason.UNKNOWN, entry);
|
||||
this.connection_handler.chat_frame.info_frame().update_channel_talk();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -398,57 +400,36 @@ namespace connection {
|
|||
let channel_from = tree.findChannel(entry["cfid"]);
|
||||
let channel_to = tree.findChannel(entry["ctid"]);
|
||||
|
||||
this.connection_handler.log.log(log.server.Type.CLIENT_VIEW_LEAVE, {
|
||||
channel_from: channel_from ? channel_from.log_data() : undefined,
|
||||
channel_to: channel_to ? channel_to.log_data() : undefined,
|
||||
client: client.log_data(),
|
||||
invoker: entry["invokeruid"] ? {
|
||||
client_id: entry["invokerid"],
|
||||
client_name: entry["invokername"],
|
||||
client_unique_id: entry["invokeruid"]
|
||||
} : undefined,
|
||||
message: entry["reasonmsg"],
|
||||
reason: parseInt(entry["reasonid"]),
|
||||
ban_time: parseInt(entry["bantime"]),
|
||||
own_channel: channel_from == own_channel
|
||||
});
|
||||
if(reason_id == ViewReasonId.VREASON_USER_ACTION) {
|
||||
this.connection_handler.chat.serverChat().appendMessage(tr("{0} disappeared from {1} to {2}"), true, client.createChatTag(true), channel_from.generate_tag(true), channel_to.generate_tag(true));
|
||||
|
||||
if(channel_from == own_channel)
|
||||
this.connection_handler.sound.play(Sound.USER_LEFT);
|
||||
} else if(reason_id == ViewReasonId.VREASON_SERVER_LEFT) {
|
||||
this.connection_handler.chat.serverChat().appendMessage(tr("{0} left the server{1}"), true,
|
||||
client.createChatTag(true),
|
||||
entry["reasonmsg"] ? " (" + entry["reasonmsg"] + ")" : ""
|
||||
);
|
||||
|
||||
if(channel_from == own_channel)
|
||||
this.connection_handler.sound.play(Sound.USER_LEFT_DISCONNECT);
|
||||
} else if(json["reasonid"] == ViewReasonId.VREASON_SERVER_KICK) {
|
||||
this.connection_handler.chat.serverChat().appendError(tr("{0} was kicked from the server by {1}.{2}"),
|
||||
client.createChatTag(true),
|
||||
ClientEntry.chatTag(entry["invokerid"], entry["invokername"], entry["invokeruid"]),
|
||||
entry["reasonmsg"] ? " (" + entry["reasonmsg"] + ")" : ""
|
||||
);
|
||||
if(channel_from == own_channel)
|
||||
this.connection_handler.sound.play(Sound.USER_LEFT_KICKED_SERVER);
|
||||
} else if(reason_id == ViewReasonId.VREASON_CHANNEL_KICK) {
|
||||
this.connection_handler.chat.serverChat().appendError(tr("{0} was kicked from your channel by {1}.{2}"),
|
||||
client.createChatTag(true),
|
||||
ClientEntry.chatTag(entry["invokerid"], entry["invokername"], entry["invokeruid"]),
|
||||
entry["reasonmsg"] ? " (" + entry["reasonmsg"] + ")" : ""
|
||||
);
|
||||
|
||||
if(channel_from == own_channel)
|
||||
this.connection_handler.sound.play(Sound.USER_LEFT_KICKED_CHANNEL);
|
||||
} else if(reason_id == ViewReasonId.VREASON_BAN) {
|
||||
//"Mulus" was banned for 1 second from the server by "WolverinDEV" (Sry brauchte kurz ein opfer :P <3 (Nohomo))
|
||||
let duration = "permanently";
|
||||
if(entry["bantime"])
|
||||
duration = "for " + formatDate(Number.parseInt(entry["bantime"]));
|
||||
|
||||
this.connection_handler.chat.serverChat().appendError(tr("{0} was banned {1} by {2}.{3}"),
|
||||
client.createChatTag(true),
|
||||
duration,
|
||||
ClientEntry.chatTag(entry["invokerid"], entry["invokername"], entry["invokeruid"]),
|
||||
entry["reasonmsg"] ? " (" + entry["reasonmsg"] + ")" : ""
|
||||
);
|
||||
|
||||
if(channel_from == own_channel)
|
||||
this.connection_handler.sound.play(Sound.USER_LEFT_BANNED);
|
||||
} else if(reason_id == ViewReasonId.VREASON_TIMEOUT) {
|
||||
this.connection_handler.chat.serverChat().appendError(tr("{0} timed out ({1})"),
|
||||
client.createChatTag(true),
|
||||
entry["reasonmsg"] ? " (" + entry["reasonmsg"] + ")" : ""
|
||||
);
|
||||
|
||||
if(channel_from == own_channel)
|
||||
this.connection_handler.sound.play(Sound.USER_LEFT_TIMEOUT);
|
||||
} else {
|
||||
|
@ -507,14 +488,40 @@ namespace connection {
|
|||
if(entry !== client && entry.get_audio_handle())
|
||||
entry.get_audio_handle().abort_replay();
|
||||
|
||||
if(self)
|
||||
this.connection_handler.chat_frame.info_frame().update_channel_talk();
|
||||
|
||||
const own_channel = this.connection.client.getClient().currentChannel();
|
||||
this.connection_handler.log.log(log.server.Type.CLIENT_VIEW_MOVE, {
|
||||
channel_from: channel_from ? {
|
||||
channel_id: channel_from.channelId,
|
||||
channel_name: channel_from.channelName()
|
||||
} : undefined,
|
||||
channel_from_own: channel_from == own_channel,
|
||||
|
||||
channel_to: channel_to ? {
|
||||
channel_id: channel_to.channelId,
|
||||
channel_name: channel_to.channelName()
|
||||
} : undefined,
|
||||
channel_to_own: channel_to == own_channel,
|
||||
|
||||
client: {
|
||||
client_id: client.clientId(),
|
||||
client_name: client.clientNickName(),
|
||||
client_unique_id: client.properties.client_unique_identifier
|
||||
},
|
||||
client_own: self,
|
||||
|
||||
invoker: json["invokeruid"] ? {
|
||||
client_id: parseInt(json["invokerid"]),
|
||||
client_name: json["invokername"],
|
||||
client_unique_id: json["invokeruid"]
|
||||
} : undefined,
|
||||
|
||||
message: json["reasonmsg"],
|
||||
reason: parseInt(json["reasonid"]),
|
||||
});
|
||||
if(json["reasonid"] == ViewReasonId.VREASON_MOVED) {
|
||||
this.connection_handler.chat.serverChat().appendMessage(self ? tr("You was moved by {3} from channel {1} to {2}") : tr("{0} was moved from channel {1} to {2} by {3}"), true,
|
||||
client.createChatTag(true),
|
||||
channel_from ? channel_from.generate_tag(true) : undefined,
|
||||
channel_to.generate_tag(true),
|
||||
ClientEntry.chatTag(json["invokerid"], json["invokername"], json["invokeruid"])
|
||||
);
|
||||
if(self)
|
||||
this.connection_handler.sound.play(Sound.USER_MOVED_SELF);
|
||||
else if(own_channel == channel_to)
|
||||
|
@ -522,24 +529,12 @@ namespace connection {
|
|||
else if(own_channel == channel_from)
|
||||
this.connection_handler.sound.play(Sound.USER_LEFT_MOVED);
|
||||
} else if(json["reasonid"] == ViewReasonId.VREASON_USER_ACTION) {
|
||||
this.connection_handler.chat.serverChat().appendMessage(self ? tr("You switched from channel {1} to {2}") : tr("{0} switched from channel {1} to {2}"), true,
|
||||
client.createChatTag(true),
|
||||
channel_from ? channel_from.generate_tag(true) : undefined,
|
||||
channel_to.generate_tag(true)
|
||||
);
|
||||
if(self) {} //If we do an action we wait for the error response
|
||||
else if(own_channel == channel_to)
|
||||
this.connection_handler.sound.play(Sound.USER_ENTERED);
|
||||
else if(own_channel == channel_from)
|
||||
this.connection_handler.sound.play(Sound.USER_LEFT);
|
||||
} else if(json["reasonid"] == ViewReasonId.VREASON_CHANNEL_KICK) {
|
||||
this.connection_handler.chat.serverChat().appendMessage(self ? tr("You got kicked out of the channel {1} to channel {2} by {3}{4}") : tr("{0} got kicked from channel {1} to {2} by {3}{4}"), true,
|
||||
client.createChatTag(true),
|
||||
channel_from ? channel_from.generate_tag(true) : undefined,
|
||||
channel_to.generate_tag(true),
|
||||
ClientEntry.chatTag(json["invokerid"], json["invokername"], json["invokeruid"]),
|
||||
json["reasonmsg"] ? " (" + json["reasonmsg"] + ")" : ""
|
||||
);
|
||||
if(self) {
|
||||
this.connection_handler.sound.play(Sound.CHANNEL_KICKED);
|
||||
} else if(own_channel == channel_to)
|
||||
|
@ -632,7 +627,14 @@ namespace connection {
|
|||
this.connection_handler.sound.play(Sound.MESSAGE_RECEIVED, {default_volume: .5});
|
||||
this.connection_handler.chat.channelChat().appendMessage("{0}: {1}", true, ClientEntry.chatTag(json["invokerid"], json["invokername"], json["invokeruid"], true), MessageHelper.bbcode_chat(json["msg"]))
|
||||
} else if(mode == 3) {
|
||||
this.connection_handler.chat.serverChat().appendMessage("{0}: {1}", true, ClientEntry.chatTag(json["invokerid"], json["invokername"], json["invokeruid"], true), MessageHelper.bbcode_chat(json["msg"]));
|
||||
this.connection_handler.log.log(log.server.Type.GLOBAL_MESSAGE, {
|
||||
message: json["msg"],
|
||||
sender: {
|
||||
client_unique_id: json["invokeruid"],
|
||||
client_name: json["invokername"],
|
||||
client_id: parseInt(json["invokerid"])
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -587,7 +587,9 @@ const loader_javascript = {
|
|||
"js/ui/frames/SelectedItemInfo.js",
|
||||
"js/ui/frames/ControlBar.js",
|
||||
"js/ui/frames/chat.js",
|
||||
"js/ui/frames/chat_frame.js",
|
||||
"js/ui/frames/connection_handlers.js",
|
||||
"js/ui/frames/server_log.js",
|
||||
|
||||
//Load permissions
|
||||
"js/permission/PermissionManager.js",
|
||||
|
@ -697,6 +699,7 @@ const loader_style = {
|
|||
load_style_debug: async () => {
|
||||
await loader.load_styles([
|
||||
"css/static/main.css",
|
||||
"css/static/main-layout.css",
|
||||
"css/static/helptag.css",
|
||||
"css/static/scroll.css",
|
||||
"css/static/channel-tree.css",
|
||||
|
@ -724,7 +727,9 @@ const loader_style = {
|
|||
"css/static/frame/SelectInfo.css",
|
||||
"css/static/control_bar.css",
|
||||
"css/static/context_menu.css",
|
||||
"css/static/frame-chat.css",
|
||||
"css/static/connection_handlers.css",
|
||||
"css/static/server-log.css",
|
||||
"css/static/htmltags.css"
|
||||
]);
|
||||
},
|
||||
|
|
|
@ -366,6 +366,16 @@ function main() {
|
|||
};
|
||||
|
||||
server_connections.set_active_connection_handler(server_connections.server_connection_handlers()[0]);
|
||||
const convs = server_connections.active_connection_handler().chat_frame.private_conversations();
|
||||
let conv = convs.create_conversation("xxxx0", "WolverinDEV");
|
||||
conv = convs.create_conversation("xxxx1", "Darkatzu");
|
||||
conv = convs.create_conversation("xxxx2", "ZameXxX");
|
||||
conv.set_unread_flag(true);
|
||||
|
||||
conv = convs.create_conversation("xxxx3", "Vagur");
|
||||
|
||||
//for(let i = 0; i < 100; i++)
|
||||
// convs.create_conversation('xx' + i, "WolverinDEV #" + i);
|
||||
|
||||
if(settings.static(Settings.KEY_FLAG_CONNECT_DEFAULT, false) && settings.static(Settings.KEY_CONNECT_ADDRESS, "")) {
|
||||
const profile_uuid = settings.static(Settings.KEY_CONNECT_PROFILE, (profiles.default_profile() || {id: 'default'}).id);
|
||||
|
|
|
@ -685,6 +685,7 @@ class ChannelEntry {
|
|||
log.table("Clannel update properties", entries);
|
||||
}
|
||||
|
||||
let info_update = false;
|
||||
for(let variable of variables) {
|
||||
let key = variable.key;
|
||||
let value = variable.value;
|
||||
|
@ -692,6 +693,7 @@ class ChannelEntry {
|
|||
|
||||
if(key == "channel_name") {
|
||||
this.__updateChannelName();
|
||||
info_update = true;
|
||||
} else if(key == "channel_order") {
|
||||
let order = this.channelTree.findChannel(this.properties.channel_order);
|
||||
this.channelTree.moveChannel(this, order, this.parent);
|
||||
|
@ -707,6 +709,7 @@ class ChannelEntry {
|
|||
tag.children().detach();
|
||||
this.channelTree.client.fileManager.icons.generateTag(this.properties.channel_icon_id).appendTo(tag);
|
||||
}
|
||||
info_update = true;
|
||||
} else if(key == "channel_codec") {
|
||||
(this.properties.channel_codec == 5 || this.properties.channel_codec == 3 ? $.fn.show : $.fn.hide).apply(this.channelTag().find(".icons .icon_music"));
|
||||
this.channelTag().find(".icons .icon_no_sound").toggle(!(
|
||||
|
@ -727,10 +730,19 @@ class ChannelEntry {
|
|||
this._cached_channel_description_promise_resolve = undefined;
|
||||
this._cached_channel_description_promise_reject = undefined;
|
||||
}
|
||||
if(key == "channel_maxclients" || key == "channel_maxfamilyclients" || key == "channel_flag_private" || key == "channel_flag_password")
|
||||
if(key == "channel_maxclients" || key == "channel_maxfamilyclients" || key == "channel_flag_private" || key == "channel_flag_password") {
|
||||
this.updateChannelTypeIcon();
|
||||
info_update = true;
|
||||
}
|
||||
}
|
||||
group.end();
|
||||
|
||||
if(info_update) {
|
||||
const _client = this.channelTree.client.getClient();
|
||||
if(_client.currentChannel() === this)
|
||||
this.channelTree.client.chat_frame.info_frame().update_channel_talk();
|
||||
//TODO chat channel!
|
||||
}
|
||||
}
|
||||
|
||||
updateChannelTypeIcon() {
|
||||
|
@ -862,4 +874,11 @@ class ChannelEntry {
|
|||
this._subscribe_mode = mode;
|
||||
this.channelTree.client.settings.changeServer(Settings.FN_SERVER_CHANNEL_SUBSCRIBE_MODE(this), mode);
|
||||
}
|
||||
|
||||
log_data() : log.server.base.Channel {
|
||||
return {
|
||||
channel_name: this.channelName(),
|
||||
channel_id: this.channelId
|
||||
}
|
||||
}
|
||||
}
|
|
@ -817,7 +817,15 @@ class ClientEntry {
|
|||
if(!this._channel) return;
|
||||
const index = this._channel.calculate_family_index();
|
||||
|
||||
this.tag.css('padding-left', (index + 2) * 16 + "px");
|
||||
this.tag.css('padding-left', (5 + (index + 2) * 16) + "px");
|
||||
}
|
||||
|
||||
log_data() : log.server.base.Client {
|
||||
return {
|
||||
client_unique_id: this.properties.client_unique_identifier,
|
||||
client_name: this.clientNickName(),
|
||||
client_id: this._clientId
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -912,9 +920,14 @@ class LocalClientEntry extends ClientEntry {
|
|||
elm.text(_self.clientNickName());
|
||||
_self.handle.serverConnection.command_helper.updateClient("client_nickname", text).then((e) => {
|
||||
settings.changeGlobal(Settings.KEY_CONNECT_USERNAME, text);
|
||||
this.channelTree.client.chat.serverChat().appendMessage(tr("Nickname successfully changed"));
|
||||
this.channelTree.client.log.log(log.server.Type.CLIENT_NICKNAME_CHANGED, {
|
||||
client: this.log_data(),
|
||||
own_action: true
|
||||
});
|
||||
}).catch((e: CommandResult) => {
|
||||
this.channelTree.client.chat.serverChat().appendError(tr("Could not change nickname ({})"), e.extra_message);
|
||||
this.channelTree.client.log.log(log.server.Type.CLIENT_NICKNAME_CHANGE_FAILED, {
|
||||
reason: e.extra_message
|
||||
});
|
||||
_self.openRename();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -80,7 +80,7 @@ class ControlBar {
|
|||
|
||||
initialise() {
|
||||
let dropdownify = (tag: JQuery) => {
|
||||
tag.find(".button-dropdown").on('click', () => {
|
||||
tag.find(".dropdown-arrow").on('click', () => {
|
||||
tag.addClass("displayed");
|
||||
}).hover(() => {
|
||||
tag.addClass("displayed");
|
||||
|
@ -553,11 +553,11 @@ class ControlBar {
|
|||
callback: () => bookmark_connect(true)
|
||||
}, contextmenu.Entry.CLOSE(() => {
|
||||
setTimeout(() => {
|
||||
this.htmlTag.find(".btn_bookmark.button-dropdown").removeClass("force-show")
|
||||
this.htmlTag.find(".btn_bookmark.dropdown-arrow").removeClass("force-show")
|
||||
}, 250);
|
||||
}));
|
||||
|
||||
this.htmlTag.find(".btn_bookmark.button-dropdown").addClass("force-show");
|
||||
this.htmlTag.find(".btn_bookmark.dropdown-arrow").addClass("force-show");
|
||||
})
|
||||
)
|
||||
} else {
|
||||
|
|
|
@ -408,7 +408,7 @@ class ChatBox {
|
|||
|
||||
this.createChat("chat_server", ChatType.SERVER).onMessageSend = (text: string) => {
|
||||
if(!this.connection_handler.serverConnection) {
|
||||
this.serverChat().appendError(tr("Could not send chant message (Not connected)"));
|
||||
this.serverChat().appendError(tr("Could not send chat message (Not connected)"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,292 @@
|
|||
/* the bar on the right with the chats (Channel & Client) */
|
||||
namespace chat {
|
||||
export class InfoFrame {
|
||||
private readonly handle: Frame;
|
||||
private _html_tag: JQuery;
|
||||
|
||||
constructor(handle: Frame) {
|
||||
this.handle = handle;
|
||||
this._build_html_tag();
|
||||
this.update_channel_talk();
|
||||
}
|
||||
|
||||
html_tag() : JQuery { return this._html_tag; }
|
||||
|
||||
private _build_html_tag() {
|
||||
this._html_tag = $("#tmpl_frame_chat_info").renderTag();
|
||||
}
|
||||
|
||||
update_channel_talk() {
|
||||
const client = this.handle.handle.connected ? this.handle.handle.getClient() : undefined;
|
||||
const channel = client ? client.currentChannel() : undefined;
|
||||
|
||||
const html_tag = this._html_tag.find(".value-voice-channel");
|
||||
const html_limit_tag = this._html_tag.find(".value-voice-limit");
|
||||
html_limit_tag.text("");
|
||||
html_tag.children().detach();
|
||||
|
||||
if(channel) {
|
||||
if(channel.properties.channel_icon_id != 0)
|
||||
client.handle.fileManager.icons.generateTag(channel.properties.channel_icon_id).appendTo(html_tag);
|
||||
$.spawn("div").text(channel.channelName()).appendTo(html_tag);
|
||||
|
||||
//channel.properties.channel_maxclients
|
||||
let channel_limit = tr("Unlimited");
|
||||
if(!channel.properties.channel_flag_maxclients_unlimited)
|
||||
channel_limit = "" + channel.properties.channel_maxclients;
|
||||
else if(!channel.properties.channel_flag_maxfamilyclients_unlimited) {
|
||||
if(channel.properties.channel_maxfamilyclients >= 0)
|
||||
channel_limit = "" + channel.properties.channel_maxfamilyclients;
|
||||
}
|
||||
html_limit_tag.text(channel.clients(false).length + " / " + channel_limit);
|
||||
} else {
|
||||
$.spawn("div").text("Not connected").appendTo(html_tag);
|
||||
}
|
||||
}
|
||||
|
||||
update_chat_counter() {
|
||||
const count = this.handle.private_conversations().conversations().filter(e => e.is_unread()).length;
|
||||
const count_container = this._html_tag.find(".container-indicator");
|
||||
const count_tag = count_container.find(".chat-counter");
|
||||
count_container.toggle(count > 0);
|
||||
count_tag.text(count);
|
||||
}
|
||||
}
|
||||
|
||||
export enum ConversationState {
|
||||
ACTIVE,
|
||||
CLOSED,
|
||||
OFFLINE
|
||||
}
|
||||
|
||||
class ChatBox {
|
||||
private _html_tag: JQuery;
|
||||
private _html_input: JQuery<HTMLTextAreaElement>;
|
||||
private __callback_text_changed;
|
||||
private __callback_key_down;
|
||||
|
||||
constructor() {
|
||||
this.__callback_key_down = this._callback_key_down.bind(this);
|
||||
this.__callback_text_changed = this._callback_text_changed.bind(this);
|
||||
|
||||
this._build_html_tag();
|
||||
this._initialize_listener();
|
||||
}
|
||||
|
||||
html_tag() : JQuery {
|
||||
return this._html_tag;
|
||||
}
|
||||
|
||||
private _initialize_listener() {
|
||||
this._html_input.on("cut paste drop keydown", (event) => setTimeout(() => this.__callback_text_changed(event), 0));
|
||||
this._html_input.on("change", this.__callback_text_changed);
|
||||
this._html_input.on("keydown", this.__callback_key_down);
|
||||
}
|
||||
|
||||
private _build_html_tag() {
|
||||
this._html_tag = $("#tmpl_frame_chat_chatbox").renderTag({
|
||||
emojy_support: true
|
||||
});
|
||||
this._html_input = this._html_tag.find("textarea") as any;
|
||||
}
|
||||
|
||||
private _callback_text_changed(event) {
|
||||
if(event && event.isDefaultPrevented())
|
||||
return;
|
||||
|
||||
/* Auto resize */
|
||||
const text = this._html_input[0];
|
||||
text.style.height = "1em";
|
||||
text.style.height = text.scrollHeight + 'px';
|
||||
}
|
||||
|
||||
private _callback_key_down(event: KeyboardEvent) {
|
||||
if(event.shiftKey)
|
||||
return;
|
||||
|
||||
if(event.key.toLowerCase() === "enter") {
|
||||
event.preventDefault();
|
||||
|
||||
//TODO Notify text!
|
||||
console.log("Sending text: %s", this._html_input.val());
|
||||
this._html_input.val(undefined);
|
||||
setTimeout(() => this.__callback_text_changed());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class PrivateConveration {
|
||||
readonly handle: PrivateConverations;
|
||||
private _flag_unread: boolean;
|
||||
private _html_entry_tag: JQuery;
|
||||
private _html_messages_tag: JQuery; /* TODO: Consider to create them every time on the fly? */
|
||||
private _message_history: {
|
||||
message: string;
|
||||
sender: "self" | "partner";
|
||||
}[] = [];
|
||||
|
||||
client_unique_id: string;
|
||||
client_id: string;
|
||||
client_name: string;
|
||||
|
||||
state: ConversationState = ConversationState.ACTIVE;
|
||||
|
||||
|
||||
constructor(handle: PrivateConverations, client_unique_id: string, client_name: string) {
|
||||
this.handle = handle;
|
||||
this.client_name = client_name;
|
||||
this.client_unique_id = client_unique_id;
|
||||
|
||||
this._flag_unread = false;
|
||||
this._build_entry_tag();
|
||||
this.set_unread_flag(false);
|
||||
}
|
||||
|
||||
entry_tag() : JQuery {
|
||||
return this._html_entry_tag;
|
||||
}
|
||||
|
||||
append_message(message: string, sender: "self" | "partner") {
|
||||
this._message_history.push({
|
||||
message: message,
|
||||
sender: sender
|
||||
});
|
||||
}
|
||||
|
||||
private _build_entry_tag() {
|
||||
this._html_entry_tag = $("#tmpl_frame_chat_private_entry").renderTag({
|
||||
client_name: this.client_name
|
||||
});
|
||||
this._html_entry_tag.on('click', event => this.handle.set_selected_conversation(this));
|
||||
}
|
||||
|
||||
set_client_name(name: string) {
|
||||
if(this.client_name === name)
|
||||
return;
|
||||
this.client_name = name;
|
||||
this._html_entry_tag.find(".client-name").text(name);
|
||||
}
|
||||
|
||||
set_unread_flag(flag: boolean, update_chat_counter?: boolean) {
|
||||
if(flag === this._flag_unread)
|
||||
return;
|
||||
this._flag_unread = flag;
|
||||
this._html_entry_tag.toggleClass("unread", flag);
|
||||
if(typeof(update_chat_counter) !== "boolean" || update_chat_counter)
|
||||
this.handle.handle.info_frame().update_chat_counter();
|
||||
}
|
||||
|
||||
is_unread() : boolean { return this._flag_unread; }
|
||||
}
|
||||
|
||||
export class PrivateConverations {
|
||||
readonly handle: Frame;
|
||||
private _chat_box: ChatBox;
|
||||
private _html_tag: JQuery;
|
||||
|
||||
private _container_conversation: JQuery;
|
||||
private _container_conversation_messages: JQuery;
|
||||
private _container_conversation_list: JQuery;
|
||||
|
||||
private _html_no_chats: JQuery;
|
||||
private _conversations: PrivateConveration[] = [];
|
||||
|
||||
private _current_conversation: PrivateConveration = undefined;
|
||||
|
||||
constructor(handle: Frame) {
|
||||
this.handle = handle;
|
||||
this._chat_box = new ChatBox();
|
||||
this._build_html_tag();
|
||||
}
|
||||
|
||||
html_tag() : JQuery { return this._html_tag; }
|
||||
|
||||
conversations() : PrivateConveration[] { return this._conversations; }
|
||||
create_conversation(client_uid: string, client_name: string) : PrivateConveration {
|
||||
const conv = new PrivateConveration(this, client_uid, client_name);
|
||||
this._conversations.push(conv);
|
||||
this._html_no_chats.hide();
|
||||
|
||||
this._container_conversation_list.append(conv.entry_tag());
|
||||
return conv;
|
||||
}
|
||||
delete_conversation(conv: PrivateConveration) {
|
||||
if(!this._conversations.remove(conv))
|
||||
return;
|
||||
//TODO: May animate?
|
||||
conv.entry_tag().detach();
|
||||
this._html_no_chats.toggle(this._conversations.length == 0);
|
||||
if(conv === this._current_conversation)
|
||||
this.set_selected_conversation(undefined);
|
||||
}
|
||||
clear_conversations() {
|
||||
while(this._conversations.length > 0)
|
||||
this.delete_conversation(this._conversations[0]);
|
||||
this.handle.info_frame().update_chat_counter();
|
||||
}
|
||||
|
||||
set_selected_conversation(conv: PrivateConveration | undefined) {
|
||||
if(conv === this._current_conversation)
|
||||
return;
|
||||
|
||||
this._container_conversation_list.find(".selected").removeClass("selected");
|
||||
this._container_conversation_messages.children().detach();
|
||||
this._current_conversation = conv;
|
||||
if(!this._current_conversation)
|
||||
return;
|
||||
|
||||
this._current_conversation.entry_tag().addClass("selected");
|
||||
}
|
||||
|
||||
private _build_html_tag() {
|
||||
this._html_tag = $("#tmpl_frame_chat_private").renderTag().dividerfy();
|
||||
this._container_conversation = this._html_tag.find(".conversation");
|
||||
this._container_conversation_messages = this._container_conversation.find(".messages");
|
||||
this._container_conversation.find(".chatbox").append(this._chat_box.html_tag());
|
||||
|
||||
this._container_conversation_list = this._html_tag.find(".conversation-list");
|
||||
this._html_no_chats = this._container_conversation_list.find(".no-chats");
|
||||
}
|
||||
}
|
||||
|
||||
export class Frame {
|
||||
readonly handle: ConnectionHandler;
|
||||
private _info_frame: InfoFrame;
|
||||
private _html_tag: JQuery;
|
||||
private _container_info: JQuery;
|
||||
private _container_chat: JQuery;
|
||||
|
||||
private _conversations: PrivateConverations;
|
||||
|
||||
constructor(handle: ConnectionHandler) {
|
||||
this.handle = handle;
|
||||
|
||||
this._info_frame = new InfoFrame(this);
|
||||
this._conversations = new PrivateConverations(this);
|
||||
|
||||
this._build_html_tag();
|
||||
this.show_private_conversations();
|
||||
}
|
||||
|
||||
html_tag() : JQuery { return this._html_tag; }
|
||||
info_frame() : InfoFrame { return this._info_frame; }
|
||||
|
||||
private _build_html_tag() {
|
||||
this._html_tag = $("#tmpl_frame_chat").renderTag();
|
||||
this._container_info =this._html_tag.find(".container-info");
|
||||
this._container_chat =this._html_tag.find(".container-chat");
|
||||
|
||||
this._info_frame.html_tag().appendTo(this._container_info);
|
||||
}
|
||||
|
||||
|
||||
private_conversations() : PrivateConverations {
|
||||
return this._conversations;
|
||||
}
|
||||
|
||||
show_private_conversations() {
|
||||
this._container_chat.children().detach();
|
||||
this._container_chat.append(this._conversations.html_tag());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,9 +5,10 @@ class ServerConnectionManager {
|
|||
private connection_handlers: ConnectionHandler[] = [];
|
||||
private active_handler: ConnectionHandler | undefined;
|
||||
|
||||
private _container_log_server: JQuery;
|
||||
private _container_channel_tree: JQuery;
|
||||
private _container_select_info: JQuery;
|
||||
private _container_chat_box: JQuery;
|
||||
private _container_chat: JQuery;
|
||||
|
||||
private _tag: JQuery;
|
||||
private _tag_connection_entries: JQuery;
|
||||
|
@ -29,9 +30,10 @@ class ServerConnectionManager {
|
|||
this._tag_button_scoll_left.on('click', this._button_scroll_left_clicked.bind(this));
|
||||
this._tag_button_scoll_right.on('click', this._button_scroll_right_clicked.bind(this));
|
||||
|
||||
this._container_log_server = $("#server-log");
|
||||
this._container_channel_tree = $("#channelTree");
|
||||
this._container_select_info = $("#select_info");
|
||||
this._container_chat_box = $("#chat");
|
||||
this._container_chat = $("#chat");
|
||||
|
||||
this.set_active_connection_handler(undefined);
|
||||
}
|
||||
|
@ -43,8 +45,8 @@ class ServerConnectionManager {
|
|||
control_bar.initialize_connection_handler_state(handler);
|
||||
|
||||
handler.tag_connection_handler.appendTo(this._tag_connection_entries);
|
||||
this._tag.toggleClass("shown", this.connection_handlers.length > 1);
|
||||
this._update_scroll();
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
||||
|
@ -52,6 +54,7 @@ class ServerConnectionManager {
|
|||
this.connection_handlers.remove(handler);
|
||||
handler.tag_connection_handler.detach();
|
||||
this._update_scroll();
|
||||
this._tag.toggleClass("shown", this.connection_handlers.length > 1);
|
||||
|
||||
if(handler.serverConnection) {
|
||||
const connected = handler.connected;
|
||||
|
@ -72,7 +75,8 @@ class ServerConnectionManager {
|
|||
this._tag_connection_entries.find(".active").removeClass("active");
|
||||
this._container_channel_tree.children().detach();
|
||||
this._container_select_info.children().detach();
|
||||
this._container_chat_box.children().detach();
|
||||
this._container_chat.children().detach();
|
||||
this._container_log_server.children().detach();
|
||||
|
||||
control_bar.set_connection_handler(handler);
|
||||
if(handler) {
|
||||
|
@ -80,7 +84,8 @@ class ServerConnectionManager {
|
|||
|
||||
this._container_channel_tree.append(handler.channelTree.tag_tree());
|
||||
this._container_select_info.append(handler.select_info.get_tag());
|
||||
this._container_chat_box.append(handler.chat.htmlTag);
|
||||
this._container_chat.append(handler.chat_frame.html_tag());
|
||||
this._container_log_server.append(handler.log.html_tag());
|
||||
|
||||
if(handler.invoke_resized_on_activate)
|
||||
handler.resize_elements();
|
||||
|
|
|
@ -0,0 +1,448 @@
|
|||
namespace log {
|
||||
export namespace server {
|
||||
export enum Type {
|
||||
CONNECTION_BEGIN = "connection_begin",
|
||||
CONNECTION_HOSTNAME_RESOLVE = "connection_hostname_resolve",
|
||||
CONNECTION_HOSTNAME_RESOLVE_ERROR = "connection_hostname_resolve_error",
|
||||
CONNECTION_HOSTNAME_RESOLVED = "connection_hostname_resolved",
|
||||
CONNECTION_LOGIN = "connection_login",
|
||||
CONNECTION_CONNECTED = "connection_connected",
|
||||
CONNECTION_FAILED = "connection_failed",
|
||||
|
||||
CONNECTION_VOICE_SETUP_FAILED = "connection_voice_setup_failed",
|
||||
|
||||
GLOBAL_MESSAGE = "global_message",
|
||||
|
||||
CLIENT_VIEW_ENTER = "client_view_enter",
|
||||
CLIENT_VIEW_LEAVE = "client_view_leave",
|
||||
CLIENT_VIEW_MOVE = "client_view_move",
|
||||
|
||||
CLIENT_NICKNAME_CHANGED = "client_nickname_changed",
|
||||
CLIENT_NICKNAME_CHANGE_FAILED = "client_nickname_change_failed",
|
||||
|
||||
CLIENT_SERVER_GROUP_ADD = "client_server_group_add",
|
||||
CLIENT_SERVER_GROUP_REMOVE = "client_server_group_remove",
|
||||
CLIENT_CHANNEL_GROUP_CHANGE = "client_channel_group_change",
|
||||
|
||||
CHANNEL_CREATE = "channel_create",
|
||||
CHANNEL_DELETE = "channel_delete",
|
||||
|
||||
ERROR_CUSTOM = "error_custom",
|
||||
ERROR_PERMISSION = "error_permission",
|
||||
|
||||
RECONNECT_SCHEDULED = "reconnect_scheduled",
|
||||
RECONNECT_EXECUTE = "reconnect_execute",
|
||||
RECONNECT_CANCELED = "reconnect_canceled"
|
||||
}
|
||||
|
||||
export namespace base {
|
||||
export type Client = {
|
||||
client_unique_id: string;
|
||||
client_name: string;
|
||||
client_id: number;
|
||||
}
|
||||
export type Channel = {
|
||||
channel_id: number;
|
||||
channel_name: string;
|
||||
}
|
||||
export type Server = {
|
||||
server_name: string;
|
||||
server_unique_id: string;
|
||||
}
|
||||
export type ServerAddress = {
|
||||
server_hostname: string;
|
||||
server_port: number;
|
||||
}
|
||||
}
|
||||
|
||||
export namespace event {
|
||||
export type GlobalMessage = {
|
||||
sender: base.Client;
|
||||
message: string;
|
||||
}
|
||||
export type ConnectBegin = {
|
||||
address: base.ServerAddress;
|
||||
client_nickname: string;
|
||||
}
|
||||
export type ErrorCustom = {
|
||||
message: string;
|
||||
}
|
||||
|
||||
export type ReconnectScheduled = {
|
||||
timeout: number;
|
||||
}
|
||||
|
||||
export type ReconnectCanceled = { }
|
||||
export type ReconnectExecute = { }
|
||||
|
||||
export type ErrorPermission = {
|
||||
permission: PermissionInfo;
|
||||
}
|
||||
|
||||
//tr("You was moved by {3} from channel {1} to {2}") : tr("{0} was moved from channel {1} to {2} by {3}")
|
||||
//tr("You switched from channel {1} to {2}") : tr("{0} switched from channel {1} to {2}")
|
||||
//tr("You got kicked out of the channel {1} to channel {2} by {3}{4}") : tr("{0} got kicked from channel {1} to {2} by {3}{4}")
|
||||
export type ClientMove = {
|
||||
channel_from?: base.Channel;
|
||||
channel_from_own: boolean;
|
||||
|
||||
channel_to?: base.Channel;
|
||||
channel_to_own: boolean;
|
||||
|
||||
client: base.Client;
|
||||
client_own: boolean;
|
||||
|
||||
invoker?: base.Client;
|
||||
|
||||
message?: string;
|
||||
reason: ViewReasonId;
|
||||
}
|
||||
|
||||
export type ClientEnter = {
|
||||
channel_from?: base.Channel;
|
||||
channel_to?: base.Channel;
|
||||
|
||||
client: base.Client;
|
||||
invoker?: base.Client;
|
||||
|
||||
message?: string;
|
||||
own_channel: boolean;
|
||||
|
||||
reason: ViewReasonId;
|
||||
ban_time?: number;
|
||||
}
|
||||
|
||||
export type ClientLeave = {
|
||||
channel_from?: base.Channel;
|
||||
channel_to?: base.Channel;
|
||||
|
||||
client: base.Client;
|
||||
invoker?: base.Client;
|
||||
|
||||
message?: string;
|
||||
own_channel: boolean;
|
||||
|
||||
reason: ViewReasonId;
|
||||
ban_time?: number;
|
||||
}
|
||||
|
||||
export type ChannelCreate = {
|
||||
creator: base.Client;
|
||||
channel: base.Channel;
|
||||
|
||||
own_action: boolean;
|
||||
}
|
||||
|
||||
export type ChannelDelete = {
|
||||
deleter: base.Client;
|
||||
channel: base.Channel;
|
||||
|
||||
own_action: boolean;
|
||||
}
|
||||
|
||||
export type ConnectionConnected = {
|
||||
own_client: base.Client;
|
||||
}
|
||||
export type ConnectionFailed = {};
|
||||
export type ConnectionLogin = {}
|
||||
export type ConnectionHostnameResolve = {};
|
||||
export type ConnectionHostnameResolved = {
|
||||
address: base.ServerAddress;
|
||||
}
|
||||
export type ConnectionHostnameResolveError = {
|
||||
message: string;
|
||||
}
|
||||
|
||||
export type ConnectionVoiceSetupFailed = {
|
||||
reason: string;
|
||||
reconnect_delay: number; /* if less or equal to 0 reconnect is prohibited */
|
||||
}
|
||||
|
||||
export type ClientNicknameChanged = {
|
||||
own_action: boolean;
|
||||
client: base.Client;
|
||||
}
|
||||
|
||||
export type ClientNicknameChangeFailed = {
|
||||
reason: string;
|
||||
}
|
||||
}
|
||||
|
||||
export type LogMessage = {
|
||||
type: Type;
|
||||
timestamp: number;
|
||||
data: any;
|
||||
}
|
||||
|
||||
export interface TypeInfo {
|
||||
"connection_begin" : event.ConnectBegin;
|
||||
"global_message": event.GlobalMessage;
|
||||
|
||||
"error_custom": event.ErrorCustom;
|
||||
"error_permission": event.ErrorPermission;
|
||||
|
||||
"connection_hostname_resolved": event.ConnectionHostnameResolved;
|
||||
"connection_hostname_resolve": event.ConnectionHostnameResolve;
|
||||
"connection_hostname_resolve_error": event.ConnectionHostnameResolveError;
|
||||
"connection_failed": event.ConnectionFailed;
|
||||
"connection_login": event.ConnectionLogin;
|
||||
"connection_connected": event.ConnectionConnected;
|
||||
"connection_voice_setup_failed": event.ConnectionVoiceSetupFailed;
|
||||
|
||||
"reconnect_scheduled": event.ReconnectScheduled;
|
||||
"reconnect_canceled": event.ReconnectCanceled;
|
||||
"reconnect_execute": event.ReconnectExecute;
|
||||
|
||||
"client_view_enter": event.ClientEnter;
|
||||
"client_view_move": event.ClientMove;
|
||||
"client_view_leave": event.ClientLeave;
|
||||
|
||||
"client_nickname_change_failed": event.ClientNicknameChangeFailed,
|
||||
"client_nickname_changed": event.ClientNicknameChanged,
|
||||
|
||||
"channel_create": event.ChannelCreate;
|
||||
"channel_delete": event.ChannelDelete;
|
||||
}
|
||||
|
||||
type MessageBuilderOptions = {};
|
||||
type MessageBuilder<T extends keyof server.TypeInfo> = (data: TypeInfo[T], options: MessageBuilderOptions) => JQuery[] | undefined;
|
||||
|
||||
export const MessageBuilders: {[key: string]: MessageBuilder<any>} = {
|
||||
"global_message": (data: event.GlobalMessage, options) => {
|
||||
return [];
|
||||
},
|
||||
"error_custom": (data: event.ErrorCustom, options) => {
|
||||
return [$.spawn("div").addClass("log-error").text(data.message)]
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export class ServerLog {
|
||||
private readonly handle: ConnectionHandler;
|
||||
private history_length: number = 100;
|
||||
|
||||
private _log: server.LogMessage[] = [];
|
||||
private _html_tag: JQuery;
|
||||
private _log_container: JQuery;
|
||||
private auto_follow: boolean; /* automatic scroll to bottom */
|
||||
private _ignore_event: number; /* after auto scroll we've triggered the scroll event. We want to prevent this so we capture the next event */
|
||||
|
||||
constructor(handle: ConnectionHandler) {
|
||||
this.handle = handle;
|
||||
this.auto_follow = true;
|
||||
|
||||
this._html_tag = $.spawn("div").addClass("container-log");
|
||||
this._log_container = $.spawn("div").addClass("container-messages");
|
||||
this._log_container.appendTo(this._html_tag);
|
||||
|
||||
this._html_tag.on('scroll', event => {
|
||||
if(Date.now() - this._ignore_event < 100) {
|
||||
this._ignore_event = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
this.auto_follow = (this._html_tag[0].scrollTop + this._html_tag[0].clientHeight + this._html_tag[0].clientHeight * .125) > this._html_tag[0].scrollHeight;
|
||||
})
|
||||
}
|
||||
|
||||
log<T extends keyof server.TypeInfo>(type: T, data: server.TypeInfo[T]) {
|
||||
const event = {
|
||||
data: data,
|
||||
timestamp: Date.now(),
|
||||
type: type as any
|
||||
};
|
||||
|
||||
this._log.push(event);
|
||||
while(this._log.length > this.history_length)
|
||||
this._log.pop_front();
|
||||
|
||||
this.append_log(event);
|
||||
}
|
||||
|
||||
html_tag() : JQuery {
|
||||
return this._html_tag;
|
||||
}
|
||||
|
||||
private append_log(message: server.LogMessage) {
|
||||
let container = $.spawn("div").addClass("log-message");
|
||||
|
||||
/* build timestamp */
|
||||
{
|
||||
const num = number => ('00' + number).substr(-2);
|
||||
const date = new Date(message.timestamp);
|
||||
$.spawn("div")
|
||||
.addClass("timestamp")
|
||||
.text("<" + num(date.getHours()) + ":" + num(date.getMinutes()) + ":" + num(date.getSeconds()) + ">")
|
||||
.appendTo(container);
|
||||
}
|
||||
|
||||
/* build message data */
|
||||
{
|
||||
const builder = server.MessageBuilders[message.type];
|
||||
if(!builder) {
|
||||
MessageHelper.formatMessage(tr("missing log message builder {0}!"), message.type).forEach(e => e.addClass("log-error").appendTo(container));
|
||||
} else {
|
||||
const elements = builder(message.data, {});
|
||||
if(!elements)
|
||||
return; /* discard message */
|
||||
container.append(...elements);
|
||||
}
|
||||
}
|
||||
this._ignore_event = Date.now();
|
||||
this._log_container.append(container);
|
||||
|
||||
/* max history messages! */
|
||||
const messages = this._log_container.children();
|
||||
let index = 0;
|
||||
while(messages.length - index > this.history_length)
|
||||
index++;
|
||||
const hide_elements = messages.filter(idx => idx < index);
|
||||
hide_elements.hide(250, () => hide_elements.detach());
|
||||
|
||||
if(this.auto_follow)
|
||||
this._html_tag.scrollTop(this._html_tag[0].scrollHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* impl of the parsers */
|
||||
namespace log {
|
||||
export namespace server {
|
||||
namespace impl {
|
||||
const client_tag = (client: base.Client, braces?: boolean) => htmltags.generate_client_object({
|
||||
client_unique_id: client.client_unique_id,
|
||||
client_id: client.client_id,
|
||||
client_name: client.client_name,
|
||||
add_braces: braces
|
||||
});
|
||||
const channel_tag = (channel: base.Channel, braces?: boolean) => htmltags.generate_channel_object({
|
||||
channel_display_name: channel.channel_name,
|
||||
channel_name: channel.channel_name,
|
||||
channel_id: channel.channel_id,
|
||||
add_braces: braces
|
||||
});
|
||||
|
||||
MessageBuilders["connection_begin"] = (data: event.ConnectBegin, options) => {
|
||||
return MessageHelper.formatMessage(tr("Connecting to {0}{1}"), data.address.server_hostname, data.address.server_port == 9987 ? "" : (":" + data.address.server_port));
|
||||
};
|
||||
|
||||
MessageBuilders["connection_hostname_resolve"] = (data: event.ConnectionHostnameResolve, options) => MessageHelper.formatMessage(tr("Resolving hostname"));
|
||||
MessageBuilders["connection_hostname_resolved"] = (data: event.ConnectionHostnameResolved, options) => MessageHelper.formatMessage(tr("Hostname resolved successfully to {0}:{1}"), data.address.server_hostname, data.address.server_port);
|
||||
MessageBuilders["connection_hostname_resolve_error"] = (data: event.ConnectionHostnameResolveError, options) => MessageHelper.formatMessage(tr("Failed to resolve hostname. Connecting to given hostname. Error: {0}"), data.message);
|
||||
|
||||
MessageBuilders["connection_login"] = (data: event.ConnectionLogin, options) => MessageHelper.formatMessage(tr("Logging in..."));
|
||||
MessageBuilders["connection_failed"] = (data: event.ConnectionFailed, options) => MessageHelper.formatMessage(tr("Connect failed."));
|
||||
MessageBuilders["connection_connected"] = (data: event.ConnectionConnected, options) => MessageHelper.formatMessage(tr("Connected as {0}"), client_tag(data.own_client, true));
|
||||
|
||||
MessageBuilders["connection_voice_setup_failed"] = (data: event.ConnectionVoiceSetupFailed, options) => {
|
||||
return MessageHelper.formatMessage(tr("Failed to setup voice bridge: {0}. Allow reconnect: {1}"), data.reason, data.reconnect_delay > 0 ? tr("yes") : tr("no"));
|
||||
};
|
||||
|
||||
MessageBuilders["error_permission"] = (data: event.ErrorPermission, options) => {
|
||||
return MessageHelper.formatMessage(tr("Insufficient client permissions. Failed on permission {0}"), data.permission.name).map(e => e.addClass("log-error"));
|
||||
};
|
||||
|
||||
MessageBuilders["client_view_enter"] = (data: event.ClientEnter, options) => {
|
||||
if(data.reason == ViewReasonId.VREASON_SYSTEM) {
|
||||
return undefined;
|
||||
} if(data.reason == ViewReasonId.VREASON_USER_ACTION) {
|
||||
/* client appeared */
|
||||
if(data.channel_from) {
|
||||
return MessageHelper.formatMessage(data.own_channel ? tr("{0} appeared from {1} to your {2}") : tr("{0} appeared from {1} to {2}"), client_tag(data.client), channel_tag(data.channel_from), channel_tag(data.channel_to));
|
||||
} else {
|
||||
return MessageHelper.formatMessage(data.own_channel ? tr("{0} connected to your channel {1}") : tr("{0} connected to channel {1}"), client_tag(data.client), channel_tag(data.channel_to));
|
||||
}
|
||||
} else if(data.reason == ViewReasonId.VREASON_MOVED) {
|
||||
if(data.channel_from) {
|
||||
return MessageHelper.formatMessage(data.own_channel ? tr("{0} appeared from {1} to your channel {2}, moved by {3}") : tr("{0} appeared from {1} to {2}, moved by {3}"),
|
||||
client_tag(data.client),
|
||||
channel_tag(data.channel_from),
|
||||
channel_tag(data.channel_to),
|
||||
client_tag(data.invoker)
|
||||
);
|
||||
} else {
|
||||
return MessageHelper.formatMessage(data.own_channel ? tr("{0} appeared to your channel {1}, moved by {2}") : tr("{0} appeared to {1}, moved by {2}"),
|
||||
client_tag(data.client),
|
||||
channel_tag(data.channel_to),
|
||||
client_tag(data.invoker)
|
||||
);
|
||||
}
|
||||
} else if(data.reason == ViewReasonId.VREASON_CHANNEL_KICK) {
|
||||
if(data.channel_from) {
|
||||
return MessageHelper.formatMessage(data.own_channel ? tr("{0} appeared from {1} to your channel {2}, kicked by {3}{4}") : tr("{0} appeared from {1} to {2}, kicked by {3}{4}"),
|
||||
client_tag(data.client),
|
||||
channel_tag(data.channel_from),
|
||||
channel_tag(data.channel_to),
|
||||
client_tag(data.invoker),
|
||||
data.message ? (" (" + data.message + ")") : ""
|
||||
);
|
||||
} else {
|
||||
return MessageHelper.formatMessage(data.own_channel ? tr("{0} appeared to your channel {1}, kicked by {2}{3}") : tr("{0} appeared to {1}, kicked by {2}{3}"),
|
||||
client_tag(data.client),
|
||||
channel_tag(data.channel_to),
|
||||
client_tag(data.invoker),
|
||||
data.message ? (" (" + data.message + ")") : ""
|
||||
);
|
||||
}
|
||||
}
|
||||
return [$.spawn("div").addClass("log-error").text("Invalid view enter reason id (" + data.message + ")")];
|
||||
};
|
||||
|
||||
MessageBuilders["client_view_move"] = (data: event.ClientMove, options) => {
|
||||
if(data.reason == ViewReasonId.VREASON_MOVED) {
|
||||
return MessageHelper.formatMessage(data.client_own ? tr("You was moved by {3} from channel {1} to {2}") : tr("{0} was moved from channel {1} to {2} by {3}"),
|
||||
client_tag(data.client),
|
||||
channel_tag(data.channel_from),
|
||||
channel_tag(data.channel_to),
|
||||
client_tag(data.invoker)
|
||||
);
|
||||
} else if(data.reason == ViewReasonId.VREASON_USER_ACTION) {
|
||||
return MessageHelper.formatMessage(data.client_own ? tr("You switched from channel {1} to {2}") : tr("{0} switched from channel {1} to {2}"),
|
||||
client_tag(data.client),
|
||||
channel_tag(data.channel_from),
|
||||
channel_tag(data.channel_to)
|
||||
);
|
||||
} else if(data.reason == ViewReasonId.VREASON_CHANNEL_KICK) {
|
||||
return MessageHelper.formatMessage(data.client_own ? tr("You got kicked out of the channel {1} to channel {2} by {3}{4}") : tr("{0} got kicked from channel {1} to {2} by {3}{4}"),
|
||||
client_tag(data.client),
|
||||
channel_tag(data.channel_from),
|
||||
channel_tag(data.channel_to),
|
||||
client_tag(data.invoker),
|
||||
data.message ? (" (" + data.message + ")") : ""
|
||||
);
|
||||
}
|
||||
return [$.spawn("div").addClass("log-error").text("Invalid view move reason id (" + data.reason + ")")];
|
||||
};
|
||||
|
||||
MessageBuilders["client_view_leave"] = (data: event.ClientLeave, options) => {
|
||||
if(data.reason == ViewReasonId.VREASON_USER_ACTION) {
|
||||
return MessageHelper.formatMessage(data.own_channel ? tr("{0} disappeared from your channel {1} to {2}") : tr("{0} disappeared from {1} to {2}"), client_tag(data.client), channel_tag(data.channel_from), channel_tag(data.channel_to));
|
||||
} else if(data.reason == ViewReasonId.VREASON_SERVER_LEFT) {
|
||||
return MessageHelper.formatMessage(tr("{0} left the server{1}"), client_tag(data.client), data.message ? (" (" + data.message + ")") : "");
|
||||
} else if(data.reason == ViewReasonId.VREASON_SERVER_KICK) {
|
||||
return MessageHelper.formatMessage(tr("{0} was kicked from the server by {1}.{2}"), client_tag(data.client), client_tag(data.invoker), data.message ? (" (" + data.message + ")") : "");
|
||||
} else if(data.reason == ViewReasonId.VREASON_CHANNEL_KICK) {
|
||||
return MessageHelper.formatMessage(data.own_channel ? tr("{0} was kicked from your channel by {2}.{3}") : tr("{0} was kicked from channel {1} by {2}.{3}"),
|
||||
client_tag(data.client),
|
||||
channel_tag(data.channel_from),
|
||||
client_tag(data.invoker),
|
||||
data.message ? (" (" + data.message + ")") : ""
|
||||
);
|
||||
} else if(data.reason == ViewReasonId.VREASON_BAN) {
|
||||
let duration = "permanently";
|
||||
if(data.ban_time)
|
||||
duration = "for " + formatDate(data.ban_time);
|
||||
return MessageHelper.formatMessage(tr("{0} was banned {1} by {2}.{3}"),
|
||||
client_tag(data.client),
|
||||
duration,
|
||||
client_tag(data.invoker),
|
||||
data.message ? (" (" + data.message + ")") : ""
|
||||
);
|
||||
} else if(data.reason == ViewReasonId.VREASON_TIMEOUT) {
|
||||
return MessageHelper.formatMessage(tr("{0} timed out{1}"), client_tag(data.client), data.message ? (" (" + data.message + ")") : "");
|
||||
}
|
||||
return [$.spawn("div").addClass("log-error").text("Invalid view leave reason id (" + data.message + ")")];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -65,6 +65,10 @@ namespace htmltags {
|
|||
return result;
|
||||
}
|
||||
|
||||
export function generate_client_object(properties: ClientProperties) : JQuery {
|
||||
return $(this.generate_client(properties));
|
||||
}
|
||||
|
||||
/* required for the bbcodes */
|
||||
function generate_channel_open(properties: ChannelProperties) : string {
|
||||
let result = "";
|
||||
|
@ -103,6 +107,10 @@ namespace htmltags {
|
|||
return result;
|
||||
}
|
||||
|
||||
export function generate_channel_object(properties: ChannelProperties) : JQuery {
|
||||
return $(this.generate_channel(properties));
|
||||
}
|
||||
|
||||
|
||||
export namespace callbacks {
|
||||
export function callback_context_client(element: JQuery) {
|
||||
|
|
|
@ -280,17 +280,19 @@ namespace Modals {
|
|||
icon.state = "error";
|
||||
};
|
||||
|
||||
if(image.naturalWidth > 32 && image.naturalHeight > 32) {
|
||||
width_error("width and height (max 32px)");
|
||||
return;
|
||||
}
|
||||
if(image.naturalWidth > 32) {
|
||||
width_error("width (max 32px)");
|
||||
return;
|
||||
}
|
||||
if(image.naturalHeight > 32) {
|
||||
width_error("height (max 32px)");
|
||||
return;
|
||||
if(!result.startsWith("data:image/svg+xml")) {
|
||||
if(image.naturalWidth > 32 && image.naturalHeight > 32) {
|
||||
width_error("width and height (max 32px). Given: " + image.naturalWidth + "x" + image.naturalHeight);
|
||||
return;
|
||||
}
|
||||
if(image.naturalWidth > 32) {
|
||||
width_error("width (max 32px)");
|
||||
return;
|
||||
}
|
||||
if(image.naturalHeight > 32) {
|
||||
width_error("height (max 32px)");
|
||||
return;
|
||||
}
|
||||
}
|
||||
console.log("Image loaded (%dx%d) %s (%s)", image.naturalWidth, image.naturalHeight, image.name, icon.icon_id);
|
||||
icon.image_element = () => {
|
||||
|
|
|
@ -299,6 +299,11 @@ namespace Modals {
|
|||
const permission = entry.permission();
|
||||
const value: PermissionValue = this.permission_value_map[permission.id];
|
||||
|
||||
if(permission.name === "i_icon_id") {
|
||||
entry.set_icon_id_image(undefined);
|
||||
entry.on_icon_select = this.icon_selector;
|
||||
}
|
||||
|
||||
if(value && value.hasValue()) {
|
||||
entry.value = value.value;
|
||||
entry.flag_skip = value.flag_skip;
|
||||
|
@ -311,13 +316,11 @@ namespace Modals {
|
|||
}).catch(error => {
|
||||
console.warn(tr("Failed to load icon for permission editor: %o"), error);
|
||||
});
|
||||
entry.on_icon_select = this.icon_selector;
|
||||
}
|
||||
} else {
|
||||
entry.value = undefined;
|
||||
entry.flag_skip = false;
|
||||
entry.flag_negate = false;
|
||||
entry.set_icon_id_image(undefined);
|
||||
}
|
||||
|
||||
if(value && value.hasGrant()) {
|
||||
|
|
|
@ -643,7 +643,11 @@ class ChannelTree {
|
|||
|
||||
return new Promise<ChannelEntry>(resolve => { resolve(channel); })
|
||||
}).then(channel => {
|
||||
this.client.chat.serverChat().appendMessage(tr("Channel {} successfully created!"), true, channel.generate_tag(true));
|
||||
this.client.log.log(log.server.Type.CHANNEL_CREATE, {
|
||||
channel: channel.log_data(),
|
||||
creator: this.client.getClient().log_data(),
|
||||
own_action: true
|
||||
});
|
||||
this.client.sound.play(Sound.CHANNEL_CREATED);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -45,7 +45,7 @@ namespace connection {
|
|||
|
||||
on_connect: () => void = () => {
|
||||
console.log(tr("Socket connected"));
|
||||
this.client.chat.serverChat().appendMessage(tr("Logging in..."));
|
||||
this.client.log.log(log.server.Type.CONNECTION_LOGIN, {});
|
||||
this._handshakeHandler.initialize();
|
||||
this._handshakeHandler.startHandshake();
|
||||
};
|
||||
|
|
|
@ -393,7 +393,10 @@ namespace audio {
|
|||
} else if(json["request"] == "status") {
|
||||
if(json["state"] == "failed") {
|
||||
const chandler = this.connection.client;
|
||||
chandler.chat.serverChat().appendError(tr("Failed to setup voice bridge ({}). Allow reconnect: {}"), json["reason"], json["allow_reconnect"]);
|
||||
chandler.log.log(log.server.Type.CONNECTION_VOICE_SETUP_FAILED, {
|
||||
reason: json["reason"],
|
||||
reconnect_delay: json["allow_reconnect"] ? 1 : 0
|
||||
});
|
||||
log.error(LogCategory.NETWORKING, tr("Failed to setup voice bridge (%s). Allow reconnect: %s"), json["reason"], json["allow_reconnect"]);
|
||||
if(json["allow_reconnect"] == true) {
|
||||
this.createSession();
|
||||
|
|
Loading…
Reference in New Issue