Home   Archive   Permalink



Enhanced ftp chat room

As a bit of a demo at work, I want to modify Nick's ftp chat room:
    
http://business-programming.com/business_programming.html#section-5.14
    
to add a VID front end. I know how to put the entire chat history into one scrolling text area, but I thought it would be a nice touch if I could separate and color-code the chat entries for different people, each person having his own color, sort of like the altme interface. I can't quite see how that might be done.
    
I could use a list and put each entry into a row of the list, but each row would have to be the same size, and some chat entries might be too long.
    
I know, in theory, how to make a scrolling sub-face, and I could put each chat entry into its own text area on the scrolling sub-face, and color-code each, but I don't know how to translate the size of the text into the size of the text area that would hold it.    
    
If there are other options, I am at this time unable to imagine them. Clearly it can be done because altme does it.    
    
Does anyone have any guidance for me? I am thinking of just a direction, not necessarily the specifics.
    
Thank you.

posted by:   Steven White       12-Jan-2017/9:23:38-8:00



AltMe looks to me to be a scrollable panel containing separate textboxes for the chat texts (and usernames and times).
I think you have to work it out in that direction.

posted by:   iArnold       12-Jan-2017/10:36:53-8:00



A scrollable panel of text boxes makes sense, and since I have made a scrollable panel of buttons, I do know how to do that in theory. What I don't quite see is that each text box is a different size, a size that holds all the text but not bigger. So if I have a string of text for a single chat message, and I know how long it is, how do I calculate how big a text box I need to hold it?    
    
Maybe the answer is something like this:
    
1. Decide on the X dimension of the text box I will use.
    
2. Discover by trial and error how many characters fit in single line of X pixels across.
    
3. Divide the total number of characters in a chat message by the characters per line to decide how many lines a chat entry will take.
    
4. Assume, based on a bit of trial and error, that a single line needs, maybe, 16 pixels in the Y direction.
    
5. Calculate the Y dimension of the text box as the number of lines times the number of pixels per line.
    
6. For each chat message, generate a box to hold it with the calculated X and Y dimensions.    
    
7. Set the color of the box based on the author of the chat message.
    
8. Run the generated VID code for for the panel of text boxes through the layout function.
    
9. Put the generated layout into the scrollable panel.    
    
10. Details left as an exercise for the reader, as they used to say in the math books.
    
Maybe I'll hack at that approach a bit unless anybody has a better idea. If I can get it to work, it might boot me out of Beginnerland.
    
Thank you.


posted by:   Steven White       12-Jan-2017/11:58:32-8:00



One issue that might arise is mentioned on
http://www.rebol.net/cookbook/recipes/0016.html

posted by:   Ned K       13-Jan-2017/1:01:03-8:00



And maybe use the Draw dialect to color the text.    
    
Can't recall if RebGUI from Dobeash.com has coloured text, it might.

posted by:   Ned K       13-Jan-2017/1:07:43-8:00



Hi Steve,
    
Everything you need to make the colored text display is described at http://business-programming.com/business_programming.html#section-16.21 in the section titled '16.21.2 Creating Home Made Multi Column Data Grids'. If I get a moment, I'll post a solution.

posted by:   Nick       13-Jan-2017/13:46:05-8:00



I edited the first example there to demonstrate how to color different lines of text in a scrolling display:
    
R E B O L []
x: copy [] for i 1 179 1 [append x reduce [i random "abcdefghijklmnop"]]
grid: copy [across space 0] ; the GUI block containing the grid of fields
foreach [num name] x [
    append grid compose [
     text (form num)
     text (name) (random 255.255.255)
     return
    ]
]
view center-face layout [
    across
    g: box 150x200 with [pane: layout/tight grid pane/offset: 0x0]
    scroller [g/pane/offset/y: g/size/y - g/pane/size/y * value show g]
]

posted by:   Nick       13-Jan-2017/14:08:01-8:00



You may also want to start with a simpler chat example and build up from there. This FTP chat example is from http://re-bol.com/short_rebol_examples.r (there's also a CGI version which can run on any Apache server (including cheap shared hosting providers) and connect with this app):
    
R E B O L [title: "Group Text Chat, Desktop App"]
url: ftp://user:pass@site.com/public_html/chat.txt
write/append url ""
name: copy ask "^LName: "
forever [
     notes: copy read url
     message: ask rejoin [newpage notes "Message: "]
     if message = "erase" [write url ""]
     if message <> "" [
         write/append url rejoin [
             now " (" name "): " message "^/^/"
         ]
     ]
]

posted by:   Nick       13-Jan-2017/14:11:28-8:00



No time to integrate the examples at the moment, but if you run the chat script:
    
R E B O L [title: "Group Text Chat, Desktop App"]
; url: ftp://user:pass@site.com/public_html/chat.txt
url: %chat.txt ; local file for demonstration
write/append url ""
name: copy ask "^LName: "
forever [
     notes: copy read url
     message: ask rejoin [newpage notes "Message: "]
     if message = "erase" [write url ""]
     if message <> "" [
         write/append url rejoin [
             now " (" name "): " message "^/^/"
         ]
     ]
]
    
Then run this code, you'll see the working code you need. You could eliminate the need to parse the messages if you save them in a block format, instead of in a long string of text:
    
