Moar progress, sorry for no commit message
This commit is contained in:
parent
b9e9c58848
commit
efbf4ba81d
11 changed files with 434 additions and 91 deletions
|
@ -36,7 +36,10 @@ OTHER_FILES += qml/harbour-weechatrelay.qml \
|
|||
qml/js/debug.js \
|
||||
qml/js/buffers.js \
|
||||
qml/js/eventqueue.js \
|
||||
qml/js/uniqid.js
|
||||
qml/js/uniqid.js \
|
||||
qml/pages/BufferView.qml \
|
||||
qml/js/config.js \
|
||||
qml/pages/BufferList.qml
|
||||
|
||||
HEADERS += \
|
||||
src/relayconnection.h \
|
||||
|
|
|
@ -10,24 +10,75 @@
|
|||
|
||||
.pragma library
|
||||
|
||||
.import QtQuick 2.0 as QQ
|
||||
|
||||
.import "eventqueue.js" as EQ
|
||||
.import "moment.js" as M
|
||||
.import "debug.js" as D
|
||||
|
||||
function Buffer(id) {
|
||||
this.id = id;
|
||||
this.window = null;
|
||||
var _textListComponent = Qt.createComponent('../pages/TextListComponent.qml');
|
||||
|
||||
function Buffer(pointer, number, name, title) {
|
||||
this.pointer = pointer;
|
||||
this.number = number;
|
||||
this.name = name;
|
||||
this.title = title;
|
||||
|
||||
this.textList = _textListComponent.createObject(_parentPage);
|
||||
|
||||
// Add line to this buffer
|
||||
this.add = function(moment, str) {
|
||||
this.textList.add(moment, str);
|
||||
};
|
||||
}
|
||||
|
||||
// Dict of buffers, pointer as key, for fast referencing
|
||||
var _buffers = {};
|
||||
|
||||
// List of all buffers for easy iteration, will be sorted ascending
|
||||
// according to buffer number whenever requested
|
||||
var _buffersList = [];
|
||||
|
||||
// Page that will own all of our textlistcomponents
|
||||
var _parentPage = null;
|
||||
|
||||
|
||||
function init() {
|
||||
EQ.addHandler("__weecrapp_ready", connected);
|
||||
EQ.addHandler("_buffer_line_added", lineAdded);
|
||||
}
|
||||
|
||||
// Set the given page to be used for the core buffer
|
||||
// This is so that we can reuse the debug page as the
|
||||
// WeeChat core buffer
|
||||
function setDebugPage(page) {
|
||||
_parentPage = page;
|
||||
|
||||
var pointer = '0';
|
||||
var buffer = new Buffer(pointer, 1, 'weechat', 'Debug/core');
|
||||
_buffers[pointer] = buffer;
|
||||
_buffersList.push(buffer);
|
||||
D.setDebugBuffer(buffer);
|
||||
page.changeBuffer(buffer);
|
||||
}
|
||||
|
||||
function getBuffer(i) {
|
||||
if (_buffers.hasOwnProperty(i)) {
|
||||
return _buffers[i];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Return bufferlist sorted by buffer number
|
||||
function getBuffersByNumber() {
|
||||
return _buffersList;
|
||||
}
|
||||
|
||||
|
||||
function connected() {
|
||||
EQ.command("hdata buffer:gui_buffers(*) name,number", bufferListData);
|
||||
D.d("Fetching all buffers...");
|
||||
EQ.command("hdata buffer:gui_buffers(*) full_name,short_name,number,type,title", bufferListData);
|
||||
EQ.command("sync");
|
||||
}
|
||||
|
||||
|
@ -38,18 +89,51 @@ function disconnected() {
|
|||
|
||||
|
||||
function bufferListData(data) {
|
||||
D.d("Got buffer list data:");
|
||||
|
||||
data = data[0];
|
||||
var buffers = data.objectSets;
|
||||
|
||||
for (var i = 0; i < buffers.length; ++i) {
|
||||
D.d(buffers[i].number + " " + buffers[i].name);
|
||||
var pointer = buffers[i]['__path'][0];
|
||||
var number = buffers[i].number;
|
||||
var name = buffers[i].short_name;
|
||||
var title = buffers[i].title;
|
||||
var buffer = null;
|
||||
|
||||
//EQ.command("sync " + buffers[i].name + " buffer,nicklist");
|
||||
if (buffers[i].type !== 0) {
|
||||
// Currently only sync IRC buffers
|
||||
continue;
|
||||
}
|
||||
|
||||
// If this buffer is the core, merge it to the debug buffer
|
||||
if (_parentPage !== null && number === 1 && buffers[i].full_name === 'core.weechat') {
|
||||
_buffers[pointer] = _buffers['0'];
|
||||
buffer = _buffers['0'];
|
||||
buffer.pointer = pointer;
|
||||
buffer.name = name;
|
||||
buffer.title = title;
|
||||
buffer.number = number;
|
||||
}
|
||||
else {
|
||||
buffer = new Buffer(pointer, number, name, title);
|
||||
_buffers[pointer] = buffer;
|
||||
_buffersList.push(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
_sortBuffersList();
|
||||
}
|
||||
|
||||
function bufferSyncData(data) {
|
||||
// A new line was added to a buffer
|
||||
function lineAdded(data) {
|
||||
data = data[0].objectSets[0];
|
||||
|
||||
var buffer = data.buffer;
|
||||
var date = M.moment(data.date);
|
||||
_buffers[buffer].add(date, data.message);
|
||||
}
|
||||
|
||||
function _sortBuffersList() {
|
||||
_buffersList.sort(function (a, b) {
|
||||
return a.number - b.number;
|
||||
});
|
||||
}
|
||||
|
|
62
qml/js/config.js
Normal file
62
qml/js/config.js
Normal file
|
@ -0,0 +1,62 @@
|
|||
.pragma library
|
||||
|
||||
/*
|
||||
* © Mikko Ahlroth 2014
|
||||
* WeeCRApp is open source software. For licensing information, please check
|
||||
* the LICENCE file.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file contains the configuration settings of the app (both hardcoded
|
||||
* and user-settable) and the API to change them. Connection-specific settings
|
||||
* are handled in AddConnection.qml.
|
||||
*/
|
||||
|
||||
.import "storage.js" as S
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Constants that cannot be changed
|
||||
*/
|
||||
|
||||
// Regex to match weechat version strings
|
||||
var SUPPORTED_WEECHAT_VERSIONS = /^(?:0\.4)|(?:1\.0)/;
|
||||
|
||||
|
||||
/*
|
||||
* All settings and their defaults
|
||||
*/
|
||||
|
||||
var _s = {
|
||||
timestamp_format: 'HH:mm:ss'
|
||||
};
|
||||
|
||||
var _init = false;
|
||||
|
||||
// Load all settings on first config access
|
||||
if (!_init) {
|
||||
_loadConfig();
|
||||
}
|
||||
|
||||
|
||||
function set(key, value) {
|
||||
_s[key] = value;
|
||||
|
||||
var db = S.connect();
|
||||
S.storeSetting(db, key, value);
|
||||
}
|
||||
|
||||
function get(key) {
|
||||
return _s[key];
|
||||
}
|
||||
|
||||
|
||||
|
||||
function _loadConfig() {
|
||||
var db = S.connect();
|
||||
|
||||
for (var key in _s) {
|
||||
var val = S.readSetting(db, key, _s[key]);
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
.import "debug.js" as D
|
||||
.import "eventqueue.js" as EQ
|
||||
.import "buffers.js" as B
|
||||
.import "config.js" as C
|
||||
|
||||
/*
|
||||
* © Mikko Ahlroth 2014
|
||||
|
@ -25,6 +26,7 @@ var ps = null; // The PageStack
|
|||
|
||||
// Views
|
||||
var debugViewPage = null;
|
||||
var bufferListPage = null;
|
||||
var sslVerifyDialog = null;
|
||||
|
||||
|
||||
|
@ -40,11 +42,20 @@ function init(connectionHandler, pageStack) {
|
|||
});
|
||||
|
||||
// Wait for init reply to let system know it's ready to send
|
||||
EQ.addHandler("init", function() {
|
||||
EQ.addHandler("init", function(data) {
|
||||
// Check the received version, it must match the minimum supported
|
||||
var version = data[0]['value'];
|
||||
if (!C.SUPPORTED_WEECHAT_VERSIONS.test(version)) {
|
||||
D.d("This version of WeeChat is not supported.");
|
||||
disconnect();
|
||||
}
|
||||
else {
|
||||
D.d("Welcome to WeeChat " + version);
|
||||
EQ.handleEvent("__weecrapp_ready");
|
||||
});
|
||||
}
|
||||
}, true);
|
||||
|
||||
B.init();
|
||||
B.init(ps);
|
||||
}
|
||||
|
||||
|
||||
|
@ -94,8 +105,9 @@ function onSslError(errorStrings,
|
|||
// Public API
|
||||
|
||||
function connect(connObj) {
|
||||
debugViewPage = ps.replace("../pages/DebugView.qml");
|
||||
D.setDebugPage(debugViewPage);
|
||||
debugViewPage = ps.replace("../pages/BufferView.qml");
|
||||
bufferListPage = ps.pushAttached("../pages/BufferList.qml");
|
||||
B.setDebugPage(debugViewPage);
|
||||
D.d("Connecting...");
|
||||
|
||||
var connType = (connObj.type === "ssl")
|
||||
|
@ -158,6 +170,7 @@ function clearConnection() {
|
|||
connection = null;
|
||||
connected = false;
|
||||
handler.clearData();
|
||||
ps.replace("../pages/ConnectionList.qml");
|
||||
}
|
||||
|
||||
// Send a command to the WeeChat server
|
||||
|
|
|
@ -6,21 +6,23 @@
|
|||
|
||||
.pragma library
|
||||
|
||||
.import "moment.js" as M
|
||||
|
||||
var _page = null;
|
||||
// Buffer to push messages to
|
||||
var _buffer = null;
|
||||
|
||||
// Write a line to the debug view (will go to console if debug view isn't open)
|
||||
function debug(str) {
|
||||
if (_page != null) {
|
||||
_page.display(str);
|
||||
if (_buffer !== undefined && _buffer !== null) {
|
||||
_buffer.add(M.moment(), str);
|
||||
}
|
||||
else {
|
||||
console.log(str);
|
||||
}
|
||||
}
|
||||
|
||||
function setDebugPage(o) {
|
||||
_page = o;
|
||||
function setDebugBuffer(o) {
|
||||
_buffer = o;
|
||||
}
|
||||
|
||||
|
||||
|
@ -28,19 +30,34 @@ function d(str) {
|
|||
debug(str);
|
||||
}
|
||||
|
||||
// Go straight to console
|
||||
function c(str) {
|
||||
console.log(str);
|
||||
}
|
||||
|
||||
function e(o) {
|
||||
enumerate(o);
|
||||
}
|
||||
|
||||
function enumerate(o) {
|
||||
d("Enumerating " + o);
|
||||
d("---");
|
||||
c("Enumerating object");
|
||||
c("---");
|
||||
|
||||
var keys = Object.keys(o);
|
||||
|
||||
for (var i = 0; i < keys.length; ++i) {
|
||||
d(keys[i] + ": " + o[keys[i]]);
|
||||
var val = o[keys[i]];
|
||||
|
||||
if (typeof val === 'undefined') {
|
||||
c(keys[i] + ": undefined");
|
||||
}
|
||||
else if (val === null) {
|
||||
c(keys[i] + ": null");
|
||||
}
|
||||
else {
|
||||
c(keys[i] + ": " + val);
|
||||
}
|
||||
}
|
||||
|
||||
d("");
|
||||
c("");
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ function command(command, callback) {
|
|||
var id = UID.get();
|
||||
command = "(" + id + ") " + command;
|
||||
|
||||
D.d("Adding handler for " + id);
|
||||
//D.d("Adding handler for " + id);
|
||||
addHandler(id, callback, true);
|
||||
}
|
||||
|
||||
|
|
108
qml/pages/BufferList.qml
Normal file
108
qml/pages/BufferList.qml
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* © Mikko Ahlroth 2014
|
||||
* WeeCRApp is open source software. For licensing information, please check
|
||||
* the LICENCE file.
|
||||
*/
|
||||
|
||||
import QtQuick 2.0
|
||||
import Sailfish.Silica 1.0
|
||||
|
||||
import "../js/buffers.js" as B
|
||||
|
||||
Page {
|
||||
id: bufferListPage
|
||||
|
||||
onVisibleChanged: bufferList.updateList();
|
||||
|
||||
SilicaListView {
|
||||
id: bufferList
|
||||
model: ListModel { id: bufferListModel }
|
||||
anchors.fill: parent
|
||||
|
||||
function updateList() {
|
||||
var buffers = B.getBuffersByNumber();
|
||||
|
||||
for (var i = 0; i < buffers.length; ++i) {
|
||||
bufferListModel.append({
|
||||
number: buffers[i].number,
|
||||
name: buffers[i].name
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
header: PageHeader {
|
||||
width: bufferList.width
|
||||
title: "Buffers"
|
||||
}
|
||||
|
||||
delegate: ListItem {
|
||||
id: listItem
|
||||
contentHeight: Theme.itemSizeSmall
|
||||
menu: contextMenu
|
||||
ListView.onRemove: animateRemoval(listItem);
|
||||
|
||||
function close() {
|
||||
remorseAction("Closing buffer",
|
||||
function() {
|
||||
// TODO Close buffer forrealz
|
||||
console.log("Closed " + name + "!");
|
||||
});
|
||||
}
|
||||
|
||||
Row {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.paddingLarge
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
|
||||
Label {
|
||||
text: number
|
||||
color: listItem.highlighted ? Theme.secondaryHighlightColor
|
||||
: Theme.secondaryColor;
|
||||
|
||||
width: parent.width / 7
|
||||
horizontalAlignment: Qt.AlignRight
|
||||
}
|
||||
|
||||
Label {
|
||||
text: name
|
||||
color: listItem.highlighted ? Theme.highlightColor
|
||||
: Theme.primaryColor;
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: contextMenu
|
||||
ContextMenu {
|
||||
MenuItem {
|
||||
text: "Close"
|
||||
onClicked: close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
console.log(name + " clicked!");
|
||||
}
|
||||
}
|
||||
|
||||
VerticalScrollDecorator { flickable: connectionList }
|
||||
|
||||
|
||||
PullDownMenu {
|
||||
MenuItem {
|
||||
text: "???"
|
||||
}
|
||||
}
|
||||
|
||||
PushUpMenu {
|
||||
MenuItem {
|
||||
text: "Go to top"
|
||||
onClicked: bufferList.scrollToTop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
101
qml/pages/BufferView.qml
Normal file
101
qml/pages/BufferView.qml
Normal file
|
@ -0,0 +1,101 @@
|
|||
import QtQuick 2.0
|
||||
import Sailfish.Silica 1.0
|
||||
import "."
|
||||
|
||||
import "../js/debug.js" as D
|
||||
import "../js/connection.js" as C
|
||||
import "../js/moment.js" as M
|
||||
import "../js/buffers.js" as B
|
||||
|
||||
Page {
|
||||
id: bufferViewPage
|
||||
|
||||
property bool isConnected: false;
|
||||
property string pointer: "";
|
||||
property int number: 0;
|
||||
property string name: "";
|
||||
|
||||
function setTitle(str) {
|
||||
topic.title = str;
|
||||
}
|
||||
|
||||
function connected() {
|
||||
isConnected = true;
|
||||
}
|
||||
|
||||
function disconnected() {
|
||||
isConnected = false;
|
||||
}
|
||||
|
||||
function changeBuffer(buffer) {
|
||||
var textList = buffer.textList;
|
||||
|
||||
// Replace current list with new list
|
||||
textListItem = textList;
|
||||
textListItem.parent = mainFlickable;
|
||||
// HOW DO I SHOT WEB
|
||||
//mainFlickable.children.push(textListItem);
|
||||
//textListItem.anchors.top = topic.bottom;
|
||||
//textListItem.anchors.bottom = inpuRow.top;
|
||||
textListItem.width = textListItem.parent.width;
|
||||
textListItem.clip = true;
|
||||
|
||||
topic.title = buffer.title;
|
||||
}
|
||||
|
||||
SilicaFlickable {
|
||||
id: mainFlickable
|
||||
anchors.fill: parent
|
||||
|
||||
PageHeader {
|
||||
id: topic
|
||||
title: "Debug"
|
||||
anchors.top: parent.top
|
||||
}
|
||||
|
||||
Item {
|
||||
id: textListItem
|
||||
}
|
||||
|
||||
Row {
|
||||
id: inputRow
|
||||
|
||||
width: parent.width
|
||||
anchors.bottom: parent.bottom
|
||||
|
||||
TextField {
|
||||
id: inputField
|
||||
width: parent.width
|
||||
anchors.bottom: parent.bottom
|
||||
|
||||
placeholderText: "Type here"
|
||||
|
||||
EnterKey.enabled: text.length > 0
|
||||
//EnterKey.iconSource: "image://theme/icon-m-send"
|
||||
EnterKey.onClicked: {
|
||||
var buffer = B.getBuffer(inputField.text);
|
||||
if (buffer !== null) {
|
||||
changeBuffer(buffer);
|
||||
}
|
||||
|
||||
inputField.text = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PushUpMenu {
|
||||
MenuItem {
|
||||
text: isConnected? "Disconnect" : "Close";
|
||||
onClicked: {
|
||||
if (isConnected) {
|
||||
C.disconnect();
|
||||
isConnected = false;
|
||||
}
|
||||
else {
|
||||
C.clearConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,15 +15,16 @@ Page {
|
|||
|
||||
onVisibleChanged: connectionList.updateList();
|
||||
|
||||
PageHeader {
|
||||
title: "Connections"
|
||||
}
|
||||
|
||||
SilicaListView {
|
||||
id: connectionList
|
||||
model: ListModel { id: connectionModel }
|
||||
anchors.fill: parent
|
||||
|
||||
header: PageHeader {
|
||||
width: connectionList.width
|
||||
title: "Connections"
|
||||
}
|
||||
|
||||
delegate: ListItem {
|
||||
id: listItem
|
||||
contentHeight: Theme.itemSizeLarge
|
||||
|
@ -45,7 +46,7 @@ Page {
|
|||
Label {
|
||||
text: name
|
||||
color: listItem.highlighted ? Theme.highlightColor
|
||||
: Theme.primaryColor
|
||||
: Theme.primaryColor;
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
|
@ -56,7 +57,7 @@ Page {
|
|||
Label {
|
||||
text: host + ":" + port
|
||||
color: listItem.highlighted ? Theme.secondaryHighlightColor
|
||||
: Theme.secondaryColor
|
||||
: Theme.secondaryColor;
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
|
|
|
@ -6,49 +6,8 @@
|
|||
|
||||
import QtQuick 2.0
|
||||
import Sailfish.Silica 1.0
|
||||
import harbour.weechatrelay.connectionhandler 1.0
|
||||
import "."
|
||||
|
||||
import "../js/connection.js" as C
|
||||
|
||||
Page {
|
||||
id: debugViewPage
|
||||
|
||||
property bool isConnected: false;
|
||||
|
||||
function display(str) {
|
||||
debugList.add(new Date(), str);
|
||||
}
|
||||
|
||||
function connected() {
|
||||
isConnected = true;
|
||||
}
|
||||
|
||||
function disconnected() {
|
||||
isConnected = false;
|
||||
}
|
||||
|
||||
TextListComponent {
|
||||
id: debugList
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
PushUpMenu {
|
||||
MenuItem {
|
||||
text: isConnected? "Disconnect" : "Close";
|
||||
onClicked: {
|
||||
if (isConnected) {
|
||||
C.disconnect();
|
||||
isConnected = false;
|
||||
}
|
||||
else {
|
||||
C.clearConnection();
|
||||
pageStack.replace("ConnectionList.qml");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VerticalScrollDecorator { flickable: debugList }
|
||||
}
|
||||
BufferView {
|
||||
id: fakeDebugView
|
||||
}
|
||||
|
|
|
@ -8,42 +8,35 @@ SilicaListView {
|
|||
|
||||
function add(datetime, str) {
|
||||
var snap = false;
|
||||
if (textList.atYEnd) {
|
||||
if (textList.atYBeginning) {
|
||||
snap = true;
|
||||
}
|
||||
|
||||
textListModel.append({ "time": datetime, "str": str });
|
||||
// The top is the latest message on the bottom
|
||||
textListModel.insert(0, { "time": datetime.format('HH:mm:ss'), "str": str });
|
||||
|
||||
if (snap) {
|
||||
textList.positionViewAtEnd();
|
||||
textList.positionViewAtBeginning();
|
||||
}
|
||||
}
|
||||
|
||||
function formatTime(datetime) {
|
||||
function colorTime(time) {
|
||||
return U.colored(Theme.secondaryHighlightColor,
|
||||
padTime(datetime.getHours()) + ':'
|
||||
+ padTime(datetime.getMinutes()) + ':'
|
||||
+ padTime(datetime.getSeconds()));
|
||||
}
|
||||
|
||||
function padTime(timeInt) {
|
||||
if (timeInt < 10) {
|
||||
return '0' + timeInt;
|
||||
}
|
||||
|
||||
return '' + timeInt;
|
||||
time);
|
||||
}
|
||||
|
||||
|
||||
model: ListModel { id: textListModel }
|
||||
|
||||
verticalLayoutDirection: ListView.BottomToTop
|
||||
|
||||
delegate: ListItem {
|
||||
width: parent.width
|
||||
contentHeight: messageLabel.height
|
||||
|
||||
Label {
|
||||
id: messageLabel
|
||||
text: formatTime(time) + " " + U.escapeStyled(str)
|
||||
text: colorTime(time) + " " + U.escapeStyled(str)
|
||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||
color: Theme.highlightColor
|
||||
|
||||
|
@ -55,4 +48,6 @@ SilicaListView {
|
|||
textFormat: Text.StyledText
|
||||
}
|
||||
}
|
||||
|
||||
VerticalScrollDecorator { flickable: textList }
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue