Commit d3eed15a authored by Florian Müllner's avatar Florian Müllner Committed by Florian Müllner

Initial commit

parents
*.gir
*.la
*.lo
*.o
*.sw?
*.typelib
*~
.deps
.libs
ABOUT-NLS
Makefile
Makefile.in
aclocal.m4
autom4te.cache/
config.*
configure
data/*.desktop
data/*.gresource
depcomp
install-sh
libtool
ltmain.sh
m4/
missing
po/*.gmo
po/*.header
po/*.sed
po/*.sin
po/.intltool-merge-cache
po/Makefile.in.in
po/Makevars.template
po/POTFILES
po/Rules-quot
po/polari.pot
po/stamp-it
src/config.js
src/polari
Florian Müllner <fmuellner@gnome.org>
This diff is collapsed.
SUBDIRS = src data po
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
EXTRA_DIST = \
autogen.sh \
AUTHORS \
COPYING \
NEWS \
$(NULL)
#!/bin/bash
# Run this to generate all the initial makefiles, etc.
srcdir=`dirname $0`
test -z "$srcdir" && srcdir=.
PKG_NAME="polari"
(test -f $srcdir/configure.ac \
&& test -d $srcdir/src) || {
echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
echo " top-level polari directory"
exit 1
}
which gnome-autogen.sh || {
echo "You need to install gnome-common from GNOME Git (or from"
echo "your OS vendor's package manager)."
exit 1
}
. gnome-autogen.sh
AC_INIT([polari],[0.0.1],[],[polari])
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
AM_INIT_AUTOMAKE([1.11 dist-xz no-dist-gzip tar-ustar foreign])
AM_MAINTAINER_MODE([enable])
GETTEXT_PACKAGE=AC_PACKAGE_NAME
AC_SUBST(GETTEXT_PACKAGE)
IT_PROG_INTLTOOL(0.40.0)
AM_GNU_GETTEXT([external])
AM_GNU_GETTEXT_VERSION([0.17])
GOBJECT_INTROSPECTION_REQUIRE([0.9.6])
AM_DISABLE_STATIC
AC_PROG_LIBTOOL
GLIB_GSETTINGS
PKG_CHECK_MODULES(POLARI,
gio-2.0
gobject-introspection-1.0
telepathy-glib);
GJS_CONSOLE=`$PKG_CONFIG --variable=gjs_console gjs-1.0`
AC_SUBST(GJS_CONSOLE)
GLIB_COMPILE_RESOURCES=`$PKG_CONFIG --variable=glib_compile_resources gio-2.0`
AC_SUBST(GLIB_COMPILE_RESOURCES)
AC_PATH_PROG(DESKTOP_FILE_VALIDATE, desktop-file-validate)
AC_CONFIG_FILES([
Makefile
data/Makefile
po/Makefile.in
src/Makefile
])
AC_OUTPUT
desktopdir = $(datadir)/applications
desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
desktop_in_files = polari.desktop.in
@INTLTOOL_DESKTOP_RULE@
check-local:
$(DESKTOP_FILE_VALIDATE) $(desktop_DATA)
resource_files=$(shell $(GLIB_COMPILE_RESOURCES) --sourcedir=$(srcdir) --generate-dependencies $(srcdir)/polari.gresource.xml)
polari.gresource: polari.gresource.xml $(resource_files)
$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(srcdir) $<
resourcedir=$(pkgdatadir)
resource_DATA=polari.gresource
EXTRA_DIST = \
$(desktop_in_files) \
polari.gresource.xml \
$(resource_files) \
$(NULL)
CLEANFILES = \
$(desktop_DATA) \
$(resource_DATA) \
$(NULL)
[Desktop Entry]
_Name=Polari
_Comment=An Internet Relay Chat Client for GNOME
Exec=polari
TryExec=polari
Icon=
Type=Application
StartupNotify=true
Categories=GNOME;GTK;Network;IRCClient;
_Keywords=IRC;Internet;Relay;Chat;
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/polari">
<file alias="app-menu.ui" preprocess="xml-stripblanks">resources/app-menu.ui</file>
<file alias="join-room-dialog.ui" preprocess="xml-stripblanks">resources/join-room-dialog.ui</file>
<file alias="main-window.ui" preprocess="xml-stripblanks">resources/main-window.ui</file>
<file alias="application.css">resources/application.css</file>
</gresource>
</gresources>
<interface>
<menu id="app-menu">
<section>
<item>
<attribute name="action">app.connections</attribute>
<attribute name="label" translatable="yes">Connections</attribute>
</item>
<item>
<attribute name="action">app.preferences</attribute>
<attribute name="label" translatable="yes">Preferences</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">app.about</attribute>
<attribute name="label" translatable="yes">About Polari</attribute>
</item>
<item>
<attribute name="action">app.quit</attribute>
<attribute name="label" translatable="yes">Quit</attribute>
</item>
</section>
</menu>
</interface>
@define-color polari_dark_bg_color shade(@theme_bg_color, 0.95);
.polari-main-window.background {
background-color: @polari_dark_bg_color;
}
.polari-room-list {
background-color: @theme_bg_color;
}
.polari-room-list .room-list-header {
background-color: @polari_dark_bg_color;
font-size: smaller;
padding: 2px 6px;
}
.polari-room-list .list-row:selected {
background-color: mix(@theme_selected_bg_color, @theme_selected_fg_color, 0.7);
color: @theme_text_color;
}
.polari-room-list .list-row .pending-messages-count {
color: @theme_selected_fg_color;
background-color: mix(@theme_selected_bg_color, @theme_selected_fg_color, 0.3);
font-size: smaller;
border-radius: 4px;
padding: 0px 4px;
}
.polari-chat-stack {
background-color: @theme_base_color;
}
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.10 -->
<object class="GtkEntryCompletion" id="entrycompletion1"/>
<object class="GtkDialog" id="join_room_dialog">
<property name="can_focus">False</property>
<property name="title" translatable="yes">Join Chat Room</property>
<property name="modal">True</property>
<property name="destroy_with_parent">True</property>
<property name="type_hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox1">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area1">
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="cancel_button">
<property name="label">gtk-cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="join_button">
<property name="label" translatable="yes">_Join</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="receives_default">True</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkGrid" id="grid1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="margin_left">96</property>
<property name="margin_right">96</property>
<property name="margin_top">24</property>
<property name="margin_bottom">48</property>
<property name="row_spacing">12</property>
<property name="column_spacing">12</property>
<child>
<object class="GtkEntry" id="password_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="visibility">False</property>
<property name="activates_default">True</property>
<property name="placeholder_text" translatable="yes">optional</property>
<property name="input_purpose">password</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">4</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="name_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="activates_default">True</property>
<property name="completion">entrycompletion1</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkComboBoxText" id="connection_combo">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="server_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Server</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">2</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="room_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">24</property>
<property name="label" translatable="yes">Room</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
<property name="width">2</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="connection_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">C_onnection</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">connection_combo</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="name_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">_Name</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">name_entry</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="password_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">_Password</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">password_entry</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">4</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="-5">join_button</action-widget>
<action-widget response="-6">cancel_button</action-widget>
</action-widgets>
</object>
</interface>
This diff is collapsed.
data/polari.desktop.in
[type: gettext/glade]data/resources/app-menu.ui
[type: gettext/glade]data/resources/join-room-dialog.ui
[type: gettext/glade]data/resources/main-window.ui
src/application.js
src/mainWindow.js
src/userList.js
pkglib_LTLIBRARIES = libpolari-1.0.la
libpolari_headers = \
lib/polari-room.h \
$(NULL)
libpolari_sources = \
lib/polari-room.c \
$(NULL)
libpolari_1_0_la_SOURCES = $(libpolari_headers) $(libpolari_sources)
libpolari_1_0_la_LIBADD = $(POLARI_LIBS)
libpolari_1_0_la_CFLAGS = $(POLARI_CFLAGS)
INTROSPECTION_GIRS += Polari-1.0.gir
Polari-1.0.gir: libpolari-1.0.la Makefile
Polari_1_0_gir_NAMESPACE = Polari
Polari_1_0_gir_VERSION = 1.0
Polari_1_0_gir_LIBS = libpolari-1.0.la
Polari_1_0_gir_CFLAGS = $(POLARI_CFLAGS)
Polari_1_0_gir_FILES = $(libpolari_headers) $(libpolari_sources)
Polari_1_0_gir_SCANNERFLAGS = --warn-all --symbol-prefix=polari --identifier-prefix=Polari
Polari_1_0_gir_INCLUDES = \
Gio-2.0 \
TelepathyGLib-0.12 \
$(NULL)
EXTRA_DIST =
CLEANFILES =
INTROSPECTION_GIRS =
girdir = $(pkgdatadir)/gir-1.0
typelibdir = $(pkglibdir)/girepository-1.0
include $(INTROSPECTION_MAKEFILE)
include Makefile-lib.am
gir_DATA = $(INTROSPECTION_GIRS)
typelib_DATA = $(gir_DATA:.gir=.typelib)
CLEANFILES += $(gir_DATA) $(typelib_DATA)
do_subst = sed -e 's|@localedir[@]|$(localedir)|g' \
-e 's|@pkgdatadir[@]|$(pkgdatadir)|g' \
-e 's|@pkglibdir[@]|$(pkglibdir)|g' \
-e 's|@GJS_CONSOLE[@]|$(GJS_CONSOLE)|g' \
-e 's|@PACKAGE_VERSION[@]|$(PACKAGE_VERSION)|g' \
$(NULL)
bin_SCRIPTS = polari
polari: polari.in
$(AM_V_GEN) $(do_subst) $< > $@
jsdir = $(pkgdatadir)/js/
dist_js_DATA = \
application.js \
chatroomManager.js \
chatView.js \
main.js \
mainWindow.js \
roomList.js \
telepathyClient.js \
userList.js \
utils.js \
$(NULL)
config.js: config.js.in Makefile
$(do_subst) $< > $@
nodist_js_DATA = \
config.js \
$(NULL)
EXTRA_DIST += \
config.js.in \
polari.in \
$(NULL)
CLEANFILES += \
config.js \
polari \
$(NULL)
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Config = imports.config;
const Format = imports.format;
const Lang = imports.lang;
const MainWindow = imports.mainWindow;
const Utils = imports.utils;
const Application = new Lang.Class({
Name: 'Application',
Extends: Gtk.Application,
_init: function() {
this.parent({ application_id: 'org.gnome.Polari' });
GLib.set_prgname('polari');
GLib.set_application_name('Polari');
this._window = null;
},
vfunc_startup: function() {
this.parent();
String.prototype.format = Format.format;
let resource = Gio.Resource.load(Config.RESOURCE_DIR + '/polari.gresource');
resource._register();
let builder = new Gtk.Builder();
builder.add_from_resource('/org/gnome/polari/app-menu.ui');
this.set_app_menu(builder.get_object('app-menu'));
let actionEntries = [
{ name: 'connections',
activate: Lang.bind(this, this._listConnections) },
{ name: 'preferences',
activate: Lang.bind(this, this._showPreferences) },
{ name: 'about',
activate: Lang.bind(this, this._showAbout) },
{ name: 'quit',
activate: Lang.bind(this, this.release) }
];
Utils.createActions(actionEntries).forEach(Lang.bind(this,
function(a) {
this.add_action(a);
}));
this.add_accelerator('<Primary>q', 'app.quit', null);
this._window = new MainWindow.MainWindow(this);
let provider = new Gtk.CssProvider();
let uri = 'resource:///org/gnome/polari/application.css';
let file = Gio.File.new_for_uri(uri);
try {
provider.load_from_file(Gio.File.new_for_uri(uri));
} catch(e) {
logError(e, "Failed to add application style");
}
Gtk.StyleContext.add_provider_for_screen(this._window.window.get_screen(),
provider, 600);
this._window.window.show_all();
},
vfunc_activate: function() {
if (this._window)
this._window.window.present();
},
_listConnections: function() {
},
_showPreferences: function() {
},
_showAbout: function() {
let authors = [ 'Florian M' + String.fromCharCode(0x00FC) + 'llner <fmuellner@gnome.org>' ];
let dialog = new Gtk.AboutDialog({ transient_for: this._window.window,
modal: true,
authors: authors,
comments: 'An Internet Relay Chat Client for GNOME',
version: Config.PACKAGE_VERSION,
license_type: Gtk.License.GPL_3_0,
wrap_license: true });
dialog.show();
dialog.connect('response', function() {
dialog.destroy();
});
}
});
const Gtk = imports.gi.Gtk;
const Pango = imports.gi.Pango;
const Tp = imports.gi.TelepathyGLib;
const Lang = imports.lang;
const MAX_NICK_CHARS = 8;
const HIGHLIGHT_SCALE = (1.0 / 1.1);
const ChatView = new Lang.Class({
Name: 'ChatView',
_init: function(room) {
this.widget = new Gtk.ScrolledWindow();
this.widget.hscrollbar_policy = Gtk.PolicyType.NEVER;
this.widget.resize_mode = Gtk.ResizeMode.QUEUE;
this._view = new Gtk.TextView({ editable: false, cursor_visible: false,
margin: 6, visible: true,
wrap_mode: Gtk.WrapMode.WORD });
this.widget.add(this._view);
this.widget.show_all();
this.widget.connect('destroy', Lang.bind(this, this._onDestroy));
this.widget.connect('screen-changed',
Lang.bind(this, this._updateIndent));
this.widget.connect('parent-set', Lang.bind(this, this._onParentSet));
this.widget.connect('hierarchy-changed',
Lang.bind(this, this._onHierarchyChanged));
this.widget.vadjustment.connect('changed',
Lang.bind(this, this._onAdjustmentChanged));
this._room = room;
this._lastNick = null;
this._stackNotifyVisibleChildId = 0;
this._scrollBottom = false;
this._active = false;
this._toplevelFocus = false;
let channelSignals = [
{ name: 'message-received',
handler: Lang.bind(this, this._insertMessage) },
{ name: 'message-sent',
handler: Lang.bind(this, this._insertMessage) }
];
this._channelSignals = [];
channelSignals.forEach(Lang.bind(this, function(signal) {
this._channelSignals.push(room.channel.connect(signal.name, signal.handler));
}));
let roomSignals = [
{ name: 'member-renamed',
handler: Lang.bind(this, this._onMemberRenamed) },
{ name: 'member-disconnected',
handler: Lang.bind(this, this._onMemberDisconnected) },
{ name: 'member-kicked',
handler: Lang.bind(this, this._onMemberKicked) },
{ name: 'member-banned',
handler: Lang.bind(this, this._onMemberBanned) },
{ name: 'member-joined',
handler: Lang.bind(this, this._onMemberJoined) },
{ name: 'member-left',
handler: Lang.bind(this, this._onMemberLeft) }
];
this._roomSignals = [];
roomSignals.forEach(Lang.bind(this, function(signal) {
this._roomSignals.push(room.connect(signal.name, signal.handler));
}));
let context = this.widget.get_style_context();
context.save();
context.add_class('dim-label');
let color = context.get_color(Gtk.StateFlags.NORMAL);
context.restore();
let tagTable = this._view.get_buffer().get_tag_table();
let tags = [
{ name: 'nick',
foreground_rgba: color,
left_margin: 0 },
{ name: 'message',
indent: 0 },
{ name: 'highlight',
weight: Pango.Weight.BOLD,
scale: HIGHLIGHT_SCALE },
{ name: 'status',
foreground_rgba: color,
left_margin: 0 }
];
tags.forEach(function(tagProps) {
tagTable.add(new Gtk.TextTag(tagProps));
});
},
_onDestroy: function() {
for (let i = 0; i < this._channelSignals.length; i++)
this._room.channel.disconnect(this._channelSignals[i]);
this._channelSignals = [];
for (let i = 0; i < this._roomSignals.length; i++)
this._room.disconnect(this._roomSignals[i]);
this._roomSignals = [];
},
_updateIndent: function() {
let context = this._view.get_pango_context();
let metrics = context.get_metrics(null, null);
let charWidth = Math.max(metrics.get_approximate_char_width(),