x: read/lines url
remove-each line x [line = ""]
grid: copy [across space 0]
foreach line x [
    parse line [thru "(" copy name to ")"]
    msg: find line ": "
    if not clr: select ["Nick" red "John" orange] name [clr: black]
    append grid compose [
     text (name)
     text (msg) (clr)
     return
    ]
]
view center-face layout [
    across
    g: box 150x200 with [pane: layout/tight grid pane/offset: 0x0]
    scroller [g/pane/offset/y: g/size/y - g/pane/size/y * value show g]
]

posted by:   Nick       13-Jan-2017/14:40:58-8:00



Here's a quick hack that should get you going:
    
R E B O L [title: "Colorized Group Text Chat, Desktop App"]
; url: ftp://user:pass@site.com/public_html/chat.txt
url: %chat.txt ; local file for demonstration
write/append url ""
grid: copy [across space 0]
w: view/new layout [
     n: field "Name"
     m: field "Message"
     btn "Send" [
         if m/text = "erase" [write url ""]
         if m/text <> "" [
             write/append url rejoin [
                 now " (" n/text "): " m/text "^/^/"
             ]
         ]
     ]
     across
     g: box 500x200 with [pane: layout/tight grid pane/offset: 0x0]
     scroller [g/pane/offset/y: g/size/y - g/pane/size/y * value show g]
]
forever [
     x: read/lines url
     remove-each line x [line = ""]
     reverse x
     u: g/pane/offset/y
     grid: copy [across space 0]
     foreach line x [
         parse line [thru "(" copy name to ")"]
         msg: copy find line ": "
         if not clr: select ["Nick" red "John" orange] name[clr: black]
         append grid compose [
             text (name)
             text (msg) (clr)
             return
         ]
     ]
     loop 15 [append grid [text "" text "" return]]
     g/pane: layout/tight grid    
     g/pane/offset/y: u show g
     if not viewed? w[q] view w wait 2
]

posted by:   Nick       13-Jan-2017/22:12:34-8:00



Cleaned up a bit:
    
R E B O L [title: "Colorized Group Text Chat, Desktop App"]
write/append url: %chat.db "" ;ftp://user:pass@site.com/public_html/chat.db
colors: ["Nick" red "John" orange] ; manage this however you prefer (GUI)
w: view/new layout [
     n: field "Name"
     m: field "Message"
     btn "Send" [
         if m/text <> "" [
             write/append url reduce [
                 mold now mold n/text mold m/text
             ] focus m
         ]
     ]
     across
     g: box 550x200 with [pane: layout/tight grid:[] pane/offset: 0x0]
     scroller [g/pane/offset/y: g/size/y - g/pane/size/y * value show g]
]
forever [
     x: reverse load url u: g/pane/offset/y grid: copy [across space 0]
     foreach [msg nm dt] x [
         if not clr: select colors nm [clr: black]
         append grid compose [text 80 (nm) text (msg) (clr) return]
     ]
     loop 15 [append grid [text "" text "" return]]
     g/pane: layout/tight grid    
     g/pane/offset/y: u show g
     if not viewed? w[q] view w wait 2
]

posted by:   Nick       14-Jan-2017/9:15:04-8:00



As you can see in the script above, the text style will automatically wrap to multiple lines if its horizontal size is constrained, so your biggest potential difficulty is handled:
    
view layout [size 200x400 text {djjixikkskjsjsjxxdjjss dddjdjsisksdjdjdjd dkdidkjdk djjdiidiieie d djdjejid jdkikkdd dkdidiidds ddiididiodooiji djdidiids eididi ddiidddiidi djidid}]
    
view layout [text {djjixikkskjsjsjxxdjjss dddjdjsisksdjdjdjd dkdidkjdk djjdiidiieie d djdjejid jdkikkdd dkdidiidds ddiididiodooiji djdidiids eididi ddiidddiidi djidid}]

posted by:   Nick       17-Jan-2017/6:41:19-8:00



Good God in Heaven, I didn't expect you to write it for me. But thank you. Your version might be a bit cleaner that what I had in mind, so I might go with that. I did make some progress over the past weekend, but it was a bit more involved than just appending a text field, especially if the text field will expand as needed. As for the idea of some sort of divider between entries, the following modification of one of your code lines seems to do the job:
    
append grid compose [text 80 (nm) text (msg) (clr) return bar 550 return]
    
I am assembling, for my soon-to-be-former co-workers, a little web site of REBOL code and documentation, sort of a dumping ground for things I have learned about it to help them with some things I probably will leave behind. Similar to your documentation, but not as extensive, and trying not to overlap. If you don't mind, I might add to it a GUI version of ftp chat, once I get it going. With credits of course, and sanitized of site-specific information.
    
Thank you.

posted by:   Steven White       17-Jan-2017/11:13:11-8:00



It was no biggie - just copy/pasted some short examples with minor edits, then a few minutes to clean it up, in between appointments and before bed. Didn't want you to waste time going down a bad path, and perhaps this example is interesting to others :)

posted by:   Nick       17-Jan-2017/23:54:22-8:00



BTW Steve, if your office needs help after you leave, feel free to give them my contact info.

posted by:   Nick       17-Jan-2017/23:56:54-8:00