创建一个基本的聊天栏? [英] Creating a basic chatbar?

查看:98
本文介绍了创建一个基本的聊天栏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是旧的;请查看底部的更新文本。



因此,我和朋友们在学校时使用Google文档进行交流,我们设置了一个挑战,即创建一个工作和高效聊天栏沟通更好的结果。我已经在JavaScript上工作​​了很长一段时间,但之前从未使用过 Google Apps脚本。我们正在使用文档应用程序来聊天;我想到的代码如下,但我遇到了一些问题:


  1. 用户关闭它时出错,然后进入在工具栏中重新打开聊天 - >打开聊天,说:遇到错误:发生意外错误; 没有指定行或原因

  2. 需要文档中的某个隐藏元素,它允许用户查看其他人输入的内容,但是如果不使用聊天框,则无法编辑在推荐文本时会添加事件监听器来更新聊天框)






  //主要功能,当文档第一次打开时运行。 
函数onOpen(){
var app = UiApp.createApplication(); //创建一个用于聊天栏的UI应用程序

if(getCurrentUser()==dev1|| getCurrentUser()==dev2){//用户标识为隐私隐藏
DocumentApp.getUi()。createMenu('Chat')
.addItem('AutoColor','autoColor')
.addItem('Open Chat','createChatBox')
.addItem('Elements','displayElements')//隐藏,因为它对于经常使用不重要
.addItem('MyID','showUser')
.addToUi();
} else {
DocumentApp.getUi()。createMenu('Chat')
.addItem('AutoColor','autoColor')
.addItem('Open Chat', 'createChatBox')
.addToUi();



//创建并返回聊天记录
函数createChatBox(){
var app = UiApp.getActiveApplication()
app.setTitle(Chat Bar(not yet working));
var vPanel = app.createVerticalPanel()。setId('chatPanel')。setWidth('100%');
var textArea = app.createTextArea()。setId('chatBox')。setName('chatBox').setReadOnly(true).setText('')。setSize('250px','450px'); //只读,所以他们不能编辑文本,即使它不会影响整体聊天
var textBox = app.createTextBox()。setId('messageBox').setName('messageBox')。setText( '话');
var chatHandler = app.createServerHandler(sayChat)。addCallbackElement(textArea).addCallbackElement(textBox);
var chatButton = app.createButton()。setId(sayButton)。setText(Say!)。addMouseUpHandler(chatHandler);

vPanel.add(textArea);
vPanel.add(textBox);
vPanel.add(chatButton);

app.add(vPanel);
DocumentApp.getUi()。showSidebar(app);
返回应用程序;
}

//Say!的事件处理程序(后)按钮被按下。可能是冲突源于哪里。
函数sayChat(eventInfo){
var app = UiApp.getActiveApplication();
var parameter = eventInfo.parameter;

app.getElementById(chatBox)。setText(parameter.chatBox +[+ getCurrentUser()+]:+ parameter.messageBox);
app.getElementById(messageBox)。setText();

返回应用;
}

//一个调试函数和一个函数来告诉你电子邮件的唯一部分(无用,真的)
function showUser(){
DocumentApp。 getUi()。alert(Your userId is:+ getCurrentUser());
}

//返回一个人电子邮件的唯一部分;如果他们的电子邮件是magicuser@gmail.com,它将返回magicuser
函数getCurrentUser(){
var email = Session.getActiveUser()。getEmail();
return email.substring(0,email.indexOf(@));
}
//自动颜色和displayElements方法是隐藏的,因为它们包含其他用户信息。他们都按预期工作,不属于问题的一部分。

我不需要有人重写代码(尽管那会非常感谢!),但而是指出我做错了什么,或者建议改变/添加。

最后,在您提出建议之前,Google文档聊天功能不适用于我们的电脑。这不是文档的错误,但可能与我们的浏览器存在兼容性错误。这是因为这个问题,我们正在经历这个有趣而匆忙的制作我们自己聊天方法的过程。



更新



我决定放弃使用纯Google Apps脚本的聊天版本,并使用GAS和HTML帮助改进我的朋友版本。我添加了图像缩略图/链接支持与命令/ img或/图像,以及改进的时间和计数器,以及一些其他幕后更新。以下是它的快速截图:





宏伟的聊天程序从头开始编程,没有bug更新方法,只是一个临时刷新数据库来检查消息并设置HTML文本区域文本。没有更多的bug getText方法。对于数据库中的每条新消息,无论是针对用户还是面向聊天中的每个人,我们都会将所有数据库消息加载到限制(一次50条消息),然后显示它们。在消息中使用HTML是其出现和功能的关键,如图像。

 函数getChat(){
var chat =;
var time = getTime();

var username = getCurrentUsername();

var db = ScriptDb.getMyDb();
var query = db.query({time:db.greaterThan(getJoinTime())})。sortBy('time',db.DESCENDING).limit(50);

var flag = query.getSize()%2!= 0;

while(query.hasNext()){
var record = query.next();
if(record.showTo ==all|| record.showTo == getCurrentUsername()){
var text = record.text;
for(var i = 0; i< text.split().length; i ++){
var substr = text.split()[i];
if(substr.indexOf(http://)== 0 || substr.indexOf(https://)== 0){
text = text.replace(substr, < a href ='+ substr +'>+ substr +< / a>);
}
}
var message =< pre style ='display:inline;'>< span class ='+(flag?even:odd) +'>< b> [+ record.realTime +]< / b> +文字;
message + =< / span>< / pre>;
chat + = message;
flag =!flag;
}
}
//DocumentApp.getUi()。alert(getTime() - time);

返回聊天;
}

我将重新执行 getChat( )方法来检查新消息,并且不会在每次刷新时加载每条消息。

解决方案

首先要摆脱错误信息是在 createChat 函数中创建UiApp,而不是 onOpen

我还使用了客户端处理程序来清除文本框,因为它更高效。以下是修改的代码: 至于你的第二个要求,我不是我确定我明白你想要做什么......你能更准确地解释你期望的行为吗? (这是比答案更多的评论,但我使用答案领域更易读)






编辑:我用这段代码玩了一小会儿,发现了一些东西,几乎可以工作......它仍然需要改进,但值得展示它是如何工作的。



我使用scriptProperties来存储对话的公共部分,我认为这是一个很好的方法,但它是知道何时更新其内容的问题。这里是我迄今为止的代码,我始终对任何建议/改进持开放态度。



代码已移除,下面是新版本






编辑2 :这是一个自动更新版本,效果很好,脚本会自动更新聊天区域一定的时间...如果没有活动,那么它停止并等待用户操作。请测试(使用2个帐户)并让我们知道您的想法。



注意我使用checkBox处理autoUpdate,为了测试目的,我保留它可见它可能被隐藏在最终版本中。



编辑3:添加了一条消息,警告用户何时离线+将textBox更改为彩色textArea允许更长的消息+条件来清除messageBox,以便警告消息不会进入对话。 (为了测试目的,将时间设置为非常短的值,将计数器值更改为您的需要) (){

if(getCurrentUser()==dev1|| getCurrentUser()==dev2){//用户标识隐藏隐私
DocumentApp.getUi() .createMenu('Chat')
.addItem('AutoColor','autoColor')
.addItem('Open Chat','createChatBox')
.addItem('Elements',' displayElements')//隐藏,因为它对于经常使用不重要
.addItem('MyID','showUser')
.addToUi();
} else {
DocumentApp.getUi()。createMenu('Chat')
.addItem('AutoColor','autoColor')
.addItem('Open Chat', 'createChatBox')
.addToUi();



函数createChatBox(){
ScriptProperties.setProperty('chatContent','');
var app = UiApp.createApplication()。setWidth(252);
app.setTitle(Chat Bar);
var vPanel = app.createVerticalPanel()。setId('chatPanel')。setWidth('100%');
var chatHandler = app.createServerHandler(sayChat)。addCallbackElement(vPanel);
var textArea = app.createTextArea()。setId('chatBox')。setName('chatBox').setReadOnly(true).setText('')。setSize('250px','450px');
var textBox = app.createTextArea()。setId('messageBox')。setName('messageBox')。setText('Start chat ...')。setPixelSize(250,100).setStyleAttributes({'padding': '5像素', '背景': '#FFFFCC'})addKeyPressHandler(chatHandler);
var clearTextBoxClientHandler = app.createClientHandler()。forTargets(textBox).setText('');
textBox.addClickHandler(clearTextBoxClientHandler);
var chatButton = app.createButton()。setId(sayButton)。setText(Say!)。addMouseUpHandler(chatHandler);
var chkHandler = app.createServerHandler('autoUpdate')。addCallbackElement(vPanel);
var chk = app.createCheckBox()。setId('chk')。addValueChangeHandler(chkHandler);
vPanel.add(textArea);
vPanel.add(textBox);
vPanel.add(chatButton);
vPanel.add(chk);
app.add(vPanel);
DocumentApp.getUi()。showSidebar(app);
返回应用程序;
}

函数sayChat(e){
var app = UiApp.getActiveApplication();
var user ='['+ getCurrentUser()+']:';
if(e.parameter.messageBox ==您因为没有输入任何东西超过5分钟而被置于离线状态,请点击此处刷新对话){
app .getElementById('messageBox')。setText(''); //清除messageBox
ScriptProperties.setProperty('chatTimer',0); //重置计数器
返回应用程序;
}
if(e.parameter.source =='messageBox'&& e.parameter.keyCode!= 13){return app};
var content = ScriptProperties.getProperty('chatContent');
ScriptProperties.setProperty('chatContent',content +\\\
+ user + e.parameter.messageBox)
app.getElementById(chatBox).setText(content +\\\
+ user + e.parameter.messageBox + '\\\
');
app.getElementById('messageBox')。setText('');
app.getElementById('chk')。setValue(true,true);
ScriptProperties.setProperty('chatTimer',0);
返回应用程序;


function autoUpdate(){
var app = UiApp.getActiveApplication();
var content = ScriptProperties.getProperty('chatContent');
var counter = Number(ScriptProperties.getProperty('chatTimer'));
++ counter;
if(counter> 20){
app.getElementById('chk')。setValue(false);
app.getElementById('messageBox')。setText(您因为没有输入任何东西超过5分钟而被放置在离线状态,请点击此处刷新对话);
返回应用程序;
}
ScriptProperties.setProperty('chatTimer',counter);
var content = ScriptProperties.getProperty('chatContent');
app.getElementById(chatBox)。setText(content +'*'); //这个*仅用于测试目的
app.getElementById('chk')。setValue(false);
Utilities.sleep(750);
app.getElementById('chk')。setValue(true,true).setText('timer ='+ counter);
返回应用程序;
}

function showUser(){
DocumentApp.getUi()。alert(Your userId is:+ getCurrentUser());


函数getCurrentUser(){
var email = Session.getEffectiveUser()。getEmail();
return email.substring(0,email.indexOf(@));
}


Below is old; look at the updated text at the bottom.

So my friends and I use google docs to communicate while in school, and we setup the challenge to create a working and "efficient" chat bar to communicate with better results. I've been around JavaScript for quite some time, but have never fooled around with Google Apps Script before. We are using the document app for our chats; the code I came up with is as below, but I have a few problems with it:

  1. Errors when a user closes it, then goes to Chat -> Open Chat in the toolbar to re-open, saying, "Error encountered: An unexpected error occurred"; does not specify a line or reason
  2. Needs a hidden element somewhere in the document which can allow users to see what others have typed, but that they can't edit without using the chat box (would add event listener to update chat box when text is ammended)


//Main function, ran when the document first opens.
function onOpen() {
    var app = UiApp.createApplication(); //Create a Ui App to use for the chat bar

    if(getCurrentUser()=="dev1"||getCurrentUser()=="dev2"){ //user-Id's hidden for privacy
        DocumentApp.getUi().createMenu('Chat')
          .addItem('AutoColor', 'autoColor')
          .addItem('Open Chat', 'createChatBox')
          .addItem('Elements', 'displayElements') //Hidden as it is not important for regular use
          .addItem('MyID', 'showUser')
          .addToUi();
    }else{
        DocumentApp.getUi().createMenu('Chat')
          .addItem('AutoColor', 'autoColor')
          .addItem('Open Chat', 'createChatBox')
          .addToUi();
   }
}

//Creates and returns the chats GUI
function createChatBox(){
    var app = UiApp.getActiveApplication()
    app.setTitle("Chat Bar (not yet working)");
    var vPanel = app.createVerticalPanel().setId('chatPanel').setWidth('100%');
    var textArea = app.createTextArea().setId('chatBox').setName('chatBox').setReadOnly(true).setText('').setSize('250px', '450px'); //Read only so they can not edit the text, even if it won't affect overall chat
    var textBox = app.createTextBox().setId('messageBox').setName('messageBox').setText('Words');
    var chatHandler = app.createServerHandler("sayChat").addCallbackElement(textArea).addCallbackElement(textBox);
    var chatButton = app.createButton().setId("sayButton").setText("Say!").addMouseUpHandler(chatHandler);

    vPanel.add(textArea);
    vPanel.add(textBox);
    vPanel.add(chatButton);

    app.add(vPanel);
    DocumentApp.getUi().showSidebar(app);
    return app;
}

//The event handler for when the "Say!" (post) button is pressed. Is probably where the conflict stems from.
function sayChat(eventInfo){
    var app = UiApp.getActiveApplication();
    var parameter = eventInfo.parameter;

    app.getElementById("chatBox").setText(parameter.chatBox+"["+getCurrentUser()+"]: "+parameter.messageBox);
    app.getElementById("messageBox").setText("");

    return app;
}

//A debug function and a function to tell you the unique part of your email (useless, really)
function showUser(){
    DocumentApp.getUi().alert("Your userId is: "+getCurrentUser());
}

//Returns the unique part of a person's email; if their email is "magicuser@gmail.com", it returns "magicuser"
function getCurrentUser(){
    var email = Session.getActiveUser().getEmail();
    return email.substring(0,email.indexOf("@"));
}
//The Auto-color and displayElements methods are hidden as they contain other user-info. They both work as intended and are not part of the issue.

I do not need someone to rewrite the code (although that'd be greatly appreciated!), but instead point out what I'm doing wrong or suggest something to change/add.

Last, before you suggest it, the google docs chat does not work with our computers. It is not the fault of the document, but probably a compatability error with our browser. It is because of this issue that we are going through this fun yet hasty process of making our own chat method.

Update

I decided to give up on my version of the chat using pure Google Apps Script and help improve my friends version using both G-A-S and HTML. I added image thumbnail/linking support with command /img or /image, along with improved time and counter, and some other behind the scenes updates. Here is a quick screenshot of it:

Magnificent chat programmed from scratch, and no buggy update methods, just a casual refresh database to check for messages and set HTML text-area text. No more buggy getText methods. For each new message in the database, whether targeted toward the user or toward everyone in the chat, we load all the database messages up to a limit (50 messages at a time), then display them. The use of HTML in the messages is key to its appearence and features, such as images.

function getChat() {
  var chat = "";
  var time = getTime();

  var username = getCurrentUsername();

  var db = ScriptDb.getMyDb();
  var query = db.query({time : db.greaterThan(getJoinTime())}).sortBy('time', db.DESCENDING).limit(50);

  var flag = query.getSize() % 2 != 0;

  while(query.hasNext()) {
    var record = query.next();
    if(record.showTo == "all" || record.showTo == getCurrentUsername()) {
      var text = record.text;
      for(var i = 0; i < text.split(" ").length; i++) {
        var substr = text.split(" ")[i];
        if(substr.indexOf("http://") == 0 || substr.indexOf("https://") == 0) {
          text = text.replace(substr, "<a href='" + substr + "'>" + substr + "</a>");
        }
      }
      var message = "<pre style='display:inline;'><span class='" + (flag? "even" : "odd") + "'><b>[" + record.realTime + "]</b>" + text;
      message += "</span></pre>";
      chat += message;
      flag = !flag;
    }
  }
  //DocumentApp.getUi().alert(getTime() - time);

  return chat;
}

I am going to re-do his getChat() method to only check for new messages, and not load every message at each refresh.

解决方案

First thing to to to get rid of your error message is to create the UiApp in the createChat function instead of onOpen.

I also used a client handler to clear the textBox because it's just more efficient. Here is the modified code :

code removed see updates below

As for your second request I'm not sure I understand exactly what you want to do... could you explain more precisely the behavior you expect ? (this is more a comment than an answer but I used the "answer field" to be more readable)


EDIT : I played a little with this code and came to something that -almost- works... it still needs to be improved but it's worth showing how it works.

I used scriptProperties to store the common part of the conversation, I think that's a good approach but the issue it to know when to update its content. Here is the code I have so far, I keep being open to any suggestion/improvement of course.

code removed, new version below


EDIT 2 : here is a version with an auto update that works quite good, the script updates the chat area automatically for a certain time... if no activity then it stops and wait for a user action. please test (using 2 accounts) and let us know what you think.

note I used a checkBox to handler the autoUpdate, I keep it visible for test purpose but of course it could be hidden in a final version.

EDIT 3 : added a message to warn the user when he's been put offline + changed textBox to colored textArea to allow for longer messages + condition to clear the messageBox so that the warning message doesn't go in the conversation. (set the time out to a very short value for test purpose, change the counter value to restore to your needs)

function onOpen() {

    if(getCurrentUser()=="dev1"||getCurrentUser()=="dev2"){ //user-Id's hidden for privacy
        DocumentApp.getUi().createMenu('Chat')
          .addItem('AutoColor', 'autoColor')
          .addItem('Open Chat', 'createChatBox')
          .addItem('Elements', 'displayElements') //Hidden as it is not important for regular use
          .addItem('MyID', 'showUser')
          .addToUi();
    }else{
        DocumentApp.getUi().createMenu('Chat')
          .addItem('AutoColor', 'autoColor')
          .addItem('Open Chat', 'createChatBox')
          .addToUi();
   }
}

function createChatBox(){
  ScriptProperties.setProperty('chatContent','');
  var app = UiApp.createApplication().setWidth(252);
  app.setTitle("Chat Bar");
  var vPanel = app.createVerticalPanel().setId('chatPanel').setWidth('100%');
  var chatHandler = app.createServerHandler("sayChat").addCallbackElement(vPanel);
  var textArea = app.createTextArea().setId('chatBox').setName('chatBox').setReadOnly(true).setText('').setSize('250px', '450px');
  var textBox = app.createTextArea().setId('messageBox').setName('messageBox').setText('Start chat...').setPixelSize(250,100).setStyleAttributes({'padding':'5px','background':'#ffffcc'}).addKeyPressHandler(chatHandler);
  var clearTextBoxClientHandler = app.createClientHandler().forTargets(textBox).setText('');
  textBox.addClickHandler(clearTextBoxClientHandler);
  var chatButton = app.createButton().setId("sayButton").setText("Say!").addMouseUpHandler(chatHandler);
  var chkHandler = app.createServerHandler('autoUpdate').addCallbackElement(vPanel);
  var chk = app.createCheckBox().setId('chk').addValueChangeHandler(chkHandler);
  vPanel.add(textArea);
  vPanel.add(textBox);
  vPanel.add(chatButton);
  vPanel.add(chk);
  app.add(vPanel);
  DocumentApp.getUi().showSidebar(app);
  return app;
}

function sayChat(e){
  var app = UiApp.getActiveApplication();  
  var user = '['+getCurrentUser()+'] : ';
  if(e.parameter.messageBox=="You have been put offline because you didn't type anything for more than 5 minutes..., please click here to refresh the conversation"){
    app.getElementById('messageBox').setText('');// clear messageBox
    ScriptProperties.setProperty('chatTimer',0);// reset counter
    return app;
  }
  if(e.parameter.source=='messageBox'&&e.parameter.keyCode!=13){return app};
  var content = ScriptProperties.getProperty('chatContent');
  ScriptProperties.setProperty('chatContent',content+"\n"+user+e.parameter.messageBox)
  app.getElementById("chatBox").setText(content+"\n"+user+e.parameter.messageBox+'\n');
  app.getElementById('messageBox').setText('');
  app.getElementById('chk').setValue(true,true);
  ScriptProperties.setProperty('chatTimer',0);
  return app;
}

function autoUpdate(){
  var app = UiApp.getActiveApplication();
  var content = ScriptProperties.getProperty('chatContent');
  var counter = Number(ScriptProperties.getProperty('chatTimer'));
  ++counter;
  if(counter>20){
    app.getElementById('chk').setValue(false);
    app.getElementById('messageBox').setText("You have been put offline because you didn't type anything for more than 5 minutes..., please click here to refresh the conversation");
    return app;
  }
  ScriptProperties.setProperty('chatTimer',counter);
  var content = ScriptProperties.getProperty('chatContent');
  app.getElementById("chatBox").setText(content+'*'); // the * is there only for test purpose
  app.getElementById('chk').setValue(false);
  Utilities.sleep(750);
  app.getElementById('chk').setValue(true,true).setText('timer = '+counter);
  return app;
}

function showUser(){
  DocumentApp.getUi().alert("Your userId is: "+getCurrentUser());
}

function getCurrentUser(){
  var email = Session.getEffectiveUser().getEmail();
  return email.substring(0,email.indexOf("@"));
}

这篇关于创建一个基本的聊天栏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