mirror of
https://github.com/citizenfx/cfx-server-data.git
synced 2025-12-12 06:14:09 +01:00
chatv2: channels, hidden modes and automatic webpack
This commit is contained in:
1
resources/[gameplay]/chat/.gitignore
vendored
1
resources/[gameplay]/chat/.gitignore
vendored
@@ -1,3 +1,4 @@
|
|||||||
node_modules/
|
node_modules/
|
||||||
|
.yarn.installed
|
||||||
yarn-error.log
|
yarn-error.log
|
||||||
dist/
|
dist/
|
||||||
@@ -43,7 +43,8 @@ AddEventHandler('__cfx_internal:serverPrint', function(msg)
|
|||||||
message = {
|
message = {
|
||||||
templateId = 'print',
|
templateId = 'print',
|
||||||
multiline = true,
|
multiline = true,
|
||||||
args = { msg }
|
args = { msg },
|
||||||
|
mode = '_global'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -15,3 +15,10 @@ files {
|
|||||||
fx_version 'adamant'
|
fx_version 'adamant'
|
||||||
games { 'rdr3', 'gta5' }
|
games { 'rdr3', 'gta5' }
|
||||||
rdr3_warning 'I acknowledge that this is a prerelease build of RedM, and I am aware my resources *will* become incompatible once RedM ships.'
|
rdr3_warning 'I acknowledge that this is a prerelease build of RedM, and I am aware my resources *will* become incompatible once RedM ships.'
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
'yarn',
|
||||||
|
'webpack'
|
||||||
|
}
|
||||||
|
|
||||||
|
webpack_config 'webpack.config.js'
|
||||||
@@ -13,6 +13,8 @@ export interface Message {
|
|||||||
multiline?: boolean;
|
multiline?: boolean;
|
||||||
color?: [ number, number, number ];
|
color?: [ number, number, number ];
|
||||||
templateId?: number;
|
templateId?: number;
|
||||||
|
mode?: string;
|
||||||
|
modeData?: Mode;
|
||||||
|
|
||||||
id?: string;
|
id?: string;
|
||||||
}
|
}
|
||||||
@@ -31,6 +33,9 @@ export interface Mode {
|
|||||||
name: string;
|
name: string;
|
||||||
displayName: string;
|
displayName: string;
|
||||||
color: string;
|
color: string;
|
||||||
|
hidden?: boolean;
|
||||||
|
isChannel?: boolean;
|
||||||
|
isGlobal?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ChatHideStates {
|
enum ChatHideStates {
|
||||||
@@ -45,6 +50,14 @@ const defaultMode: Mode = {
|
|||||||
color: '#fff'
|
color: '#fff'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const globalMode: Mode = {
|
||||||
|
name: '_global',
|
||||||
|
displayName: 'All',
|
||||||
|
color: '#fff',
|
||||||
|
isGlobal: true,
|
||||||
|
hidden: true
|
||||||
|
};
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
template: "#app_template",
|
template: "#app_template",
|
||||||
name: "app",
|
name: "app",
|
||||||
@@ -72,7 +85,7 @@ export default Vue.extend({
|
|||||||
showWindowTimer: 0,
|
showWindowTimer: 0,
|
||||||
showHideStateTimer: 0,
|
showHideStateTimer: 0,
|
||||||
listener: (event: MessageEvent) => {},
|
listener: (event: MessageEvent) => {},
|
||||||
modes: [defaultMode] as Mode[],
|
modes: [defaultMode, globalMode] as Mode[],
|
||||||
modeIdx: 0,
|
modeIdx: 0,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -118,6 +131,17 @@ export default Vue.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
filteredMessages(): Message[] {
|
||||||
|
return this.messages.filter(
|
||||||
|
// show messages that are
|
||||||
|
// - (if the current mode is a channel) global, or in the current mode
|
||||||
|
// - (if the message is a channel) in the current mode
|
||||||
|
el => (el.modeData?.isChannel || this.modes[this.modeIdx].isChannel) ?
|
||||||
|
(el.mode === this.modes[this.modeIdx].name || el.modeData?.isGlobal) :
|
||||||
|
true
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
suggestions(): Suggestion[] {
|
suggestions(): Suggestion[] {
|
||||||
return this.backingSuggestions.filter(
|
return this.backingSuggestions.filter(
|
||||||
el => this.removedSuggestions.indexOf(el.name) <= -1
|
el => this.removedSuggestions.indexOf(el.name) <= -1
|
||||||
@@ -133,7 +157,7 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
modePrefix(): string {
|
modePrefix(): string {
|
||||||
if (this.modes.length === 1) {
|
if (this.modes.length === 2) {
|
||||||
return `➤`;
|
return `➤`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,6 +225,7 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
ON_MESSAGE({ message }: { message: Message }) {
|
ON_MESSAGE({ message }: { message: Message }) {
|
||||||
message.id = `${new Date().getTime()}${Math.random()}`;
|
message.id = `${new Date().getTime()}${Math.random()}`;
|
||||||
|
message.modeData = this.modes.find(mode => mode.name === message.mode);
|
||||||
this.messages.push(message);
|
this.messages.push(message);
|
||||||
},
|
},
|
||||||
ON_CLEAR() {
|
ON_CLEAR() {
|
||||||
@@ -360,13 +385,17 @@ export default Vue.extend({
|
|||||||
buf.scrollTop = buf.scrollTop + 100;
|
buf.scrollTop = buf.scrollTop + 100;
|
||||||
} else if (e.which === 9) { // tab
|
} else if (e.which === 9) { // tab
|
||||||
if (e.shiftKey || e.altKey) {
|
if (e.shiftKey || e.altKey) {
|
||||||
--this.modeIdx;
|
do {
|
||||||
|
--this.modeIdx;
|
||||||
|
|
||||||
if (this.modeIdx < 0) {
|
if (this.modeIdx < 0) {
|
||||||
this.modeIdx = this.modes.length - 1;
|
this.modeIdx = this.modes.length - 1;
|
||||||
}
|
}
|
||||||
|
} while (this.modes[this.modeIdx].hidden);
|
||||||
} else {
|
} else {
|
||||||
this.modeIdx = (this.modeIdx + 1) % this.modes.length;
|
do {
|
||||||
|
this.modeIdx = (this.modeIdx + 1) % this.modes.length;
|
||||||
|
} while (this.modes[this.modeIdx].hidden);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
'hidden': !showWindow
|
'hidden': !showWindow
|
||||||
}">
|
}">
|
||||||
<div class="chat-messages" ref="messages">
|
<div class="chat-messages" ref="messages">
|
||||||
<message v-for="msg in messages"
|
<message v-for="msg in filteredMessages"
|
||||||
:templates="templates"
|
:templates="templates"
|
||||||
:multiline="msg.multiline"
|
:multiline="msg.multiline"
|
||||||
:args="msg.args"
|
:args="msg.args"
|
||||||
|
|||||||
@@ -62,7 +62,9 @@ exports('registerMode', function(modeData)
|
|||||||
local clObj = {
|
local clObj = {
|
||||||
name = modeData.name,
|
name = modeData.name,
|
||||||
displayName = modeData.displayName,
|
displayName = modeData.displayName,
|
||||||
color = modeData.color or '#fff'
|
color = modeData.color or '#fff',
|
||||||
|
isChannel = modeData.isChannel,
|
||||||
|
isGlobal = modeData.isGlobal,
|
||||||
}
|
}
|
||||||
|
|
||||||
if not modeData.seObject then
|
if not modeData.seObject then
|
||||||
@@ -185,9 +187,6 @@ local function routeMessage(source, author, message, mode, fromConsole)
|
|||||||
TriggerEvent('chatMessage', source, #outMessage.args > 1 and outMessage.args[1] or '', outMessage.args[#outMessage.args])
|
TriggerEvent('chatMessage', source, #outMessage.args > 1 and outMessage.args[1] or '', outMessage.args[#outMessage.args])
|
||||||
|
|
||||||
if not WasEventCanceled() then
|
if not WasEventCanceled() then
|
||||||
-- remove the mode name, we don't need this for routing
|
|
||||||
outMessage.mode = nil
|
|
||||||
|
|
||||||
if type(routingTarget) ~= 'table' then
|
if type(routingTarget) ~= 'table' then
|
||||||
TriggerClientEvent('chat:addMessage', routingTarget, outMessage)
|
TriggerClientEvent('chat:addMessage', routingTarget, outMessage)
|
||||||
else
|
else
|
||||||
@@ -270,7 +269,9 @@ AddEventHandler('chat:init', function()
|
|||||||
local clObj = {
|
local clObj = {
|
||||||
name = modeData.name,
|
name = modeData.name,
|
||||||
displayName = modeData.displayName,
|
displayName = modeData.displayName,
|
||||||
color = modeData.color or '#fff'
|
color = modeData.color or '#fff',
|
||||||
|
isChannel = modeData.isChannel,
|
||||||
|
isGlobal = modeData.isGlobal,
|
||||||
}
|
}
|
||||||
|
|
||||||
if not modeData.seObject or IsPlayerAceAllowed(source, modeData.seObject) then
|
if not modeData.seObject or IsPlayerAceAllowed(source, modeData.seObject) then
|
||||||
|
|||||||
Reference in New Issue
Block a user