Compare commits
470 Commits
Author | SHA1 | Date |
---|---|---|
Travis Burtrum | ebbdc383ec | |
Sebastian Kaspari | 2282784df2 | |
Sebastian Kaspari | d9b17bc4a1 | |
Sebastian Kaspari | aea85d6cd6 | |
Sebastian Kaspari | 7f680f1282 | |
Sebastian Kaspari | 19c9541307 | |
Sebastian Kaspari | fd6f2d219f | |
Sebastian Kaspari | c4f3fd1cd8 | |
Sebastian Kaspari | 1e0ac76c15 | |
Sebastian Kaspari | 408dfdb2e3 | |
Sebastian Kaspari | cd759757fb | |
Sebastian Kaspari | 0cf49a6cd3 | |
Sebastian Kaspari | 948ef762cd | |
Sebastian Kaspari | 3f4b2f2de3 | |
Sebastian Kaspari | 91c0d23ac2 | |
Sebastian Kaspari | 29bdca690f | |
Sebastian Kaspari | dec2c2cc1d | |
Sebastian Kaspari | 5891d90b24 | |
Sebastian Kaspari | ff7cf2656b | |
Sebastian Kaspari | 2f17919e2e | |
Sebastian Kaspari | 408d4ee80e | |
Sebastian Kaspari | 6d843abbac | |
Sebastian Kaspari | 92ae35c7b0 | |
Sebastian Kaspari | 63e6a70314 | |
Sebastian Kaspari | 0de229c130 | |
Sebastian Kaspari | 3e4f8f57bd | |
Sebastian Kaspari | 6ee5ed0eff | |
Sebastian Kaspari | fc6516e1d3 | |
Sebastian Kaspari | b374f2972d | |
Sebastian Kaspari | 06591a9b4e | |
Sebastian Kaspari | c5dd873e9d | |
Sebastian Kaspari | bb8cd1a4de | |
Sebastian Kaspari | 690e9442f3 | |
Sebastian Kaspari | 4aca69e765 | |
Sebastian Kaspari | 0e0b2bb199 | |
Sebastian Kaspari | b1fe1b09a0 | |
Sebastian Kaspari | 0a539c3a04 | |
Sebastian Kaspari | 396d6cec0a | |
Sebastian Kaspari | 33560b4913 | |
Sebastian Kaspari | 74ae710f22 | |
Sebastian Kaspari | deaf1c4679 | |
Sebastian Kaspari | 3b66320fb0 | |
Sebastian Kaspari | 521d1ead14 | |
Sebastian Kaspari | 465e4e407e | |
Sebastian Kaspari | 2c78483c64 | |
Sebastian Kaspari | 9ed0b8c001 | |
Sebastian Kaspari | 5e304a2d98 | |
Sebastian Kaspari | 54b8f01e32 | |
Sebastian Kaspari | 86e6f49f8b | |
Sebastian Kaspari | 0a42cb5352 | |
Sebastian Kaspari | 330239c093 | |
Sebastian Kaspari | 0256c28391 | |
Sebastian Kaspari | 7abdd48094 | |
Sebastian Kaspari | 4c26ac0586 | |
Sebastian Kaspari | 7cd59283eb | |
Sebastian Kaspari | 8da30cc425 | |
Sebastian Kaspari | a1147a60f2 | |
Sebastian Kaspari | b316f2e9eb | |
Sebastian Kaspari | 5d9ba0d119 | |
Sebastian Kaspari | 8fc20b46a4 | |
Sebastian Kaspari | c8ecda3436 | |
Sebastian Kaspari | ab590458e3 | |
Sebastian Kaspari | e2200d9e64 | |
Sebastian Kaspari | 7cf957d0b2 | |
Sebastian Kaspari | d6f1cd4c41 | |
Sebastian Kaspari | 8fe8b9669a | |
Sebastian Kaspari | f564245ee8 | |
Sebastian Kaspari | 90055e839c | |
Sebastian Kaspari | c813a4a79e | |
Sebastian Kaspari | c6b9c700f0 | |
Sebastian Kaspari | 4b1642bce1 | |
Sebastian Kaspari | 6c93aaef62 | |
Sebastian Kaspari | 175254e652 | |
Ricky Elrod | 170f632c07 | |
Sebastian Kaspari | 8858b362fe | |
Sebastian Kaspari | a39a4259ea | |
Sebastian Kaspari | f9ef1c65ec | |
Sebastian Kaspari | 4d49e5e106 | |
Sebastian Kaspari | b479ac55dc | |
Sebastian Kaspari | f3239d9492 | |
Sebastian Kaspari | cdcc3c1eb3 | |
Sebastian Kaspari | ae131d8acd | |
Sebastian Kaspari | 936a747d41 | |
Sebastian Kaspari | fd3e9f3f04 | |
Sebastian Kaspari | e931087172 | |
Sebastian Kaspari | 214faa06b6 | |
Sebastian Kaspari | ead068e78e | |
Sebastian Kaspari | 48b12bff40 | |
Sebastian Kaspari | 98076c1d24 | |
Sebastian Kaspari | c1f2648628 | |
Sebastian Kaspari | 81b7fe798c | |
Sebastian Kaspari | dbdc731965 | |
Sebastian Kaspari | e05b15731c | |
Sebastian Kaspari | b9b1468157 | |
Sebastian Kaspari | 09091c229a | |
Sebastian Kaspari | 346287a0ae | |
Sebastian Kaspari | e2eb4a39f0 | |
Sebastian Kaspari | be49f407bb | |
Sebastian Kaspari | 369fa7f8df | |
Sebastian Kaspari | ef09f4fc68 | |
Sebastian Kaspari | 59ab0efd9d | |
Sebastian Kaspari | 35a8d93cd0 | |
Daniel E. Moctezuma | 89ff98b93d | |
Daniel E. Moctezuma | e444354d48 | |
Daniel E. Moctezuma | 59ce275105 | |
Daniel E. Moctezuma | 3f8578ef73 | |
Daniel E. Moctezuma | 6dc38f5f54 | |
Daniel E. Moctezuma | 1cfb74a2df | |
Sebastian Kaspari | 862dedb33b | |
Sebastian Kaspari | aecb828477 | |
jgeboski | 1a43262cb5 | |
Sebastian Kaspari | 0381728018 | |
Sebastian Kaspari | 95be86b2bf | |
Sebastian Kaspari | db6ed0a122 | |
Sebastian Kaspari | 56304633f4 | |
Sebastian Kaspari | da78ea15d0 | |
Sebastian Kaspari | 7c27b09298 | |
Sebastian Kaspari | 929d2e873e | |
remram44 | 0de3c817b1 | |
Sebastian Kaspari | 640acec6eb | |
Sebastian Kaspari | 419c2bb3cb | |
Sebastian Kaspari | 9c551d73bf | |
Sebastian Kaspari | 743eae9b85 | |
Sebastian Kaspari | 9884ef1bff | |
Sebastian Kaspari | 6f7275563c | |
Sebastian Kaspari | debc79dd59 | |
Sebastian Kaspari | a7c121ebea | |
Sebastian Kaspari | b32b24c4ba | |
Sebastian Kaspari | d6176ca5a0 | |
Sebastian Kaspari | 2c73859b58 | |
Sebastian Kaspari | 8fc10e0419 | |
Sebastian Kaspari | 4831e71567 | |
Sebastian Kaspari | c511e9bcc5 | |
Daniel E. Moctezuma | ca4a93d40d | |
Sebastian Kaspari | 84c3025c26 | |
Sebastian Kaspari | 9a05d3b606 | |
Sebastian Kaspari | 8f329f475c | |
Sebastian Kaspari | f713466468 | |
Sebastian Kaspari | 6045cd0f91 | |
Sebastian Kaspari | 2e6292eac0 | |
Sebastian Kaspari | cb5354a306 | |
Sebastian Kaspari | c292892307 | |
Sebastian Kaspari | 35b896c3d6 | |
Sebastian Kaspari | 5d68a5efb1 | |
Jose Carlos Garcia Sogo | 03b5782e82 | |
Sebastian Kaspari | 309c730b33 | |
Sebastian Kaspari | 8ecb697f28 | |
remram44 | 493f9f758c | |
Sebastian Kaspari | 5485213e52 | |
Sebastian Kaspari | 690012504e | |
Sebastian Kaspari | 9f314df091 | |
Sebastian Kaspari | 1a4f570d6e | |
remram44 | e89b641536 | |
Sebastian Kaspari | 0ec311c074 | |
Sebastian Kaspari | 6aff86bcb6 | |
Sebastian Kaspari | d0ea5a2a2d | |
Sebastian Kaspari | e7c84fb694 | |
Sebastian Kaspari | 2fbe9c4e26 | |
Sebastian Kaspari | 8d32855938 | |
Sebastian Kaspari | 21032950b7 | |
Sebastian Kaspari | fbdebc2ca5 | |
Sebastian Kaspari | 3e9735760a | |
Sebastian Kaspari | 46a45523a8 | |
Sebastian Kaspari | d4f2c1cc3a | |
Sebastian Kaspari | c4ba9cd35d | |
Sebastian Kaspari | f9615a2344 | |
Sebastian Kaspari | b09ba251ea | |
Sebastian Kaspari | da885094da | |
Sebastian Kaspari | 2a51daf45c | |
Sebastian Kaspari | 25cf7eb2ad | |
Sebastian Kaspari | 706a864f44 | |
Sebastian Kaspari | 8386f4a1ef | |
remram44 | 6ff79ee50d | |
Sebastian Kaspari | ec90fe3db6 | |
Sebastian Kaspari | e04499070a | |
Sebastian Kaspari | 659d6c0b89 | |
Sebastian Kaspari | ca0a86d2cb | |
Sebastian Kaspari | e6be035a8e | |
Sebastian Kaspari | a4bc0ada80 | |
Sebastian Kaspari | 29e102b5d0 | |
Sebastian Kaspari | d1d23ecb04 | |
Sebastian Kaspari | e00cb44553 | |
Sebastian Kaspari | 2522aacb11 | |
Sebastian Kaspari | a0a1d3fb3d | |
Sebastian Kaspari | e7243258b9 | |
Sebastian Kaspari | bd17dcd598 | |
Steven Luo | 66006cabf5 | |
Sebastian Kaspari | 5c25c86614 | |
Jonas Häggqvist | 61e1681b03 | |
Sebastian Kaspari | 8c8e9e8081 | |
Daniel E. Moctezuma | c7c0b0c44e | |
Francesco Lavra | 0a8e75feff | |
Sebastian Kaspari | d155e86cd1 | |
Steven Luo | e07d99ed5d | |
Steven Luo | f84369bc19 | |
Steven Luo | c8266fbe62 | |
Steven Luo | fafbe1ca4a | |
Sebastian Kaspari | 4396e66954 | |
Sebastian Kaspari | 0b0579c475 | |
Sebastian Kaspari | a357c42477 | |
Sebastian Kaspari | 39175635d9 | |
Sebastian Kaspari | e82345c1fe | |
Sebastian Kaspari | 668f7f26ae | |
Sebastian Kaspari | 99b4b0929a | |
Steven Luo | 02316ffdbc | |
Steven Luo | ec17d34e4d | |
Steven Luo | e0f90768b2 | |
Steven Luo | d80f4133f1 | |
remram44 | 5d5ce6445a | |
Darren Salt | 2759b00084 | |
Sebastian Kaspari | 9dba05eb2d | |
Darren Salt | 23ca120f0e | |
Sebastian Kaspari | a6da4970aa | |
Sebastian Kaspari | d7070c84cf | |
Sebastian Kaspari | 61252c7535 | |
Rey Rey | 2e2aebf2c4 | |
Rey Rey | 5c48724425 | |
Rey Rey | f7ccd50227 | |
Rey Rey | 84ade9fae4 | |
Rey Rey | 27d93ebaa7 | |
Steven Luo | ccaf9f59c4 | |
Steven Luo | 77dec6249d | |
Rey Rey | 6da6a7b76b | |
Rey Rey | 93e77ea6ed | |
Sebastian Kaspari | a5d81a1350 | |
Rey Rey | 750df0de36 | |
Steven Luo | bce2523f98 | |
Steven Luo | e7651315df | |
Steven Luo | a69fafc4dd | |
Sebastian Kaspari | ae871f8a1f | |
remram44 | 8fea644007 | |
remram44 | 938577128d | |
Sebastian Kaspari | 6e48a29b34 | |
Sebastian Kaspari | 2f19eb8032 | |
Sebastian Kaspari | 4739d292c5 | |
Sebastian Kaspari | d9d1c4aba8 | |
Sebastian Kaspari | 2fde7559e3 | |
Sebastian Kaspari | 571090aa13 | |
Jonas Häggqvist | d4e22f3846 | |
Sebastian Kaspari | 7c7ce7cc41 | |
Sebastian Kaspari | 862d6664d4 | |
Sebastian Kaspari | 5fa92b9cf4 | |
Sebastian Kaspari | 14ed6f7f2b | |
Sebastian Kaspari | 2350e9743a | |
Sebastian Kaspari | 1a820d9609 | |
Steven Luo | aaf3f3e332 | |
Steven Luo | a9621b66b4 | |
Steven Luo | dc95472aaf | |
Steven Luo | 06e0849c17 | |
Steven Luo | 35609e5529 | |
Steven Luo | aa355c4283 | |
Steven Luo | 91d211c51d | |
Steven Luo | 61960c9add | |
Steven Luo | 09fedc6975 | |
Steven Luo | 9a8bf44d63 | |
Steven Luo | 159cb8195d | |
Steven Luo | c9ed28767d | |
Steven Luo | ae1b574997 | |
Steven Luo | ffe73b7c9f | |
Steven Luo | c4504be725 | |
Steven Luo | 464430ee74 | |
Steven Luo | caf3272f71 | |
Steven Luo | f1b57c9e25 | |
remram44 | 3102340762 | |
Sebastian Kaspari | 1201931de1 | |
Sebastian Kaspari | b4493b81a4 | |
Matt Mastracci | ac4fa4a104 | |
remram44 | 322c4e0ac8 | |
Sebastian Kaspari | daf07014f8 | |
Sebastian Kaspari | c20cd695e6 | |
Sebastian Kaspari | 1e5f016012 | |
Sebastian Kaspari | 50a6047edd | |
Sebastian Kaspari | c6dbe8cc18 | |
Sebastian Kaspari | 86e0812741 | |
Sebastian Kaspari | 4e266e1bb7 | |
Sebastian Kaspari | 9387a02068 | |
Sebastian Kaspari | ded6485f6b | |
Sebastian Kaspari | b3fd4157dc | |
Sebastian Kaspari | dd07bd358a | |
Sebastian Kaspari | aa5a081c02 | |
José Antonio Pérez Sánchez | 2b3ce5132a | |
Sebastian Kaspari | dbf7983eec | |
Sebastian Kaspari | b798d4dacb | |
Sebastian Kaspari | 591dc8f763 | |
Sebastian Kaspari | 673598ad31 | |
liato | ac1a07894f | |
liato | 92a1e93bc1 | |
liato | 7490cdb38c | |
liato | eea82e506f | |
liato | 2189d2c05f | |
liato | 7c4abe0c9c | |
liato | 59c70a750d | |
liato | 624f8c5014 | |
liato | e612d3b09c | |
Sebastian Kaspari | bd19398d65 | |
Sebastian Kaspari | 9b776aef15 | |
Sebastian Kaspari | ba9f6c6544 | |
liato | 1f9c8efcca | |
liato | 1ebea8f7d6 | |
liato | b49ead73ad | |
Sebastian Kaspari | 7563437343 | |
Sebastian Kaspari | 78a47ca17b | |
Sebastian Kaspari | 214a786175 | |
Sebastian Kaspari | f44aea0d5e | |
Sebastian Kaspari | 23ed9c3343 | |
Sebastian Kaspari | 4713c22655 | |
Sebastian Kaspari | 7e559f288e | |
Sebastian Kaspari | f71e89e1ee | |
Sebastian Kaspari | 3e188a0445 | |
Sebastian Kaspari | 7d4194a1ea | |
Sebastian Kaspari | f46887d9ee | |
Sebastian Kaspari | f5b29ef01a | |
Sebastian Kaspari | 22fb895ad3 | |
Sebastian Kaspari | c06b6b7296 | |
Sebastian Kaspari | 533a8ec97b | |
Sebastian Kaspari | acb7f0d100 | |
Sebastian Kaspari | 59755b376c | |
Sebastian Kaspari | 3156e3b704 | |
Sebastian Kaspari | 836e9ee6cd | |
Sebastian Kaspari | 7ba3303892 | |
Sebastian Kaspari | e486d34189 | |
Sebastian Kaspari | 1b5f8ef0e9 | |
Sebastian Kaspari | ff6abb7828 | |
Sebastian Kaspari | 0dc194cefc | |
Sebastian Kaspari | 4262cbcd15 | |
Sebastian Kaspari | b855b7ea92 | |
Sebastian Kaspari | 49f067cd67 | |
Sebastian Kaspari | 488924546f | |
Sebastian Kaspari | 95f3c4b255 | |
Sebastian Kaspari | 1c8076ec53 | |
liato | a3ebf8d5d0 | |
Sebastian Kaspari | 84d45c5f5c | |
Sebastian Kaspari | 635b90b5da | |
Sebastian Kaspari | d2a638d527 | |
Sebastian Kaspari | 5ea5b800b8 | |
Sebastian Kaspari | 3f18a678ce | |
Sebastian Kaspari | 1e0a15c110 | |
Sebastian Kaspari | 7845ad73f0 | |
Thomas Martitz | f4637ac582 | |
Thomas Martitz | 70b5ee876d | |
Thomas Martitz | db91a85676 | |
Thomas Martitz | 7120bb48ea | |
liato | efecd7c6f7 | |
liato | 33f181de3c | |
Sebastian Kaspari | b4f3fc4a15 | |
Sebastian Kaspari | e169627905 | |
Sebastian Kaspari | 97c382c893 | |
Sebastian Kaspari | 8c5258710f | |
Sebastian Kaspari | f6a518462c | |
Sebastian Kaspari | b3e26c626b | |
Sebastian Kaspari | b1a8c5d539 | |
Sebastian Kaspari | 669113610a | |
Sebastian Kaspari | 984fbd7efa | |
Sebastian Kaspari | d4f05e5c13 | |
Sebastian Kaspari | c35e1fc1ab | |
Sebastian Kaspari | cf5ea6049c | |
Sebastian Kaspari | ca6e342c9d | |
Sebastian Kaspari | 450ba9c7a2 | |
Sebastian Kaspari | 68fc686ccf | |
Sebastian Kaspari | d8b1a0218f | |
Sebastian Kaspari | dddfd2e0aa | |
Sebastian Kaspari | 0fb2338f9c | |
Sebastian Kaspari | 4edaa4436d | |
Sebastian Kaspari | feaf1d4aea | |
Sebastian Kaspari | 7c63155cfb | |
Sebastian Kaspari | e68ef9c8c2 | |
Sebastian Kaspari | a315fbb6fa | |
Sebastian Kaspari | e0b4b3d25d | |
Sebastian Kaspari | aaa313e805 | |
Sebastian Kaspari | 7764351a37 | |
Sebastian Kaspari | 414bc658ba | |
Sebastian Kaspari | 78ca7deebc | |
Sebastian Kaspari | e014165a17 | |
Sebastian Kaspari | 4b3e47c799 | |
Sebastian Kaspari | 832a462bfd | |
Sebastian Kaspari | 4d04ca810d | |
Sebastian Kaspari | c60644521a | |
Sebastian Kaspari | 890fc1c50f | |
Sebastian Kaspari | 7d080a8134 | |
Sebastian Kaspari | 82e62db96c | |
Sebastian Kaspari | 3b50e5a095 | |
Sebastian Kaspari | 6c3597ff80 | |
Sebastian Kaspari | 02b7ec1741 | |
Sebastian Kaspari | f3f195f631 | |
Sebastian Kaspari | ce0650d711 | |
Sebastian Kaspari | 46cb3f9f17 | |
Sebastian Kaspari | 6d2a6bff14 | |
liato | 3708a9c60c | |
liato | f5b5b99adb | |
liato | 81f2c94b87 | |
Sebastian Kaspari | 1d2f6e5237 | |
Sebastian Kaspari | d23e984e21 | |
Sebastian Kaspari | 37f12b6ab7 | |
Sebastian Kaspari | 514aaf5cf1 | |
Sebastian Kaspari | 72c75b4dae | |
Sebastian Kaspari | 0b82433320 | |
Sebastian Kaspari | 6a237792e6 | |
Sebastian Kaspari | f4b30f0217 | |
Sebastian Kaspari | eba7788038 | |
Sebastian Kaspari | 6f82e84484 | |
Sebastian Kaspari | 1250c10d9c | |
Sebastian Kaspari | 59ef955987 | |
Sebastian Kaspari | c92a3dce8b | |
Sebastian Kaspari | ebea92ccf8 | |
Sebastian Kaspari | b2e37a8644 | |
Sebastian Kaspari | 952a1c6782 | |
Sebastian Kaspari | 9e91c6b2b9 | |
Sebastian Kaspari | f8a5fde6fb | |
Sebastian Kaspari | 3f469d4074 | |
Sebastian Kaspari | 99cf534f20 | |
Sebastian Kaspari | 4fc593050f | |
Sebastian Kaspari | 510d3967c6 | |
diegok | baa9dd438c | |
Remi Rampin | 6127dcedd6 | |
Remi Rampin | 2c4a2a7969 | |
Remi Rampin | a3fbd38b24 | |
Sebastian Kaspari | 5e0888775b | |
Sebastian Kaspari | 2b2fdeb6ae | |
Sebastian Kaspari | 01cedbab92 | |
Sebastian Kaspari | d86e90d6e9 | |
Sebastian Kaspari | 6ced20032d | |
Sebastian Kaspari | d9da2d022e | |
Sebastian Kaspari | 059f21d983 | |
Sebastian Kaspari | f10aa55d5d | |
Sebastian Kaspari | 5df472fe11 | |
Sebastian Kaspari | 14a76d2c95 | |
Sebastian Kaspari | 075164bd51 | |
Sebastian Kaspari | be07e2e0ad | |
Sebastian Kaspari | d447990a35 | |
Sebastian Kaspari | c818458a97 | |
Sebastian Kaspari | 7411db41f9 | |
Sebastian Kaspari | 43f8f7af62 | |
Sebastian Kaspari | e136a56d7d | |
Sebastian Kaspari | a535d74a85 | |
Sebastian Kaspari | 8775d93020 | |
Michael Imamura | 8c5af16b29 | |
Michael Imamura | 288a1a9093 | |
Michael Imamura | b9c1363a2d | |
Sebastian Kaspari | 26330bdf99 | |
chantra | 30dc021129 | |
Sebastian Kaspari | 6691b9ad1b | |
Sebastian Kaspari | 1f0df9caaf | |
Sebastian Kaspari | 60bb5759ef | |
Sebastian Kaspari | 4622579189 | |
Sebastian Kaspari | a4595bf756 | |
Sebastian Kaspari | 8901056b17 | |
Sebastian Kaspari | e29a6ec7af | |
Sebastian Kaspari | caaa5395fd | |
Sebastian Kaspari | 307605e594 | |
Sebastian Kaspari | eeb26335ac | |
Sebastian Kaspari | aacc0a85c2 | |
Sebastian Kaspari | 6c9094b7e0 | |
Sebastian Kaspari | 9f2e16e2ce | |
Sebastian Kaspari | 802de03689 | |
Sebastian Kaspari | 1f206371bd | |
Sebastian Kaspari | 5ea7d49c34 | |
Sebastian Kaspari | 84fedf8be2 | |
Sebastian Kaspari | 25cfb5a980 | |
Sebastian Kaspari | ba16f15079 | |
Sebastian Kaspari | 9e33ec9b01 | |
Sebastian Kaspari | 2a55b81049 | |
Sebastian Kaspari | 72301331f2 | |
Sebastian Kaspari | 943b4635dc | |
Sebastian Kaspari | 5e78c020a1 | |
Sebastian Kaspari | 90459a156f | |
Sebastian Kaspari | 9d2011330f | |
Sebastian Kaspari | e6ba6f4bad | |
Sebastian Kaspari | c5b52e95c1 | |
Sebastian Kaspari | 8fc5ca054d | |
Sebastian Kaspari | 17aba7ca71 |
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
|
@ -1,8 +1,23 @@
|
|||
#
|
||||
# Git Ignore for Yaaic
|
||||
#
|
||||
|
||||
# Android Studio & Gradle
|
||||
*.iml
|
||||
build/
|
||||
.gradle/
|
||||
.idea/
|
||||
|
||||
|
||||
# Compiled and generated files
|
||||
bin/
|
||||
gen/
|
||||
R.java
|
||||
|
||||
# Build files
|
||||
local.properties
|
||||
ant.properties
|
||||
build.xml
|
||||
proguard.cfg
|
||||
|
||||
# Maven
|
||||
target/
|
||||
|
||||
|
|
33
.project
33
.project
|
@ -1,33 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>Yaaic</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -0,0 +1,12 @@
|
|||
language: android
|
||||
android:
|
||||
components:
|
||||
- platform-tools
|
||||
- tools
|
||||
- build-tools-22.0.0
|
||||
- android-22
|
||||
- extra-google-google_play_services
|
||||
- extra-google-m2repository
|
||||
- extra-android-m2repository
|
||||
notifications:
|
||||
irc: "irc.freenode.net#yaaic"
|
|
@ -1,92 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2010 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.yaaic"
|
||||
android:versionCode="6"
|
||||
android:versionName="0.5">
|
||||
<application
|
||||
android:icon="@drawable/icon"
|
||||
android:label="Yaaic">
|
||||
<activity
|
||||
android:name=".activity.ServersActivity"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTask">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.AddServerActivity"
|
||||
android:label="@string/add_server_label">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="irc"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.ConversationActivity"
|
||||
android:windowSoftInputMode="adjustResize|stateHidden">
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.AboutActivity"
|
||||
android:label="@string/about_label"
|
||||
android:theme="@android:style/Theme.Dialog">
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.SettingsActivity"
|
||||
android:label="@string/settings_label">
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.JoinActivity"
|
||||
android:label="@string/join_label"
|
||||
android:theme="@android:style/Theme.Dialog">
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.UsersActivity"
|
||||
android:label="@string/users"
|
||||
android:theme="@android:style/Theme.Dialog">
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.AddChannelActivity"
|
||||
android:theme="@android:style/Theme.Dialog">
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.AddCommandsActivity"
|
||||
android:theme="@android:style/Theme.Dialog">
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.MessageActivity"
|
||||
android:theme="@android:style/Theme.Dialog">
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.UserActivity"
|
||||
android:theme="@android:style/Theme.Dialog">
|
||||
</activity>
|
||||
<service android:name=".irc.IRCService"></service>
|
||||
</application>
|
||||
|
||||
<uses-sdk android:minSdkVersion="3" />
|
||||
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
|
||||
</manifest>
|
|
@ -0,0 +1,261 @@
|
|||
--------------------------------------------------------------------------------
|
||||
Yaaic 1.1 - 2015-03-17 - 55 commits, 707 files changed, 4 authors
|
||||
--------------------------------------------------------------------------------
|
||||
* Android 5.0 only (First preparations for a Material theme)
|
||||
* You can finally scroll and it won't scroll back when someone writes something
|
||||
* Fixed annoying bug that caused keyboard not showing up
|
||||
* Forward slashes are now allowed in an Ident
|
||||
* Support for LED light notification on nickname highlight
|
||||
* Option to show seconds in timestamp
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Yaaic 1.0 - 2012-07-29 - 89 commits, 685 files changed, 7 authors
|
||||
--------------------------------------------------------------------------------
|
||||
* New cleaned up UI using ActionBar and ViewPager.
|
||||
* Yaaic can now be installed on SD cards.
|
||||
* New Android emoticons.
|
||||
* New command: /back - Turns off the away status (Francesco Lavra)
|
||||
* Several bug fixes
|
||||
* Updated translations - Help translating Yaaic online:
|
||||
http://crowdin.net/project/yaaic
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Yaaic 0.9 - 2011-07-17 - 67 commits, 49 files changed, 7 authors
|
||||
--------------------------------------------------------------------------------
|
||||
* SASL support (pocmo)
|
||||
* Fullscreen chat setting (reyncor)
|
||||
* Extended IRC URI support (reyncor)
|
||||
* GUI for adding authentication data for Nickserv/SASL (pocmo)
|
||||
* Only hide MOTD once (dsalt)
|
||||
* Ignore status characters in front of nicks for the purpose of nick
|
||||
completion (rasher)
|
||||
* Configurable history size (Steven Luo)
|
||||
* Overhaul notifications system (Steven Luo)
|
||||
* Now displays the number of mentions that the user has not seen in the
|
||||
notification.
|
||||
* When no mentions are outstanding, display which servers the user is
|
||||
connected to, not the last message.
|
||||
* When more than one mention is outstanding, display the names of the
|
||||
conversations with new mentions, not just the last message received.
|
||||
* Notifications of mentions are suppressed if you're in the conversation
|
||||
at the time of the mention.
|
||||
* Notifications of mentions automatically clear when you bring up the
|
||||
conversation.
|
||||
* Vibrate notifications now generate the user's chosen default vibrate
|
||||
pattern, not a hard-coded one.
|
||||
* Add ticker text to the notification that's displayed when the IRCService
|
||||
goes into the foreground, instead of displaying a blank ticker.
|
||||
* Include channel topic in the displayed conversation title (Steven Luo)
|
||||
* Actually deliver actions to existing private message windows (Steven Luo)
|
||||
* Notify the user on receipt of all private messages, not just ones with nick
|
||||
mentions. (Steven Luo)
|
||||
* Ensure privmsg with mention of user's nick opens new query when appropriate
|
||||
(Steven Luo)
|
||||
* Remembers which conversation was last selected (Steven Luo)
|
||||
* Danish translation (rasher)
|
||||
--------------------------------------------------------------------------------
|
||||
Yaaic 0.8 - 2011-03-15 - 27 commits, 35 files changed
|
||||
--------------------------------------------------------------------------------
|
||||
* Support for mIRC colors (liato)
|
||||
* Support for graphical smilies (liato)
|
||||
* Bugfix: Connection issues when nickname already in use (pocmo)
|
||||
* Bugfix: Only automatically change nickname on server code 433 if not already
|
||||
registered with server (pocmo)
|
||||
* Turkish translation (Hasan Kiran)
|
||||
* Several bugs fixed regarding force closes (pocmo)
|
||||
* On own nick change: Display message in server info window (pocmo)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Yaaic 0.7 - 2011-03-27 - 79 commits, 144 files changed
|
||||
--------------------------------------------------------------------------------
|
||||
* New setting: Play notification sound on highlight.
|
||||
* Updated Robotium to 2.0.2
|
||||
* All current scenario tests are now running
|
||||
* Ident: Added "-" to the list of allowed characters
|
||||
* Fixed voice recognition (Only add top match to the text input)
|
||||
* Code cleanup and eclipse code formatter settings
|
||||
* New translation: Italian (Thanks to Gianmarco Laggia!)
|
||||
* Minimum width defined for some buttons that may become difficult to touch
|
||||
* A lot of code cleanup (mostly formatting)
|
||||
* New user action view and new actions: reply, query
|
||||
* Fixed typo: "joines" -> "joins"
|
||||
* Fixed some issues in the IRC parser for bouncers. Especially regarding
|
||||
Irsii proxy.
|
||||
* Tablet support. Yaaic will scale to different screen resolutions.
|
||||
* Tweak some nick colors for readability on Yaaic's dark background. (kugel-)
|
||||
* Reduce sensitivity of channel switcher (kugel-)
|
||||
* Always open last activity and do not start with server list (liato & kugel-)
|
||||
* Resolved a lot of connection issues - especially with bouncers.
|
||||
* Some improvements for accessibility (but still a lot of things to do)
|
||||
* All dimensions and fontsizes now use screen independent sizes and should
|
||||
therefore look better on differen screen sizes.
|
||||
* It's now possible to hide quit messages as well.
|
||||
* New Setting: Show notices in server window
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Yaaic 0.6.1 - 2010-12-17 - 15 commits, 109 files changed
|
||||
--------------------------------------------------------------------------------
|
||||
* Fixed a bug in the french and spanish translation that may cause force closes
|
||||
on connecting to a server.
|
||||
* New setting available: Hide join and part messages.
|
||||
* Automated testing: Some first scenario tests using the Robotium framework.
|
||||
* Improved nickname detection: Words including the nickname won't cause a
|
||||
highlight. (Thanks to liato!)
|
||||
* Vibrating on highlight is now available as a setting. (Thanks to liato!)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Yaaic 0.6 - 2010-11-16 - 80 commits, 179 files changed
|
||||
--------------------------------------------------------------------------------
|
||||
* Voice recognition via Google API
|
||||
* Everything is now easy translatable via one XML file
|
||||
* Customizable font sizes (8px - 20px)
|
||||
* New shortcut: /w for /whois
|
||||
* Every unknown command will now be sent to the server. No more command
|
||||
whitelisting.
|
||||
* Colored nicknames (by chantra)
|
||||
* Set a list of nickname aliases (by ZoogieZork)
|
||||
* Small ruby script to check the translation status
|
||||
* Userlist is now sorted alphabetically (By mloskot)
|
||||
* Nick completion via search button - completes current selection or at the
|
||||
cursor position (Patch by Thomas Martitz)
|
||||
* Build files for ant
|
||||
* Merged yaaic application and testing repositories
|
||||
* First scenario tests via the robotium lib.
|
||||
* Translations:
|
||||
o Chinese
|
||||
o Japanese (work in progress)
|
||||
o German (work in progress)
|
||||
o French
|
||||
o Spanish
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Yaaic 0.5 - 2010-08-27 - 35 commits, 19 files changed
|
||||
--------------------------------------------------------------------------------
|
||||
* Awesome channel indicator at the bottom of the screen showing highlights and
|
||||
new messages in other channels
|
||||
* Define a custom quit message in the settings menu
|
||||
* Execute commands on connect BEFORE joining channels
|
||||
* Wait a small amount of time before auto-joining channels (because of slow
|
||||
server commands)
|
||||
* Tap a nickname in the user list to perform an action (op, deop, kick, ...)
|
||||
* Bugfix: Enter key did not work on Motorola Milestone
|
||||
* Disable "Ok" button on Add Channel, Add Command dialogs until something's
|
||||
actually been added or removed. (by brion. thanks!)
|
||||
* Other small adjustments and bugfixes
|
||||
* Bugfix: The ident now can contain numbers
|
||||
* Bugfix: Nicknames now can start with an underscore (_)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Yaaic 0.4.1 - 2010-04-27 - 14 commits, 13 files changed
|
||||
--------------------------------------------------------------------------------
|
||||
* When using the reconnect feature (Settings) - Yaaic sometimes did reconnect
|
||||
even when you disconnected yourself (even when "exit" was used)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Yaaic 0.4 - 2010-04-25 - 66 commits, 36 files changed
|
||||
--------------------------------------------------------------------------------
|
||||
* You can now define channels to join after connecting to a server
|
||||
* It's also possible now to add commands that are executed after connecting to
|
||||
a server
|
||||
* When adding/editing a server spaces at the beginning and ending will be
|
||||
removed due to some "on screen keyboards" adding spaces.
|
||||
* The following server commands have been added to the whitelist and Yaaic will
|
||||
now send them to the server: /opper, /nickserv, /ns, /chanserv, /cs,
|
||||
/authserv, /hostserv, /memoserv, /operserv
|
||||
* Bugfix: Closed queries couldn't be reopened when closed
|
||||
* New command: Send a message to a channel or user:
|
||||
/msg <target> <message> (See Issue 10)
|
||||
* New command: Send a message to all channels on the server: /amsg <message>
|
||||
* Bugfix: Nicknames can now contain a hyphen (-) (See issue 9)
|
||||
* Bugfix: When using BIP IRC Proxy channels were not joined (See Issue 8)
|
||||
* New command: /quote <line> or /raw <line> to send a raw line to the server
|
||||
* Settings: You can now enable to reconnect automatically on disconnect
|
||||
* Bugfix: Sometimes the notification icon was still in the notification bar if
|
||||
not connected to any server and yaaic not running
|
||||
* The menu now contains an "exit" option to disconnect from all servers and
|
||||
exiting Yaaic.
|
||||
* Bugfix: When selection "connect" via long-click on a connected server in the
|
||||
list, Yaaic disconnected.
|
||||
* The /help command now shows the usage of a command if given as parameter:
|
||||
/help <command> (Thanks to Kell)
|
||||
* The server list now also shows the nickname and the port of the server
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Yaaic 0.3 - 2010-04-15 - 145 commits, 79 files changed.
|
||||
--------------------------------------------------------------------------------
|
||||
* Yaaic now has an awesome icon designed by androidicons.com
|
||||
* It's now possible to select a charset when adding/editing a server. See the
|
||||
list of supported charsets for more details.
|
||||
* SSL-Support! You are now able to use SSL connections with Yaaic. But beware!
|
||||
The current TrustManager will accept every certificate.
|
||||
* There will be an icon in your notification bar if you are connected to a
|
||||
server.
|
||||
* You can now connect to some IRC networks that use strange spam bot checks.
|
||||
* The background service is now persistent so that you don't get disconnected
|
||||
while yaaic is in the background and you are using an other app.
|
||||
* Bugfix: Sometimes the app crashed if you disconnected from a server and
|
||||
connected again to the same server later.
|
||||
* There has been a lot of code optimization. Hopefully Yaaic is now much more
|
||||
smoother.
|
||||
* You are now notified about a disconnect in all conversation views.
|
||||
* The background color is now fixed so that Yaaic should look the same on
|
||||
Android 1.5 as well as on Android 2.x.
|
||||
* There's now a menu option to show a list of the users in the current selected
|
||||
channel
|
||||
* Highlights (if someone mentions your nickname), Connects and Disconnects are
|
||||
now shown as notifications in the notification bar.
|
||||
* You can now use the dialpad up and dialpad down buttons to scroll in the
|
||||
history of messages entered by you
|
||||
* Menu items that are not ussable until connect are now inactive.
|
||||
* There's now a /help command showing all commands available (Thanks to Kell)
|
||||
* If a disconnect occurs Yaaic will now ask you if you want to reconnect
|
||||
(Currently only if yaaic is not in the background)
|
||||
* Developers: There's now a second repository for automated testing with some
|
||||
unit tests already added: http://github.com/pocmo/Yaaic-Test
|
||||
* Bugfix: The timestamps sometimes were wrong, especially the timestamps in
|
||||
12h format were totally wrong at all
|
||||
* New commands handled by the client: /away /whois
|
||||
* Last but not least, thanks to tkn for contributing a bug fix! :)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Yaaic 0.2 - 2010-03-20 - 58 commits, 22 files changed.
|
||||
--------------------------------------------------------------------------------
|
||||
* Bugfix: Fixed an annoying bug that caused messages to sometimes appear in the
|
||||
wrong channel / query
|
||||
* Bugfix: A lot of (visual) issues have been fixed when using the on screen
|
||||
keyboard
|
||||
* More IRC events are now shown as messages:
|
||||
* On set / remove channel key
|
||||
* On set / remove channel secret
|
||||
* On set / remove channel ban
|
||||
* On set / remove channel limit
|
||||
* On set / remove topic protection
|
||||
* On set / remove external messages
|
||||
* On set / remove invite only
|
||||
* On set / remove moderated
|
||||
* On set / remove private
|
||||
* On invite into channel
|
||||
* Send files via DCC with /dcc SEND <nickname> <file>
|
||||
* The join channel dialog is now permanent and does not disappear on rotation
|
||||
* It's now mandatory to enter a real name as servers require a value on connect
|
||||
* A nicer look and feel with transcluent conversation windows and rounded
|
||||
corners
|
||||
* Bugfix: Scrollbar didn't scroll automatically sometimes
|
||||
* Bugfix: Messages updated their timestamp when application was resumed
|
||||
* Server responses are now shown in the server info window (some are skipped)
|
||||
* Messages containing the current nickname are now highlighted (red color)
|
||||
* If you are clicking on an irc:// link in the browser you are now able to add
|
||||
this server to your server list
|
||||
* Servers in the serverlist can now be edited (long touch a server)
|
||||
* UTF-8 is now the default enconding used by the IRC client. There will be an
|
||||
option to choose an enconding in a future release
|
||||
* Bugfix: Messages that have been written by users while the client was paused
|
||||
didn't appear directly on resume
|
||||
* Server titles now have to be unique
|
||||
* ... some other small fixes and adjustments
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Yaaic 0.1 (Beta) - 2010-03-14
|
||||
--------------------------------------------------------------------------------
|
||||
* This is the first release. There hasn't changed anything to prior releases ;)
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
Thanks to all contributors!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Development
|
||||
--------------------------------------------------------------------------------
|
||||
Sebastian Kaspari https://github.com/pocmo
|
||||
Karol Gliniecki https://github.com/kell
|
||||
Michael Imamura https://github.com/ZoogieZork
|
||||
Liato https://github.com/liato
|
||||
Chantra https://github.com/chantra
|
||||
Torben Nielsen https://github.com/tkn
|
||||
Brion Vibber https://github.com/brion
|
||||
Thomas Martitz https://github.com/kugel-
|
||||
Mateusz Loskot https://github.com/mloskot
|
||||
Steven Luo
|
||||
Jonas Häggqvist https://github.com/rasher
|
||||
Reyncor https://github.com/Reyncor
|
||||
Darren Salt https://github.com/dsalt
|
||||
Daniel E. Moctezuma https://github.com/democtezuma
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Graphics
|
||||
--------------------------------------------------------------------------------
|
||||
Guenther Beyer http://www.androidicons.com
|
||||
Jörn Schreiber http://www.joern-schreiber.de
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Translations
|
||||
--------------------------------------------------------------------------------
|
||||
English Sebastian Kaspari https://github.com/pocmo
|
||||
Spanish Diego Kuperman https://github.com/diegok
|
||||
German Daniel Bonkowski
|
||||
Italian Gianmarco Laggia
|
||||
French Remi Rampin https://github.com/remram44
|
||||
Japanese Nobuhiro Ito https://github.com/iseebi
|
||||
Daniel E. Moctezuma https://github.com/democtezuma
|
||||
Chinese Leekie (江珑)
|
||||
Turkish Hasan Kiran
|
||||
Danish Jonas Häggqvist https://github.com/rasher
|
||||
Russian NeKit
|
||||
|
44
README
44
README
|
@ -1,44 +0,0 @@
|
|||
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
This is the source code distribution of Yaaic. If you are looking
|
||||
for a compiled 'ready to use' version, see the official homepage at:
|
||||
|
||||
http://www.yaaic.org
|
||||
|
||||
If you are a developer and want to contribute to Yaaic, checkout
|
||||
our repository at github:
|
||||
|
||||
http://github.com/pocmo/Yaaic
|
||||
|
||||
See also the "test package" for unit tests & co.:
|
||||
|
||||
http://github.com/pocmo/Yaaic-Test
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
Yaaic includes the PircBot IRC API written by Paul Mutton available
|
||||
under the GNU General Public License (GPL). http://www.jibble.org
|
||||
|
||||
The Yaaic icon was designed by http://www.androidicons.com
|
||||
|
||||
Some icons are part of the Silk icon set designed by Mark James
|
||||
available under the Creative Commons Licence Attribution 3.0
|
||||
Licence. http://www.famfamfam.com
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see http://www.gnu.org/licenses/
|
|
@ -0,0 +1,61 @@
|
|||
[![Build Status](https://travis-ci.org/pocmo/Yaaic.svg?branch=master)](https://travis-ci.org/pocmo/Yaaic)
|
||||
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
======================================
|
||||
|
||||
Yaaic is as the full name already says an Internet Relay Chat (IRC)
|
||||
client for Android devices.
|
||||
|
||||
This is the source code distribution of Yaaic. If you are looking
|
||||
for a compiled 'ready to use' version (APK), get the official
|
||||
build at the Google Play Store:
|
||||
|
||||
* https://play.google.com/store/apps/details?id=org.yaaic
|
||||
|
||||
If you are a developer and want to contribute to Yaaic, checkout
|
||||
our repository at GitHub:
|
||||
|
||||
* http://github.com/pocmo/Yaaic
|
||||
|
||||
The project is using Gradle to build the application. Importing it
|
||||
into Android Studio should be enough to get it building.
|
||||
|
||||
Drop me a line for questions regarding Yaaic or use one of the
|
||||
following resources:
|
||||
|
||||
- IRC: irc.freenode.net #yaaic
|
||||
- Homepage: http://www.yaaic.org
|
||||
- Google Group: http://groups.google.com/group/yaaic
|
||||
- Twitter: http://twitter.com/Yaaic
|
||||
- Facebook: http://www.facebook.com/pages/Yaaic/359902798214
|
||||
|
||||
Third party libraries & resources
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Yaaic includes the PircBot IRC API written by Paul Mutton available
|
||||
under the GNU General Public License (GPL). http://www.jibble.org
|
||||
|
||||
The Yaaic icon was designed by http://www.androidicons.com
|
||||
|
||||
Some icons are part of the Silk icon set designed by Mark James
|
||||
available under the Creative Commons Licence Attribution 3.0
|
||||
Licence. http://www.famfamfam.com
|
||||
|
||||
Copyright (GPL)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Copyright 2009-2015 Sebastian Kaspari
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see http://www.gnu.org/licenses/
|
||||
|
|
@ -0,0 +1 @@
|
|||
/build
|
|
@ -0,0 +1,32 @@
|
|||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 22
|
||||
buildToolsVersion '22.0.0'
|
||||
|
||||
defaultConfig {
|
||||
applicationId "org.yaaic"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 22
|
||||
versionCode 14
|
||||
versionName "2.0"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
// A warning inside of appcompat prevents us from enabling this option
|
||||
abortOnError false
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile 'com.android.support:support-v4:22.1.1'
|
||||
compile 'com.android.support:cardview-v7:22.1.1'
|
||||
compile 'com.android.support:recyclerview-v7:22.1.1'
|
||||
compile 'com.android.support:appcompat-v7:22.1.1'
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in /Applications/Android-SDK/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
|
@ -0,0 +1,100 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.yaaic"
|
||||
android:installLocation="auto">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
|
||||
<application
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="Yaaic"
|
||||
android:theme="@style/Theme.Yaaic"
|
||||
android:allowBackup="true"
|
||||
android:name=".YaaicApplication">
|
||||
<activity android:name=".activity.MainActivity"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="standard" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.AddServerActivity"
|
||||
android:label="@string/add_server_label" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data android:scheme="irc" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.AboutActivity"
|
||||
android:label="@string/about_label"
|
||||
android:theme="@android:style/Theme.Material.Dialog" >
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.JoinActivity"
|
||||
android:label="@string/join_label"
|
||||
android:theme="@android:style/Theme.Material.Dialog" >
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.UsersActivity"
|
||||
android:label="@string/users"
|
||||
android:theme="@android:style/Theme.Material.Dialog" >
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.AddAliasActivity"
|
||||
android:theme="@android:style/Theme.Dialog" >
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.AddChannelActivity"
|
||||
android:theme="@android:style/Theme.Material.Dialog" >
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.AddCommandsActivity"
|
||||
android:theme="@android:style/Theme.Material.Dialog" >
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.MessageActivity"
|
||||
android:theme="@android:style/Theme.Material.Dialog" >
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.UserActivity"
|
||||
android:theme="@android:style/Theme.Material.Dialog" >
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.AuthenticationActivity"
|
||||
android:theme="@android:style/Theme.Material.Dialog" >
|
||||
</activity>
|
||||
|
||||
<service android:name=".irc.IRCService" >
|
||||
</service>
|
||||
</application>
|
||||
|
||||
</manifest>
|
|
@ -22,9 +22,9 @@ package org.jibble.pircbot;
|
|||
* @version 1.4.6 (Build time: Wed Apr 11 19:20:59 2007)
|
||||
*/
|
||||
public class IrcException extends Exception {
|
||||
private static final long serialVersionUID = -3705541066912475928L;
|
||||
private static final long serialVersionUID = -3705541066912475928L;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs a new IrcException.
|
||||
*
|
||||
* @param e The error message to report.
|
|
@ -25,9 +25,9 @@ package org.jibble.pircbot;
|
|||
* @version 1.4.6 (Build time: Wed Apr 11 19:20:59 2007)
|
||||
*/
|
||||
public class NickAlreadyInUseException extends IrcException {
|
||||
private static final long serialVersionUID = -4724325464519465479L;
|
||||
private static final long serialVersionUID = -4724325464519465479L;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs a new IrcException.
|
||||
*
|
||||
* @param e The error message to report.
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
|
||||
import org.yaaic.db.Database;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Global Master Class :)
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class Yaaic
|
||||
{
|
||||
public static Yaaic instance;
|
||||
|
||||
private HashMap<Integer, Server> servers;
|
||||
private boolean serversLoaded = false;
|
||||
|
||||
/**
|
||||
* Private constructor, you may want to use static getInstance()
|
||||
*/
|
||||
private Yaaic()
|
||||
{
|
||||
servers = new HashMap<Integer, Server>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load servers from database
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
public void loadServers(Context context)
|
||||
{
|
||||
if (!serversLoaded) {
|
||||
Database db = new Database(context);
|
||||
servers = db.getServers();
|
||||
db.close();
|
||||
|
||||
// context.sendBroadcast(new Intent(Broadcast.SERVER_UPDATE));
|
||||
serversLoaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get global Yaaic instance
|
||||
*
|
||||
* @return the global Yaaic instance
|
||||
*/
|
||||
public static Yaaic getInstance()
|
||||
{
|
||||
if (instance == null) {
|
||||
instance = new Yaaic();
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get server by id
|
||||
*
|
||||
* @return Server object with given unique id
|
||||
*/
|
||||
public Server getServerById(int serverId)
|
||||
{
|
||||
return servers.get(serverId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove server with given unique id from list
|
||||
*
|
||||
* @param serverId
|
||||
*/
|
||||
public void removeServerById(int serverId)
|
||||
{
|
||||
servers.remove(serverId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add server to list
|
||||
*/
|
||||
public void addServer(Server server)
|
||||
{
|
||||
if (!servers.containsKey(server.getId())) {
|
||||
servers.put(server.getId(), server);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a server in list
|
||||
*/
|
||||
public void updateServer(Server server)
|
||||
{
|
||||
servers.put(server.getId(), server);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of servers
|
||||
*
|
||||
* @return list of servers
|
||||
*/
|
||||
public ArrayList<Server> getServersAsArrayList()
|
||||
{
|
||||
ArrayList<Server> serverList = new ArrayList<Server>();
|
||||
|
||||
Set<Integer> mKeys = servers.keySet();
|
||||
for (int key : mKeys) {
|
||||
serverList.add(servers.get(key));
|
||||
}
|
||||
|
||||
return serverList;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2010 Sebastian Kaspari
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
|
@ -18,11 +18,18 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.listener;
|
||||
package org.yaaic;
|
||||
|
||||
public interface ConversationListener
|
||||
{
|
||||
public void onConversationMessage(String target);
|
||||
public void onNewConversation(String target);
|
||||
public void onRemoveConversation(String target);
|
||||
import android.app.Application;
|
||||
|
||||
/**
|
||||
* Application implementation for Yaaic.
|
||||
*/
|
||||
public class YaaicApplication extends Application {
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
||||
Yaaic.getInstance().loadServers(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2015 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.activity;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.yaaic.R;
|
||||
|
||||
/**
|
||||
* "About" dialog activity.
|
||||
*/
|
||||
public class AboutActivity extends Activity {
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
|
||||
setContentView(R.layout.about);
|
||||
|
||||
initializeVersionView();
|
||||
initializeIrcView();
|
||||
}
|
||||
|
||||
private void initializeVersionView() {
|
||||
try {
|
||||
TextView versionView = (TextView) findViewById(R.id.version);
|
||||
versionView.setText(
|
||||
getPackageManager().getPackageInfo(getPackageName(), 0).versionName
|
||||
);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
throw new AssertionError("Should not happen: Can't read application info of myself");
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeIrcView() {
|
||||
TextView ircLinkView = (TextView) findViewById(R.id.about_irclink);
|
||||
ircLinkView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
Intent intent = new Intent(AboutActivity.this, AddServerActivity.class);
|
||||
intent.setData(Uri.parse(getString(R.string.app_irc)));
|
||||
startActivity(intent);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
package org.yaaic.activity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.model.Extra;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.Window;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ListView;
|
||||
|
||||
public class AddAliasActivity extends Activity implements OnClickListener, OnItemClickListener, TextWatcher
|
||||
{
|
||||
private EditText aliasInput;
|
||||
private ArrayAdapter<String> adapter;
|
||||
private ArrayList<String> aliases;
|
||||
private Button addButton;
|
||||
private Button okButton;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
|
||||
setContentView(R.layout.aliasadd);
|
||||
|
||||
aliasInput = (EditText) findViewById(R.id.alias);
|
||||
aliasInput.addTextChangedListener(this);
|
||||
|
||||
adapter = new ArrayAdapter<String>(this, R.layout.aliasitem);
|
||||
|
||||
ListView list = (ListView) findViewById(R.id.aliases);
|
||||
list.setAdapter(adapter);
|
||||
list.setOnItemClickListener(this);
|
||||
|
||||
addButton = (Button) findViewById(R.id.add);
|
||||
addButton.setOnClickListener(this);
|
||||
((Button) findViewById(R.id.cancel)).setOnClickListener(this);
|
||||
|
||||
okButton = (Button) findViewById(R.id.ok);
|
||||
okButton.setOnClickListener(this);
|
||||
okButton.setEnabled(false);
|
||||
|
||||
aliases = getIntent().getExtras().getStringArrayList(Extra.ALIASES);
|
||||
|
||||
for (String alias : aliases) {
|
||||
adapter.add(alias);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On Click
|
||||
*/
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
switch (v.getId()) {
|
||||
case R.id.add:
|
||||
String alias = aliasInput.getText().toString().trim();
|
||||
aliases.add(alias);
|
||||
adapter.add(alias);
|
||||
aliasInput.setText("");
|
||||
okButton.setEnabled(true);
|
||||
break;
|
||||
|
||||
case R.id.cancel:
|
||||
setResult(RESULT_CANCELED);
|
||||
finish();
|
||||
break;
|
||||
|
||||
case R.id.ok:
|
||||
// Get list and return as result
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(Extra.ALIASES, aliases);
|
||||
setResult(RESULT_OK, intent);
|
||||
finish();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On item clicked
|
||||
*/
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> list, View item, int position, long id)
|
||||
{
|
||||
final String alias = adapter.getItem(position);
|
||||
|
||||
String[] items = { getResources().getString(R.string.action_remove) };
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle(alias);
|
||||
builder.setItems(items, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int item) {
|
||||
switch (item) {
|
||||
case 0: // Remove
|
||||
adapter.remove(alias);
|
||||
aliases.remove(alias);
|
||||
okButton.setEnabled(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.show();
|
||||
}
|
||||
|
||||
/**
|
||||
* On text changed
|
||||
*/
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count)
|
||||
{
|
||||
addButton.setEnabled(aliasInput.getText().length() > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* After text changed
|
||||
*/
|
||||
@Override
|
||||
public void afterTextChanged(Editable s)
|
||||
{
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
/**
|
||||
* Before text changed
|
||||
*/
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after)
|
||||
{
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.activity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.model.Extra;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ListView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
|
||||
/**
|
||||
* Adding auto join channels to a server
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class AddChannelActivity extends Activity implements OnClickListener, OnItemClickListener
|
||||
{
|
||||
private EditText channelInput;
|
||||
private ArrayAdapter<String> adapter;
|
||||
private ArrayList<String> channels;
|
||||
private Button okButton;
|
||||
|
||||
/**
|
||||
* On create
|
||||
*/
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
|
||||
setContentView(R.layout.channeladd);
|
||||
|
||||
channelInput = (EditText) findViewById(R.id.channel);
|
||||
channelInput.setSelection(1);
|
||||
|
||||
adapter = new ArrayAdapter<String>(this, R.layout.channelitem);
|
||||
|
||||
ListView list = (ListView) findViewById(R.id.channels);
|
||||
list.setAdapter(adapter);
|
||||
list.setOnItemClickListener(this);
|
||||
|
||||
((Button) findViewById(R.id.add)).setOnClickListener(this);
|
||||
((Button) findViewById(R.id.cancel)).setOnClickListener(this);
|
||||
|
||||
okButton = (Button) findViewById(R.id.ok);
|
||||
okButton.setOnClickListener(this);
|
||||
okButton.setEnabled(false);
|
||||
|
||||
channels = getIntent().getExtras().getStringArrayList(Extra.CHANNELS);
|
||||
|
||||
for (String channel : channels) {
|
||||
adapter.add(channel);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On Click
|
||||
*/
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
switch (v.getId()) {
|
||||
case R.id.add:
|
||||
String channel = channelInput.getText().toString().trim();
|
||||
channels.add(channel);
|
||||
adapter.add(channel);
|
||||
channelInput.setText("#");
|
||||
channelInput.setSelection(1);
|
||||
okButton.setEnabled(true);
|
||||
break;
|
||||
|
||||
case R.id.cancel:
|
||||
setResult(RESULT_CANCELED);
|
||||
finish();
|
||||
break;
|
||||
|
||||
case R.id.ok:
|
||||
// Get list and return as result
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(Extra.CHANNELS, channels);
|
||||
setResult(RESULT_OK, intent);
|
||||
finish();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On item clicked
|
||||
*/
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> list, View item, int position, long id)
|
||||
{
|
||||
final String channel = adapter.getItem(position);
|
||||
|
||||
String[] items = { getResources().getString(R.string.action_remove) };
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle(channel);
|
||||
builder.setItems(items, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int item) {
|
||||
switch (item) {
|
||||
case 0: // Remove
|
||||
adapter.remove(channel);
|
||||
channels.remove(channel);
|
||||
okButton.setEnabled(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.show();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.activity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.model.Extra;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.Window;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ListView;
|
||||
|
||||
/**
|
||||
* Adding commands (to execute after connect) to a server
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class AddCommandsActivity extends Activity implements OnClickListener, OnItemClickListener
|
||||
{
|
||||
private EditText commandInput;
|
||||
private ArrayAdapter<String> adapter;
|
||||
private ArrayList<String> commands;
|
||||
private Button okButton;
|
||||
|
||||
/**
|
||||
* On create
|
||||
*/
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
|
||||
setContentView(R.layout.commandadd);
|
||||
|
||||
commandInput = (EditText) findViewById(R.id.command);
|
||||
|
||||
adapter = new ArrayAdapter<String>(this, R.layout.commanditem);
|
||||
|
||||
ListView list = (ListView) findViewById(R.id.commands);
|
||||
list.setAdapter(adapter);
|
||||
list.setOnItemClickListener(this);
|
||||
|
||||
((Button) findViewById(R.id.add)).setOnClickListener(this);
|
||||
((Button) findViewById(R.id.ok)).setOnClickListener(this);
|
||||
((Button) findViewById(R.id.cancel)).setOnClickListener(this);
|
||||
|
||||
okButton = (Button) findViewById(R.id.ok);
|
||||
okButton.setOnClickListener(this);
|
||||
okButton.setEnabled(false);
|
||||
|
||||
commands = getIntent().getExtras().getStringArrayList(Extra.COMMANDS);
|
||||
|
||||
for (String command : commands) {
|
||||
adapter.add(command);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On Click
|
||||
*/
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
switch (v.getId()) {
|
||||
case R.id.add:
|
||||
String command = commandInput.getText().toString().trim();
|
||||
|
||||
if (!command.startsWith("/")) {
|
||||
command = "/" + command;
|
||||
}
|
||||
|
||||
commands.add(command);
|
||||
adapter.add(command);
|
||||
commandInput.setText("/");
|
||||
okButton.setEnabled(true);
|
||||
break;
|
||||
|
||||
case R.id.cancel:
|
||||
setResult(RESULT_CANCELED);
|
||||
finish();
|
||||
break;
|
||||
|
||||
case R.id.ok:
|
||||
// Get list and return as result
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(Extra.COMMANDS, commands);
|
||||
setResult(RESULT_OK, intent);
|
||||
finish();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On item clicked
|
||||
*/
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> list, View item, int position, long id)
|
||||
{
|
||||
final String command = adapter.getItem(position);
|
||||
|
||||
String[] items = { getResources().getString(R.string.action_remove) };
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle(command);
|
||||
builder.setItems(items, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int item) {
|
||||
switch (item) {
|
||||
case 0: // Remove
|
||||
adapter.remove(command);
|
||||
commands.remove(command);
|
||||
okButton.setEnabled(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.show();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,453 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.activity;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.Yaaic;
|
||||
import org.yaaic.db.Database;
|
||||
import org.yaaic.exception.ValidationException;
|
||||
import org.yaaic.model.Authentication;
|
||||
import org.yaaic.model.Extra;
|
||||
import org.yaaic.model.Identity;
|
||||
import org.yaaic.model.Server;
|
||||
import org.yaaic.model.Status;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Add a new server to the list
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class AddServerActivity extends ActionBarActivity implements OnClickListener
|
||||
{
|
||||
private static final int REQUEST_CODE_CHANNELS = 1;
|
||||
private static final int REQUEST_CODE_COMMANDS = 2;
|
||||
private static final int REQUEST_CODE_ALIASES = 3;
|
||||
private static final int REQUEST_CODE_AUTHENTICATION = 4;
|
||||
|
||||
private Server server;
|
||||
private Authentication authentication;
|
||||
private ArrayList<String> aliases;
|
||||
private ArrayList<String> channels;
|
||||
private ArrayList<String> commands;
|
||||
|
||||
/**
|
||||
* On create
|
||||
*/
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.activity_add_server);
|
||||
|
||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||
toolbar.addView(LayoutInflater.from(this).inflate(R.layout.item_done_discard, toolbar, false));
|
||||
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
authentication = new Authentication();
|
||||
aliases = new ArrayList<String>();
|
||||
channels = new ArrayList<String>();
|
||||
commands = new ArrayList<String>();
|
||||
|
||||
findViewById(R.id.aliases).setOnClickListener(this);
|
||||
findViewById(R.id.channels).setOnClickListener(this);
|
||||
findViewById(R.id.commands).setOnClickListener(this);
|
||||
findViewById(R.id.authentication).setOnClickListener(this);
|
||||
|
||||
Spinner spinner = (Spinner) findViewById(R.id.charset);
|
||||
String[] charsets = getResources().getStringArray(R.array.charsets);
|
||||
ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(this, android.R.layout.simple_spinner_item, charsets);
|
||||
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
spinner.setAdapter(adapter);
|
||||
|
||||
Bundle extras = getIntent().getExtras();
|
||||
if (extras != null && extras.containsKey(Extra.SERVER)) {
|
||||
setTitle(R.string.edit_server_label);
|
||||
|
||||
// Request to edit an existing server
|
||||
Database db = new Database(this);
|
||||
this.server = db.getServerById(extras.getInt(Extra.SERVER));
|
||||
aliases.addAll(server.getIdentity().getAliases());
|
||||
this.channels = db.getChannelsByServerId(server.getId());
|
||||
this.commands = db.getCommandsByServerId(server.getId());
|
||||
this.authentication = server.getAuthentication();
|
||||
db.close();
|
||||
|
||||
// Set server values
|
||||
((EditText) findViewById(R.id.title)).setText(server.getTitle());
|
||||
((EditText) findViewById(R.id.host)).setText(server.getHost());
|
||||
((EditText) findViewById(R.id.port)).setText(String.valueOf(server.getPort()));
|
||||
((EditText) findViewById(R.id.password)).setText(server.getPassword());
|
||||
|
||||
((EditText) findViewById(R.id.nickname)).setText(server.getIdentity().getNickname());
|
||||
((EditText) findViewById(R.id.ident)).setText(server.getIdentity().getIdent());
|
||||
((EditText) findViewById(R.id.realname)).setText(server.getIdentity().getRealName());
|
||||
((CheckBox) findViewById(R.id.useSSL)).setChecked(server.useSSL());
|
||||
|
||||
// Select charset
|
||||
if (server.getCharset() != null) {
|
||||
for (int i = 0; i < charsets.length; i++) {
|
||||
if (server.getCharset().equals(charsets[i])) {
|
||||
spinner.setSelection(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Disable suggestions for host name
|
||||
if (android.os.Build.VERSION.SDK_INT >= 5) {
|
||||
EditText serverHostname = (EditText) findViewById(R.id.host);
|
||||
serverHostname.setInputType(0x80000);
|
||||
}
|
||||
|
||||
Uri uri = getIntent().getData();
|
||||
if (uri != null && uri.getScheme().equals("irc")) {
|
||||
// handling an irc:// uri
|
||||
|
||||
((EditText) findViewById(R.id.host)).setText(uri.getHost());
|
||||
if (uri.getPort() != -1) {
|
||||
((EditText) findViewById(R.id.port)).setText(String.valueOf(uri.getPort()));
|
||||
}
|
||||
if (uri.getPath() != null) {
|
||||
channels.add(uri.getPath().replace('/', '#'));
|
||||
}
|
||||
if (uri.getQuery() != null) {
|
||||
((EditText) findViewById(R.id.password)).setText(String.valueOf(uri.getQuery()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On activity result
|
||||
*/
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
if (resultCode != RESULT_OK) {
|
||||
return; // ignore everything else
|
||||
}
|
||||
|
||||
switch (requestCode) {
|
||||
case REQUEST_CODE_ALIASES:
|
||||
aliases.clear();
|
||||
aliases.addAll(data.getExtras().getStringArrayList(Extra.ALIASES));
|
||||
break;
|
||||
|
||||
case REQUEST_CODE_CHANNELS:
|
||||
channels = data.getExtras().getStringArrayList(Extra.CHANNELS);
|
||||
break;
|
||||
|
||||
case REQUEST_CODE_COMMANDS:
|
||||
commands = data.getExtras().getStringArrayList(Extra.COMMANDS);
|
||||
break;
|
||||
|
||||
case REQUEST_CODE_AUTHENTICATION:
|
||||
authentication.setSaslUsername(data.getExtras().getString(Extra.SASL_USER));
|
||||
authentication.setSaslPassword(data.getExtras().getString(Extra.SASL_PASSWORD));
|
||||
authentication.setNickservPassword(data.getExtras().getString(Extra.NICKSERV_PASSWORD));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On click add server or cancel activity
|
||||
*/
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
switch (v.getId()) {
|
||||
case R.id.aliases:
|
||||
Intent aliasIntent = new Intent(this, AddAliasActivity.class);
|
||||
aliasIntent.putExtra(Extra.ALIASES, aliases);
|
||||
startActivityForResult(aliasIntent, REQUEST_CODE_ALIASES);
|
||||
break;
|
||||
|
||||
case R.id.authentication:
|
||||
Intent authIntent = new Intent(this, AuthenticationActivity.class);
|
||||
authIntent.putExtra(Extra.NICKSERV_PASSWORD, authentication.getNickservPassword());
|
||||
authIntent.putExtra(Extra.SASL_USER, authentication.getSaslUsername());
|
||||
authIntent.putExtra(Extra.SASL_PASSWORD, authentication.getSaslPassword());
|
||||
startActivityForResult(authIntent, REQUEST_CODE_AUTHENTICATION);
|
||||
break;
|
||||
|
||||
case R.id.channels:
|
||||
Intent channelIntent = new Intent(this, AddChannelActivity.class);
|
||||
channelIntent.putExtra(Extra.CHANNELS, channels);
|
||||
startActivityForResult(channelIntent, REQUEST_CODE_CHANNELS);
|
||||
break;
|
||||
|
||||
case R.id.commands:
|
||||
Intent commandsIntent = new Intent(this, AddCommandsActivity.class);
|
||||
commandsIntent.putExtra(Extra.COMMANDS, commands);
|
||||
startActivityForResult(commandsIntent, REQUEST_CODE_COMMANDS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void onCancel(View view) {
|
||||
setResult(RESULT_CANCELED);
|
||||
finish();
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to save server.
|
||||
*/
|
||||
public void onSave(View view) {
|
||||
try {
|
||||
validateServer();
|
||||
validateIdentity();
|
||||
if (server == null) {
|
||||
addServer();
|
||||
} else {
|
||||
updateServer();
|
||||
}
|
||||
setResult(RESULT_OK);
|
||||
finish();
|
||||
} catch(ValidationException e) {
|
||||
Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add server to database
|
||||
*/
|
||||
private void addServer()
|
||||
{
|
||||
Database db = new Database(this);
|
||||
|
||||
Identity identity = getIdentityFromView();
|
||||
long identityId = db.addIdentity(
|
||||
identity.getNickname(),
|
||||
identity.getIdent(),
|
||||
identity.getRealName(),
|
||||
identity.getAliases()
|
||||
);
|
||||
|
||||
Server server = getServerFromView();
|
||||
server.setAuthentication(authentication);
|
||||
|
||||
long serverId = db.addServer(server, (int) identityId);
|
||||
|
||||
db.setChannels((int) serverId, channels);
|
||||
db.setCommands((int) serverId, commands);
|
||||
|
||||
db.close();
|
||||
|
||||
server.setId((int) serverId);
|
||||
server.setIdentity(identity);
|
||||
server.setAutoJoinChannels(channels);
|
||||
server.setConnectCommands(commands);
|
||||
|
||||
Yaaic.getInstance().addServer(server);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update server
|
||||
*/
|
||||
private void updateServer()
|
||||
{
|
||||
Database db = new Database(this);
|
||||
|
||||
int serverId = this.server.getId();
|
||||
int identityId = db.getIdentityIdByServerId(serverId);
|
||||
|
||||
Server server = getServerFromView();
|
||||
server.setAuthentication(authentication);
|
||||
db.updateServer(serverId, server, identityId);
|
||||
|
||||
Identity identity = getIdentityFromView();
|
||||
db.updateIdentity(
|
||||
identityId,
|
||||
identity.getNickname(),
|
||||
identity.getIdent(),
|
||||
identity.getRealName(),
|
||||
identity.getAliases()
|
||||
);
|
||||
|
||||
db.setChannels(serverId, channels);
|
||||
db.setCommands(serverId, commands);
|
||||
|
||||
db.close();
|
||||
|
||||
server.setId(this.server.getId());
|
||||
server.setIdentity(identity);
|
||||
server.setAutoJoinChannels(channels);
|
||||
server.setConnectCommands(commands);
|
||||
|
||||
Yaaic.getInstance().updateServer(server);
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate a server object from the data in the view
|
||||
*
|
||||
* @return The server object
|
||||
*/
|
||||
private Server getServerFromView()
|
||||
{
|
||||
String title = ((EditText) findViewById(R.id.title)).getText().toString().trim();
|
||||
String host = ((EditText) findViewById(R.id.host)).getText().toString().trim();
|
||||
int port = Integer.parseInt(((EditText) findViewById(R.id.port)).getText().toString().trim());
|
||||
String password = ((EditText) findViewById(R.id.password)).getText().toString().trim();
|
||||
String charset = ((Spinner) findViewById(R.id.charset)).getSelectedItem().toString();
|
||||
Boolean useSSL = ((CheckBox) findViewById(R.id.useSSL)).isChecked();
|
||||
|
||||
// not in use yet
|
||||
//boolean autoConnect = ((CheckBox) findViewById(R.id.autoconnect)).isChecked();
|
||||
|
||||
Server server = new Server();
|
||||
server.setHost(host);
|
||||
server.setPort(port);
|
||||
server.setPassword(password);
|
||||
server.setTitle(title);
|
||||
server.setCharset(charset);
|
||||
server.setUseSSL(useSSL);
|
||||
server.setStatus(Status.DISCONNECTED);
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate an identity object from the data in the view
|
||||
*
|
||||
* @return The identity object
|
||||
*/
|
||||
private Identity getIdentityFromView()
|
||||
{
|
||||
String nickname = ((EditText) findViewById(R.id.nickname)).getText().toString().trim();
|
||||
String ident = ((EditText) findViewById(R.id.ident)).getText().toString().trim();
|
||||
String realname = ((EditText) findViewById(R.id.realname)).getText().toString().trim();
|
||||
|
||||
Identity identity = new Identity();
|
||||
identity.setNickname(nickname);
|
||||
identity.setIdent(ident);
|
||||
identity.setRealName(realname);
|
||||
|
||||
identity.setAliases(aliases);
|
||||
|
||||
return identity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the input for a server
|
||||
*
|
||||
* @throws ValidationException
|
||||
*/
|
||||
private void validateServer() throws ValidationException
|
||||
{
|
||||
String title = ((EditText) findViewById(R.id.title)).getText().toString();
|
||||
String host = ((EditText) findViewById(R.id.host)).getText().toString();
|
||||
String port = ((EditText) findViewById(R.id.port)).getText().toString();
|
||||
String charset = ((Spinner) findViewById(R.id.charset)).getSelectedItem().toString();
|
||||
|
||||
if (title.trim().equals("")) {
|
||||
throw new ValidationException(getResources().getString(R.string.validation_blank_title));
|
||||
}
|
||||
|
||||
if (host.trim().equals("")) {
|
||||
// XXX: We should use some better host validation
|
||||
throw new ValidationException(getResources().getString(R.string.validation_blank_host));
|
||||
}
|
||||
|
||||
try {
|
||||
Integer.parseInt(port);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new ValidationException(getResources().getString(R.string.validation_invalid_port));
|
||||
}
|
||||
|
||||
try {
|
||||
"".getBytes(charset);
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
throw new ValidationException(getResources().getString(R.string.validation_unsupported_charset));
|
||||
}
|
||||
|
||||
Database db = new Database(this);
|
||||
if (db.isTitleUsed(title) && (server == null || !server.getTitle().equals(title))) {
|
||||
db.close();
|
||||
throw new ValidationException(getResources().getString(R.string.validation_title_used));
|
||||
}
|
||||
db.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the input for a identity
|
||||
*
|
||||
* @throws ValidationException
|
||||
*/
|
||||
private void validateIdentity() throws ValidationException
|
||||
{
|
||||
String nickname = ((EditText) findViewById(R.id.nickname)).getText().toString();
|
||||
String ident = ((EditText) findViewById(R.id.ident)).getText().toString();
|
||||
String realname = ((EditText) findViewById(R.id.realname)).getText().toString();
|
||||
|
||||
if (nickname.trim().equals("")) {
|
||||
throw new ValidationException(getResources().getString(R.string.validation_blank_nickname));
|
||||
}
|
||||
|
||||
if (ident.trim().equals("")) {
|
||||
throw new ValidationException(getResources().getString(R.string.validation_blank_ident));
|
||||
}
|
||||
|
||||
if (realname.trim().equals("")) {
|
||||
throw new ValidationException(getResources().getString(R.string.validation_blank_realname));
|
||||
}
|
||||
|
||||
// RFC 1459: <nick> ::= <letter> { <letter> | <number> | <special> }
|
||||
// <special> ::= '-' | '[' | ']' | '\' | '`' | '^' | '{' | '}'
|
||||
// Chars that are not in RFC 1459 but are supported too:
|
||||
// | and _
|
||||
Pattern nickPattern = Pattern.compile("^[a-zA-Z_][a-zA-Z0-9^\\-`\\[\\]{}|_\\\\]*$");
|
||||
if (!nickPattern.matcher(nickname).matches()) {
|
||||
throw new ValidationException(getResources().getString(R.string.validation_invalid_nickname));
|
||||
}
|
||||
|
||||
// We currently only allow chars, numbers and some special chars for ident
|
||||
Pattern identPattern = Pattern.compile("^[a-zA-Z0-9\\[\\]\\-_/]+$");
|
||||
if (!identPattern.matcher(ident).matches()) {
|
||||
throw new ValidationException(getResources().getString(R.string.validation_invalid_ident));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.activity;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.model.Extra;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||
|
||||
/**
|
||||
* Authentication activity for entering nickserv / sasl usernames and password
|
||||
* for a given server.
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class AuthenticationActivity extends Activity implements OnCheckedChangeListener, OnClickListener
|
||||
{
|
||||
private CheckBox nickservCheckbox;
|
||||
private TextView nickservPasswordLabel;
|
||||
private EditText nickservPasswordEditText;
|
||||
|
||||
private CheckBox saslCheckbox;
|
||||
private TextView saslUsernameLabel;
|
||||
private EditText saslUsernameEditText;
|
||||
private TextView saslPasswordLabel;
|
||||
private EditText saslPasswordEditText;
|
||||
|
||||
/**
|
||||
* On create
|
||||
*/
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
|
||||
setContentView(R.layout.authentication);
|
||||
|
||||
nickservCheckbox = (CheckBox) findViewById(R.id.nickserv_checkbox);
|
||||
nickservPasswordLabel = (TextView) findViewById(R.id.nickserv_label_password);
|
||||
nickservPasswordEditText = (EditText) findViewById(R.id.nickserv_password);
|
||||
|
||||
saslCheckbox = (CheckBox) findViewById(R.id.sasl_checkbox);
|
||||
saslUsernameLabel = (TextView) findViewById(R.id.sasl_label_username);
|
||||
saslUsernameEditText = (EditText) findViewById(R.id.sasl_username);
|
||||
saslPasswordLabel = (TextView) findViewById(R.id.sasl_label_password);
|
||||
saslPasswordEditText = (EditText) findViewById(R.id.sasl_password);
|
||||
|
||||
nickservCheckbox.setOnCheckedChangeListener(this);
|
||||
saslCheckbox.setOnCheckedChangeListener(this);
|
||||
|
||||
Bundle extras = getIntent().getExtras();
|
||||
|
||||
if (extras != null) {
|
||||
String nickservPassword = extras.getString(Extra.NICKSERV_PASSWORD);
|
||||
|
||||
if (nickservPassword != null && nickservPassword.length() > 0) {
|
||||
nickservCheckbox.setChecked(true);
|
||||
nickservPasswordEditText.setText(nickservPassword);
|
||||
}
|
||||
|
||||
String saslUsername = extras.getString(Extra.SASL_USER);
|
||||
String saslPassword = extras.getString(Extra.SASL_PASSWORD);
|
||||
|
||||
if (saslUsername != null && saslUsername.length() > 0) {
|
||||
saslCheckbox.setChecked(true);
|
||||
saslUsernameEditText.setText(saslUsername);
|
||||
saslPasswordEditText.setText(saslPassword);
|
||||
}
|
||||
}
|
||||
|
||||
((Button) findViewById(R.id.ok)).setOnClickListener(this);
|
||||
((Button) findViewById(R.id.cancel)).setOnClickListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* On checkbox changed
|
||||
*/
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||
{
|
||||
switch (buttonView.getId()) {
|
||||
case R.id.nickserv_checkbox:
|
||||
nickservPasswordLabel.setEnabled(isChecked);
|
||||
nickservPasswordEditText.setEnabled(isChecked);
|
||||
|
||||
if (!isChecked) {
|
||||
nickservPasswordEditText.setText("");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case R.id.sasl_checkbox:
|
||||
saslUsernameLabel.setEnabled(isChecked);
|
||||
saslUsernameEditText.setEnabled(isChecked);
|
||||
saslPasswordLabel.setEnabled(isChecked);
|
||||
saslPasswordEditText.setEnabled(isChecked);
|
||||
|
||||
if (!isChecked) {
|
||||
saslUsernameEditText.setText("");
|
||||
saslPasswordEditText.setText("");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On click on button
|
||||
*/
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
switch (v.getId()) {
|
||||
case R.id.ok:
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(Extra.NICKSERV_PASSWORD, nickservPasswordEditText.getText().toString());
|
||||
intent.putExtra(Extra.SASL_USER, saslUsernameEditText.getText().toString());
|
||||
intent.putExtra(Extra.SASL_PASSWORD, saslPasswordEditText.getText().toString());
|
||||
setResult(RESULT_OK, intent);
|
||||
finish();
|
||||
break;
|
||||
|
||||
case R.id.cancel:
|
||||
setResult(RESULT_CANCELED);
|
||||
finish();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2010 Sebastian Kaspari
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
|
@ -17,7 +17,7 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
package org.yaaic.activity;
|
||||
|
||||
import org.yaaic.R;
|
||||
|
@ -38,27 +38,30 @@ import android.widget.EditText;
|
|||
*/
|
||||
public class JoinActivity extends Activity implements OnClickListener
|
||||
{
|
||||
/**
|
||||
* On create
|
||||
*/
|
||||
/**
|
||||
* On create
|
||||
*/
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.join);
|
||||
|
||||
|
||||
((Button) findViewById(R.id.join)).setOnClickListener(this);
|
||||
|
||||
((EditText) findViewById(R.id.channel)).setSelection(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* On click
|
||||
*/
|
||||
public void onClick(View v)
|
||||
{
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra("channel", ((EditText) findViewById(R.id.channel)).getText().toString());
|
||||
setResult(RESULT_OK, intent);
|
||||
finish();
|
||||
}
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra("channel", ((EditText) findViewById(R.id.channel)).getText().toString());
|
||||
setResult(RESULT_OK, intent);
|
||||
finish();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,212 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2015 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.activity;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.app.FragmentTransaction;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.support.v4.widget.DrawerLayout;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.support.v7.app.ActionBarDrawerToggle;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.TypedValue;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.Yaaic;
|
||||
import org.yaaic.fragment.ConversationFragment;
|
||||
import org.yaaic.fragment.OverviewFragment;
|
||||
import org.yaaic.fragment.SettingsFragment;
|
||||
import org.yaaic.irc.IRCBinder;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.model.Extra;
|
||||
import org.yaaic.model.Server;
|
||||
import org.yaaic.model.Status;
|
||||
|
||||
/**
|
||||
* The main activity of Yaaic. We'll add, remove and replace fragments here.
|
||||
*/
|
||||
public class MainActivity extends AppCompatActivity implements YaaicActivity, ServiceConnection {
|
||||
private ActionBarDrawerToggle toggle;
|
||||
private Toolbar toolbar;
|
||||
private DrawerLayout drawer;
|
||||
private IRCBinder binder;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
initializeToolbar();
|
||||
initializeDrawer();
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
onOverview(null);
|
||||
}
|
||||
}
|
||||
|
||||
public void initializeToolbar() {
|
||||
toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
}
|
||||
|
||||
public void initializeDrawer() {
|
||||
drawer = (DrawerLayout) findViewById(R.id.drawer);
|
||||
toggle = new ActionBarDrawerToggle(this, drawer, toolbar, 0, 0);
|
||||
|
||||
drawer.setDrawerListener(toggle);
|
||||
|
||||
LinearLayout serverContainer = (LinearLayout) findViewById(R.id.server_container);
|
||||
|
||||
for (final Server server : Yaaic.getInstance().getServersAsArrayList()) {
|
||||
TextView serverView = (TextView) getLayoutInflater().inflate(R.layout.item_drawer_server, drawer, false);
|
||||
serverView.setText(server.getTitle());
|
||||
|
||||
serverView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
onServerSelected(server);
|
||||
|
||||
drawer.closeDrawers();
|
||||
}
|
||||
});
|
||||
|
||||
serverContainer.addView(serverView, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostCreate(Bundle savedInstanceState) {
|
||||
super.onPostCreate(savedInstanceState);
|
||||
|
||||
toggle.syncState();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
Intent intent = new Intent(this, IRCService.class);
|
||||
intent.setAction(IRCService.ACTION_BACKGROUND);
|
||||
startService(intent);
|
||||
|
||||
bindService(intent, this, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
|
||||
if (binder != null && binder.getService() != null) {
|
||||
binder.getService().checkServiceStatus();
|
||||
}
|
||||
|
||||
unbindService(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (toggle.onOptionsItemSelected(item)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServerSelected(Server server) {
|
||||
Bundle arguments = new Bundle();
|
||||
|
||||
if (server.getStatus() == Status.DISCONNECTED && !server.mayReconnect()) {
|
||||
server.setStatus(Status.PRE_CONNECTING);
|
||||
|
||||
arguments.putBoolean(Extra.CONNECT, true);
|
||||
}
|
||||
|
||||
arguments.putInt(Extra.SERVER_ID, server.getId());
|
||||
|
||||
ConversationFragment fragment = new ConversationFragment();
|
||||
fragment.setArguments(arguments);
|
||||
|
||||
switchToFragment(fragment, ConversationFragment.TRANSACTION_TAG);
|
||||
|
||||
}
|
||||
|
||||
public void onOverview(View view) {
|
||||
switchToFragment(new OverviewFragment(), OverviewFragment.TRANSACTION_TAG);
|
||||
}
|
||||
|
||||
public void onSettings(View view) {
|
||||
switchToFragment(new SettingsFragment(), SettingsFragment.TRANSACTION_TAG);
|
||||
}
|
||||
|
||||
private void switchToFragment(Fragment fragment, String tag) {
|
||||
drawer.closeDrawers();
|
||||
|
||||
getFragmentManager()
|
||||
.beginTransaction()
|
||||
.setCustomAnimations(
|
||||
R.animator.card_flip_right_in, R.animator.card_flip_right_out,
|
||||
R.animator.card_flip_left_in, R.animator.card_flip_left_out)
|
||||
.replace(R.id.container, fragment, tag)
|
||||
.commit();
|
||||
}
|
||||
|
||||
public void onAbout(View view) {
|
||||
drawer.closeDrawers();
|
||||
|
||||
startActivity(new Intent(this, AboutActivity.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IRCBinder getBinder() {
|
||||
return binder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Toolbar getToolbar() {
|
||||
return toolbar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setToolbarTitle(String title) {
|
||||
toolbar.setTitle(title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
binder = (IRCBinder) service;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
binder = null;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2010 Sebastian Kaspari
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
|
@ -17,7 +17,7 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
package org.yaaic.activity;
|
||||
|
||||
import org.yaaic.R;
|
||||
|
@ -35,19 +35,19 @@ import android.widget.TextView;
|
|||
*/
|
||||
public class MessageActivity extends Activity
|
||||
{
|
||||
/**
|
||||
* On create
|
||||
*/
|
||||
/**
|
||||
* On create
|
||||
*/
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
setContentView(R.layout.message);
|
||||
|
||||
((TextView) findViewById(R.id.message)).setText(
|
||||
getIntent().getExtras().getString(Extra.MESSAGE)
|
||||
);
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
setContentView(R.layout.message);
|
||||
|
||||
((TextView) findViewById(R.id.message)).setText(
|
||||
getIntent().getExtras().getString(Extra.MESSAGE)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.activity;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.adapter.UserActionListAdapter;
|
||||
import org.yaaic.model.Extra;
|
||||
|
||||
import android.app.ListActivity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* UserActivity
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class UserActivity extends ListActivity
|
||||
{
|
||||
private String nickname;
|
||||
|
||||
/**
|
||||
* On create
|
||||
*/
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
|
||||
setContentView(R.layout.user);
|
||||
setListAdapter(new UserActionListAdapter());
|
||||
|
||||
nickname = getIntent().getStringExtra(Extra.USER);
|
||||
((TextView) findViewById(R.id.nickname)).setText(nickname);
|
||||
}
|
||||
|
||||
/**
|
||||
* On action selected
|
||||
*/
|
||||
@Override
|
||||
protected void onListItemClick(ListView list, View view, int position, long id)
|
||||
{
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(Extra.ACTION, (int) id);
|
||||
intent.putExtra(Extra.USER, nickname);
|
||||
setResult(RESULT_OK, intent);
|
||||
finish();
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2010 Sebastian Kaspari
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
|
@ -17,9 +17,11 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
package org.yaaic.activity;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.model.Extra;
|
||||
|
||||
|
@ -29,8 +31,8 @@ import android.os.Bundle;
|
|||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
|
||||
/**
|
||||
* User Activity - Shows a list of users in the current channel
|
||||
|
@ -39,30 +41,35 @@ import android.widget.AdapterView.OnItemClickListener;
|
|||
*/
|
||||
public class UsersActivity extends ListActivity implements OnItemClickListener
|
||||
{
|
||||
/**
|
||||
* On create
|
||||
*/
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
|
||||
setContentView(R.layout.users);
|
||||
|
||||
String[] users = getIntent().getExtras().getStringArray(Extra.USERS);
|
||||
getListView().setAdapter(new ArrayAdapter<String>(this, R.layout.useritem, users));
|
||||
getListView().setOnItemClickListener(this);
|
||||
}
|
||||
/**
|
||||
* On create
|
||||
*/
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
|
||||
/**
|
||||
* On user selected
|
||||
*/
|
||||
public void onItemClick(AdapterView<?> list, View item, int position, long id)
|
||||
{
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(Extra.USER, (String) getListView().getAdapter().getItem(position));
|
||||
setResult(RESULT_OK, intent);
|
||||
finish();
|
||||
}
|
||||
setContentView(R.layout.users);
|
||||
|
||||
final String[] users = getIntent().getExtras().getStringArray(Extra.USERS);
|
||||
getListView().setOnItemClickListener(this);
|
||||
|
||||
// Add sorted list of users in own thread to avoid blocking UI
|
||||
// TODO: Move to a background task and show loading indicator while sorting
|
||||
Arrays.sort(users, String.CASE_INSENSITIVE_ORDER);
|
||||
getListView().setAdapter(new ArrayAdapter<String>(UsersActivity.this, R.layout.useritem, users));
|
||||
}
|
||||
|
||||
/**
|
||||
* On user selected
|
||||
*/
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> list, View item, int position, long id)
|
||||
{
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(Extra.USER, (String) getListView().getAdapter().getItem(position));
|
||||
setResult(RESULT_OK, intent);
|
||||
finish();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2015 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.activity;
|
||||
|
||||
import android.support.v7.widget.Toolbar;
|
||||
|
||||
import org.yaaic.irc.IRCBinder;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
/**
|
||||
* Interface for fragments accessing functionality of the main activity.
|
||||
*/
|
||||
public interface YaaicActivity {
|
||||
IRCBinder getBinder();
|
||||
|
||||
Toolbar getToolbar();
|
||||
|
||||
void setToolbarTitle(String title);
|
||||
|
||||
void onServerSelected(Server server);
|
||||
}
|
|
@ -0,0 +1,277 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v4.view.PagerAdapter;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.view.View;
|
||||
|
||||
import org.yaaic.listener.MessageClickListener;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Server;
|
||||
import org.yaaic.view.MessageListView;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* Adapter for displaying a pager of conversations.
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class ConversationPagerAdapter extends PagerAdapter
|
||||
{
|
||||
private final Server server;
|
||||
private LinkedList<ConversationInfo> conversations;
|
||||
private final HashMap<Integer, View> views;
|
||||
|
||||
/**
|
||||
* Container class to remember conversation and view association.
|
||||
*/
|
||||
public class ConversationInfo {
|
||||
public Conversation conv;
|
||||
public MessageListAdapter adapter;
|
||||
public MessageListView view;
|
||||
|
||||
public ConversationInfo(Conversation conv) {
|
||||
this.conv = conv;
|
||||
this.adapter = null;
|
||||
this.view = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link ConversationPagerAdapter} instance.
|
||||
*/
|
||||
public ConversationPagerAdapter(Context context, Server server) {
|
||||
this.server = server;
|
||||
|
||||
conversations = new LinkedList<ConversationInfo>();
|
||||
views = new HashMap<Integer, View>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a conversation to the adapter.
|
||||
*
|
||||
* @param conversation
|
||||
*/
|
||||
public void addConversation(Conversation conversation) {
|
||||
conversations.add(new ConversationInfo(conversation));
|
||||
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the conversation at the given position from the adapter.
|
||||
*
|
||||
* @param position
|
||||
*/
|
||||
public void removeConversation(int position) {
|
||||
conversations.remove(position);
|
||||
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get position of given item.
|
||||
*/
|
||||
@Override
|
||||
public int getItemPosition(Object object)
|
||||
{
|
||||
if (views.containsKey(object)) {
|
||||
return POSITION_UNCHANGED;
|
||||
}
|
||||
|
||||
return POSITION_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get item at position
|
||||
*/
|
||||
public Conversation getItem(int position)
|
||||
{
|
||||
ConversationInfo convInfo = getItemInfo(position);
|
||||
if (convInfo != null) {
|
||||
return convInfo.conv;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the adapter of the {@link MessageListView} at the given position.
|
||||
*
|
||||
* @param position
|
||||
* @return
|
||||
*/
|
||||
public MessageListAdapter getItemAdapter(int position)
|
||||
{
|
||||
ConversationInfo convInfo = getItemInfo(position);
|
||||
if (convInfo != null) {
|
||||
return convInfo.adapter;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the adapter of the {@link MessageListView} for the conversation
|
||||
* with the given name.
|
||||
*
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
public MessageListAdapter getItemAdapter(String name)
|
||||
{
|
||||
return getItemAdapter(getPositionByName(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ConversationInfo on item at position
|
||||
*
|
||||
* @param position
|
||||
*/
|
||||
private ConversationInfo getItemInfo(int position) {
|
||||
if (position >= 0 && position < conversations.size()) {
|
||||
return conversations.get(position);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an item by the channel's name
|
||||
*
|
||||
* @return The item
|
||||
*/
|
||||
public int getPositionByName(String name)
|
||||
{
|
||||
// Optimization - cache field lookups
|
||||
int mSize = conversations.size();
|
||||
LinkedList<ConversationInfo> mItems = this.conversations;
|
||||
|
||||
for (int i = 0; i < mSize; i++) {
|
||||
if (mItems.get(i).conv.getName().equalsIgnoreCase(name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all conversations.
|
||||
*/
|
||||
public void clearConversations()
|
||||
{
|
||||
conversations = new LinkedList<ConversationInfo>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of conversations from this adapter.
|
||||
*/
|
||||
@Override
|
||||
public int getCount()
|
||||
{
|
||||
return conversations.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a page View is associated with a specific key object.
|
||||
*/
|
||||
@Override
|
||||
public boolean isViewFromObject(View view, Object object)
|
||||
{
|
||||
return view == object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a view object for the conversation at the given position.
|
||||
*/
|
||||
@Override
|
||||
public Object instantiateItem(View collection, int position) {
|
||||
// ConversationInfo convInfo = getItemInfo(position);
|
||||
ConversationInfo convInfo = conversations.get(position);
|
||||
View view;
|
||||
|
||||
if (convInfo.view != null) {
|
||||
view = convInfo.view;
|
||||
} else {
|
||||
view = renderConversation(convInfo, collection);
|
||||
}
|
||||
|
||||
views.put(position, view);
|
||||
((ViewPager) collection).addView(view);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the given conversation and return the new view.
|
||||
*
|
||||
* @param convInfo
|
||||
* @param parent
|
||||
* @return
|
||||
*/
|
||||
private MessageListView renderConversation(ConversationInfo convInfo, View parent)
|
||||
{
|
||||
MessageListView list = new MessageListView(parent.getContext());
|
||||
convInfo.view = list;
|
||||
list.setOnItemClickListener(MessageClickListener.getInstance());
|
||||
|
||||
MessageListAdapter adapter = convInfo.adapter;
|
||||
|
||||
if (adapter == null) {
|
||||
adapter = new MessageListAdapter(convInfo.conv, parent.getContext());
|
||||
convInfo.adapter = adapter;
|
||||
}
|
||||
|
||||
|
||||
list.setAdapter(adapter);
|
||||
list.setSelection(adapter.getCount() - 1); // scroll to bottom
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the given view from the adapter and collection.
|
||||
*/
|
||||
@Override
|
||||
public void destroyItem(View collection, int position, Object view) {
|
||||
((ViewPager) collection).removeView((View) view);
|
||||
views.remove(position);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the title for the given position.
|
||||
*/
|
||||
@Override
|
||||
public String getPageTitle(int position)
|
||||
{
|
||||
Conversation conversation = getItem(position);
|
||||
|
||||
if (conversation.getType() == Conversation.TYPE_SERVER) {
|
||||
return server.getTitle();
|
||||
} else {
|
||||
return conversation.getName();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.adapter;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Message;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.DataSetObserver;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* Adapter for (channel) messages in a ListView
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class MessageListAdapter extends BaseAdapter
|
||||
{
|
||||
private final LinkedList<TextView> messages;
|
||||
private final Context context;
|
||||
private int historySize;
|
||||
|
||||
/**
|
||||
* Create a new MessageAdapter
|
||||
*
|
||||
* @param channel
|
||||
* @param context
|
||||
*/
|
||||
public MessageListAdapter(Conversation conversation, Context context)
|
||||
{
|
||||
LinkedList<TextView> messages = new LinkedList<TextView>();
|
||||
|
||||
// Render channel name as first message in channel
|
||||
if (conversation.getType() != Conversation.TYPE_SERVER) {
|
||||
Message header = new Message(conversation.getName());
|
||||
header.setColor(Message.COLOR_RED);
|
||||
messages.add(header.renderTextView(context));
|
||||
}
|
||||
|
||||
// Optimization - cache field lookups
|
||||
LinkedList<Message> mHistory = conversation.getHistory();
|
||||
int mSize = mHistory.size();
|
||||
|
||||
for (int i = 0; i < mSize; i++) {
|
||||
messages.add(mHistory.get(i).renderTextView(context));
|
||||
}
|
||||
|
||||
// XXX: We don't want to clear the buffer, we want to add only
|
||||
// buffered messages that are not already added (history)
|
||||
conversation.clearBuffer();
|
||||
|
||||
this.messages = messages;
|
||||
this.context = context;
|
||||
historySize = conversation.getHistorySize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a message to the list
|
||||
*
|
||||
* @param message
|
||||
*/
|
||||
public void addMessage(Message message)
|
||||
{
|
||||
messages.add(message.renderTextView(context));
|
||||
|
||||
if (messages.size() > historySize) {
|
||||
messages.remove(0);
|
||||
}
|
||||
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a list of messages to the list
|
||||
*
|
||||
* @param messages
|
||||
*/
|
||||
public void addBulkMessages(LinkedList<Message> messages)
|
||||
{
|
||||
LinkedList<TextView> mMessages = this.messages;
|
||||
Context mContext = this.context;
|
||||
int mSize = messages.size();
|
||||
|
||||
for (int i = mSize - 1; i > -1; i--) {
|
||||
mMessages.add(messages.get(i).renderTextView(mContext));
|
||||
|
||||
if (mMessages.size() > historySize) {
|
||||
mMessages.remove(0);
|
||||
}
|
||||
}
|
||||
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of items
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int getCount()
|
||||
{
|
||||
return messages.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get item at given position
|
||||
*
|
||||
* @param position
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public TextView getItem(int position)
|
||||
{
|
||||
return messages.get(position);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get id of item at given position
|
||||
*
|
||||
* @param position
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public long getItemId(int position)
|
||||
{
|
||||
return position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get item view for the given position
|
||||
*
|
||||
* @param position
|
||||
* @param convertView
|
||||
* @param parent
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent)
|
||||
{
|
||||
return getItem(position);
|
||||
}
|
||||
|
||||
/**
|
||||
* XXX This is almost certainly covering up a bug elsewhere -- find it!
|
||||
*/
|
||||
@Override
|
||||
public void unregisterDataSetObserver(DataSetObserver observer) {
|
||||
if (observer == null) {
|
||||
return;
|
||||
}
|
||||
super.unregisterDataSetObserver(observer);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.adapter;
|
||||
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.Yaaic;
|
||||
import org.yaaic.menu.ServerPopupMenu;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* RecyclerView adapter for server cards.
|
||||
*/
|
||||
public class ServersAdapter extends RecyclerView.Adapter<ServersAdapter.ViewHolder> {
|
||||
public interface ClickListener {
|
||||
void onServerSelected(Server server);
|
||||
void onConnectToServer(Server server);
|
||||
void onDisconnectFromServer(Server server);
|
||||
void onEditServer(Server server);
|
||||
void onDeleteServer(Server server);
|
||||
}
|
||||
|
||||
public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
public final TextView titleView;
|
||||
public final TextView hostView;
|
||||
public final ImageView connectionView;
|
||||
public final View menuView;
|
||||
public final ServerPopupMenu popupMenu;
|
||||
|
||||
public ViewHolder(View view, ClickListener listener) {
|
||||
super(view);
|
||||
|
||||
titleView = (TextView) view.findViewById(R.id.title);
|
||||
hostView = (TextView) view.findViewById(R.id.host);
|
||||
connectionView = (ImageView) view.findViewById(R.id.connection);
|
||||
menuView = view.findViewById(R.id.menu);
|
||||
|
||||
popupMenu = new ServerPopupMenu(
|
||||
view.getContext(), view.findViewById(R.id.menu),
|
||||
listener
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Server> servers;
|
||||
private ClickListener listener;
|
||||
|
||||
public ServersAdapter(ClickListener listener) {
|
||||
this.listener = listener;
|
||||
|
||||
loadServers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.
|
||||
from(parent.getContext()).
|
||||
inflate(R.layout.item_server, parent, false);
|
||||
|
||||
return new ViewHolder(view, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(final ViewHolder holder, int position) {
|
||||
final Server server = servers.get(position);
|
||||
|
||||
int colorResource = server.isConnected() ? R.color.connected : R.color.disconnected;
|
||||
int color = holder.itemView.getContext().getResources().getColor(colorResource);
|
||||
|
||||
holder.titleView.setText(server.getTitle());
|
||||
holder.titleView.setTextColor(color);
|
||||
holder.connectionView.setImageResource(
|
||||
server.isConnected()
|
||||
? R.drawable.ic_navigation_server_connected
|
||||
: R.drawable.ic_navigation_server_disconnected
|
||||
);
|
||||
holder.hostView.setText(String.format("%s @ %s : %d",
|
||||
server.getIdentity().getNickname(),
|
||||
server.getHost(),
|
||||
server.getPort()
|
||||
));
|
||||
|
||||
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
listener.onServerSelected(server);
|
||||
}
|
||||
});
|
||||
|
||||
holder.popupMenu.updateServer(server);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load servers from database
|
||||
*
|
||||
* Delegate call to yaaic instance
|
||||
*/
|
||||
public void loadServers() {
|
||||
servers = Yaaic.getInstance().getServersAsArrayList();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return servers.size();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.adapter;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.model.User;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* Adapter for user action lists
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class UserActionListAdapter extends BaseAdapter
|
||||
{
|
||||
/**
|
||||
* Action IDs
|
||||
*/
|
||||
private final int[] actions = {
|
||||
User.ACTION_REPLY,
|
||||
User.ACTION_QUERY,
|
||||
User.ACTION_OP,
|
||||
User.ACTION_DEOP,
|
||||
User.ACTION_VOICE,
|
||||
User.ACTION_DEVOICE,
|
||||
User.ACTION_KICK,
|
||||
User.ACTION_BAN
|
||||
};
|
||||
|
||||
/**
|
||||
* Labels for actions
|
||||
*/
|
||||
private final int[] labels = {
|
||||
R.string.user_action_reply,
|
||||
R.string.user_action_query,
|
||||
R.string.user_action_op,
|
||||
R.string.user_action_deop,
|
||||
R.string.user_action_voice,
|
||||
R.string.user_action_devoice,
|
||||
R.string.user_action_kick,
|
||||
R.string.user_action_ban
|
||||
};
|
||||
|
||||
/**
|
||||
* Icons for actions
|
||||
*/
|
||||
private final int[] icons = {
|
||||
R.drawable.action_reply,
|
||||
R.drawable.action_query,
|
||||
R.drawable.action_op,
|
||||
R.drawable.action_deop,
|
||||
R.drawable.action_voice,
|
||||
R.drawable.action_devoice,
|
||||
R.drawable.action_kick,
|
||||
R.drawable.action_ban,
|
||||
};
|
||||
|
||||
/**
|
||||
* Get number of actions
|
||||
*/
|
||||
@Override
|
||||
public int getCount()
|
||||
{
|
||||
return actions.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get object for given position
|
||||
*/
|
||||
@Override
|
||||
public Object getItem(int position)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get item id for given position
|
||||
*/
|
||||
@Override
|
||||
public long getItemId(int position)
|
||||
{
|
||||
return actions[position];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get view for given position
|
||||
*/
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent)
|
||||
{
|
||||
if (convertView == null) {
|
||||
LayoutInflater inflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
convertView = inflater.inflate(R.layout.actionitem, null);
|
||||
}
|
||||
|
||||
TextView textView = (TextView) convertView.findViewById(R.id.label);
|
||||
ImageView iconView = (ImageView) convertView.findViewById(R.id.icon);
|
||||
|
||||
textView.setText(labels[position]);
|
||||
iconView.setImageResource(icons[position]);
|
||||
|
||||
return convertView;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright (C) 2012 Sebastian Kaspari
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.yaaic.adapter;
|
||||
|
||||
import android.support.v4.view.PagerAdapter;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
/**
|
||||
* Implementation of {@link PagerAdapter} that represents each page as a {@link View}.
|
||||
*
|
||||
* @author Sebastian Kaspari <s.kaspari@gmail.com>
|
||||
*/
|
||||
public abstract class ViewPagerAdapter extends PagerAdapter
|
||||
{
|
||||
/**
|
||||
* Get a View that displays the data at the specified position in the data set.
|
||||
*
|
||||
* @param position The position of the item within the adapter's data set of the item whose view we want.
|
||||
* @param pager The ViewPager that this view will eventually be attached to.
|
||||
*
|
||||
* @return A View corresponding to the data at the specified position.
|
||||
*/
|
||||
public abstract View getView(int position, ViewPager pager);
|
||||
|
||||
/**
|
||||
* Determines whether a page View is associated with a specific key object as
|
||||
* returned by instantiateItem(ViewGroup, int).
|
||||
*
|
||||
* @param view Page View to check for association with object
|
||||
* @param object Object to check for association with view
|
||||
*
|
||||
* @return true if view is associated with the key object object.
|
||||
*/
|
||||
@Override
|
||||
public boolean isViewFromObject(View view, Object object) {
|
||||
return view == object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the page for the given position.
|
||||
*
|
||||
* @param container The containing View in which the page will be shown.
|
||||
* @param position The page position to be instantiated.
|
||||
*
|
||||
* @return Returns an Object representing the new page. This does not need
|
||||
* to be a View, but can be some other container of the page.
|
||||
*/
|
||||
@Override
|
||||
public Object instantiateItem(ViewGroup container, int position) {
|
||||
ViewPager pager = (ViewPager) container;
|
||||
View view = getView(position, pager);
|
||||
|
||||
pager.addView(view);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a page for the given position.
|
||||
*
|
||||
* @param container The containing View from which the page will be removed.
|
||||
* @param position The page position to be removed.
|
||||
* @param view The same object that was returned by instantiateItem(View, int).
|
||||
*/
|
||||
@Override
|
||||
public void destroyItem(ViewGroup container, int position, Object view) {
|
||||
((ViewPager) container).removeView((View) view);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.command;
|
||||
|
||||
import org.yaaic.exception.CommandException;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Base class for commands
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public abstract class BaseHandler
|
||||
{
|
||||
/**
|
||||
* Execute the command
|
||||
*
|
||||
* @param params The params given (0 is the command itself)
|
||||
* @param server The server object
|
||||
* @param channel The channel object or null if no channel is selected
|
||||
* @param service The service with all server connections
|
||||
* @throws CommandException if command couldn't be executed
|
||||
*/
|
||||
public abstract void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException;
|
||||
|
||||
/**
|
||||
* Get the usage description for this command
|
||||
*
|
||||
* @return The usage description
|
||||
*/
|
||||
public abstract String getUsage();
|
||||
|
||||
/**
|
||||
* Get the description for this command
|
||||
*
|
||||
* @param context The current context. Needed for getting string resources
|
||||
* @return
|
||||
*/
|
||||
public abstract String getDescription(Context context);
|
||||
|
||||
/**
|
||||
* Merge params to a string
|
||||
*
|
||||
* @params params The params to merge
|
||||
*/
|
||||
public static String mergeParams(String[] params)
|
||||
{
|
||||
return mergeParams(params, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge params to a string
|
||||
*
|
||||
* @param params The params to merge
|
||||
* @param position Start at given param
|
||||
*/
|
||||
public static String mergeParams(String[] params, int position)
|
||||
{
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
|
||||
for (; position < params.length; position++) {
|
||||
buffer.append(params[position]);
|
||||
buffer.append(" ");
|
||||
}
|
||||
|
||||
return buffer.toString().trim();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,240 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.command;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.yaaic.command.handler.AMsgHandler;
|
||||
import org.yaaic.command.handler.AwayHandler;
|
||||
import org.yaaic.command.handler.BackHandler;
|
||||
import org.yaaic.command.handler.CloseHandler;
|
||||
import org.yaaic.command.handler.DCCHandler;
|
||||
import org.yaaic.command.handler.DeopHandler;
|
||||
import org.yaaic.command.handler.DevoiceHandler;
|
||||
import org.yaaic.command.handler.EchoHandler;
|
||||
import org.yaaic.command.handler.HelpHandler;
|
||||
import org.yaaic.command.handler.JoinHandler;
|
||||
import org.yaaic.command.handler.KickHandler;
|
||||
import org.yaaic.command.handler.MeHandler;
|
||||
import org.yaaic.command.handler.ModeHandler;
|
||||
import org.yaaic.command.handler.MsgHandler;
|
||||
import org.yaaic.command.handler.NamesHandler;
|
||||
import org.yaaic.command.handler.NickHandler;
|
||||
import org.yaaic.command.handler.NoticeHandler;
|
||||
import org.yaaic.command.handler.OpHandler;
|
||||
import org.yaaic.command.handler.PartHandler;
|
||||
import org.yaaic.command.handler.QueryHandler;
|
||||
import org.yaaic.command.handler.QuitHandler;
|
||||
import org.yaaic.command.handler.RawHandler;
|
||||
import org.yaaic.command.handler.TopicHandler;
|
||||
import org.yaaic.command.handler.VoiceHandler;
|
||||
import org.yaaic.command.handler.WhoisHandler;
|
||||
import org.yaaic.exception.CommandException;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.model.Broadcast;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Message;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
import android.content.Intent;
|
||||
|
||||
/**
|
||||
* Parser for commands
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class CommandParser
|
||||
{
|
||||
private final HashMap<String, BaseHandler> commands;
|
||||
private final HashMap<String, String> aliases;
|
||||
private static CommandParser instance;
|
||||
|
||||
/**
|
||||
* Create a new CommandParser instance
|
||||
*/
|
||||
private CommandParser()
|
||||
{
|
||||
commands = new HashMap<String, BaseHandler>();
|
||||
|
||||
// Commands
|
||||
commands.put("nick", new NickHandler());
|
||||
commands.put("join", new JoinHandler());
|
||||
commands.put("me", new MeHandler());
|
||||
commands.put("names", new NamesHandler());
|
||||
commands.put("echo", new EchoHandler());
|
||||
commands.put("topic", new TopicHandler());
|
||||
commands.put("quit", new QuitHandler());
|
||||
commands.put("op", new OpHandler());
|
||||
commands.put("voice", new VoiceHandler());
|
||||
commands.put("deop", new DeopHandler());
|
||||
commands.put("devoice", new DevoiceHandler());
|
||||
commands.put("kick", new KickHandler());
|
||||
commands.put("query", new QueryHandler());
|
||||
commands.put("part", new PartHandler());
|
||||
commands.put("close", new CloseHandler());
|
||||
commands.put("notice", new NoticeHandler());
|
||||
commands.put("dcc", new DCCHandler());
|
||||
commands.put("mode", new ModeHandler());
|
||||
commands.put("help", new HelpHandler());
|
||||
commands.put("away", new AwayHandler());
|
||||
commands.put("back", new BackHandler());
|
||||
commands.put("whois", new WhoisHandler());
|
||||
commands.put("msg", new MsgHandler());
|
||||
commands.put("quote", new RawHandler());
|
||||
commands.put("amsg", new AMsgHandler());
|
||||
|
||||
aliases = new HashMap<String, String>();
|
||||
|
||||
// Aliases
|
||||
aliases.put("j","join");
|
||||
aliases.put("q", "query");
|
||||
aliases.put("h", "help");
|
||||
aliases.put("raw", "quote");
|
||||
aliases.put("w", "whois");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the global CommandParser instance
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static synchronized CommandParser getInstance()
|
||||
{
|
||||
if (instance == null) {
|
||||
instance = new CommandParser();
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the commands HashMap
|
||||
*
|
||||
* @return HashMap - command, commandHandler
|
||||
*/
|
||||
public HashMap<String, BaseHandler> getCommands()
|
||||
{
|
||||
return commands;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the command aliases HashMap
|
||||
*
|
||||
* @return HashMap - alias, command the alias belogs to
|
||||
*/
|
||||
public HashMap<String, String> getAliases()
|
||||
{
|
||||
return aliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the given command a valid client command?
|
||||
*
|
||||
* @param command The (client) command to check (/command)
|
||||
* @return true if the command can be handled by the client, false otherwise
|
||||
*/
|
||||
public boolean isClientCommand(String command)
|
||||
{
|
||||
return commands.containsKey(command.toLowerCase()) || aliases.containsKey(command.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a client command
|
||||
*
|
||||
* @param type Type of the command (/type param1 param2 ..)
|
||||
* @param params The parameters of the command (0 is the command itself)
|
||||
* @param server The current server
|
||||
* @param conversation The selected conversation
|
||||
* @param service The service handling the connections
|
||||
*/
|
||||
public void handleClientCommand(String type, String[] params, Server server, Conversation conversation, IRCService service)
|
||||
{
|
||||
BaseHandler command = null;
|
||||
|
||||
if (commands.containsKey(type.toLowerCase())) {
|
||||
command = commands.get(type.toLowerCase());
|
||||
} else if (aliases.containsKey(type.toLowerCase())) {
|
||||
String commandInCommands = aliases.get(type.toLowerCase());
|
||||
command = commands.get(commandInCommands);
|
||||
}
|
||||
|
||||
try {
|
||||
command.execute(params, server, conversation, service);
|
||||
} catch(CommandException e) {
|
||||
// Command could not be executed
|
||||
if (conversation != null) {
|
||||
Message errorMessage = new Message(type + ": " + e.getMessage());
|
||||
errorMessage.setColor(Message.COLOR_RED);
|
||||
conversation.addMessage(errorMessage);
|
||||
|
||||
// XXX:I18N - How to get a context here? (command_syntax)
|
||||
Message usageMessage = new Message("Syntax: " + command.getUsage());
|
||||
conversation.addMessage(usageMessage);
|
||||
|
||||
Intent intent = Broadcast.createConversationIntent(
|
||||
Broadcast.CONVERSATION_MESSAGE,
|
||||
server.getId(),
|
||||
conversation.getName()
|
||||
);
|
||||
|
||||
service.sendBroadcast(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a server command
|
||||
*
|
||||
* @param type Type of the command (/type param1 param2 ..)
|
||||
* @param params The parameters of the command (0 is the command itself)
|
||||
* @param server The current server
|
||||
* @param conversation The selected conversation
|
||||
* @param service The service handling the connections
|
||||
*/
|
||||
public void handleServerCommand(String type, String[] params, Server server, Conversation conversation, IRCService service)
|
||||
{
|
||||
if (params.length > 1) {
|
||||
service.getConnection(server.getId()).sendRawLineViaQueue(
|
||||
type.toUpperCase() + " " + BaseHandler.mergeParams(params)
|
||||
);
|
||||
} else {
|
||||
service.getConnection(server.getId()).sendRawLineViaQueue(type.toUpperCase());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given line
|
||||
*
|
||||
* @param line
|
||||
*/
|
||||
public void parse(String line, Server server, Conversation conversation, IRCService service)
|
||||
{
|
||||
line = line.trim().substring(1); // cut the slash
|
||||
String[] params = line.split(" ");
|
||||
String type = params[0];
|
||||
|
||||
if (isClientCommand(type)) {
|
||||
handleClientCommand(type, params, server, conversation, service);
|
||||
} else {
|
||||
handleServerCommand(type, params, server, conversation, service);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.command.handler;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.command.BaseHandler;
|
||||
import org.yaaic.exception.CommandException;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.model.Broadcast;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Message;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
/**
|
||||
* Command: /amsg <message>
|
||||
*
|
||||
* Send a message to all channels on the server
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class AMsgHandler extends BaseHandler
|
||||
{
|
||||
/**
|
||||
* Execute /amsg
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (params.length > 1) {
|
||||
String text = BaseHandler.mergeParams(params);
|
||||
|
||||
Collection<Conversation> mConversations = server.getConversations();
|
||||
|
||||
for (Conversation currentConversation : mConversations) {
|
||||
if (currentConversation.getType() == Conversation.TYPE_CHANNEL) {
|
||||
Message message = new Message("<" + service.getConnection(server.getId()).getNick() + "> " + text);
|
||||
currentConversation.addMessage(message);
|
||||
|
||||
Intent intent = Broadcast.createConversationIntent(
|
||||
Broadcast.CONVERSATION_MESSAGE,
|
||||
server.getId(),
|
||||
currentConversation.getName()
|
||||
);
|
||||
|
||||
service.sendBroadcast(intent);
|
||||
|
||||
service.getConnection(server.getId()).sendMessage(currentConversation.getName(), text);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new CommandException(service.getString(R.string.invalid_number_of_params));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage of /amsg
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/amsg <message>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of /amsg
|
||||
*/
|
||||
@Override
|
||||
public String getDescription(Context context)
|
||||
{
|
||||
return context.getString(R.string.command_desc_amsg);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2010 Sebastian Kaspari
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
|
@ -17,15 +17,18 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
package org.yaaic.command.handler;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.command.BaseHandler;
|
||||
import org.yaaic.exception.CommandException;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Command: /away [<reason>]
|
||||
*
|
||||
|
@ -35,30 +38,30 @@ import org.yaaic.model.Server;
|
|||
*/
|
||||
public class AwayHandler extends BaseHandler
|
||||
{
|
||||
/**
|
||||
* Execute /away
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
service.getConnection(server.getId()).sendRawLineViaQueue("AWAY " + BaseHandler.mergeParams(params));
|
||||
}
|
||||
/**
|
||||
* Execute /away
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
service.getConnection(server.getId()).sendRawLineViaQueue("AWAY " + BaseHandler.mergeParams(params));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get description of /away
|
||||
*/
|
||||
@Override
|
||||
public String getDescription()
|
||||
{
|
||||
return "Sets you away";
|
||||
}
|
||||
/**
|
||||
* Get description of /away
|
||||
*/
|
||||
@Override
|
||||
public String getDescription(Context context)
|
||||
{
|
||||
return context.getString(R.string.command_desc_away);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get usage of /away
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/away [<reason>]";
|
||||
}
|
||||
/**
|
||||
* Get usage of /away
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/away [<reason>]";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.command.handler;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.command.BaseHandler;
|
||||
import org.yaaic.exception.CommandException;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Command: /back
|
||||
*
|
||||
* Turn off the away status
|
||||
*
|
||||
* @author Francesco Lavra <francescola...@interfree.it>
|
||||
*/
|
||||
public class BackHandler extends BaseHandler
|
||||
{
|
||||
/**
|
||||
* Execute /back
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
service.getConnection(server.getId()).sendRawLineViaQueue("AWAY");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get description of /back
|
||||
*/
|
||||
@Override
|
||||
public String getDescription(Context context)
|
||||
{
|
||||
return context.getString(R.string.command_desc_back);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get usage of /back
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/back";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.command.handler;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.command.BaseHandler;
|
||||
import org.yaaic.exception.CommandException;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.model.Broadcast;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
/**
|
||||
* Command: /close
|
||||
*
|
||||
* Closes the current window
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class CloseHandler extends BaseHandler
|
||||
{
|
||||
/**
|
||||
* Execute /close
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (conversation.getType() == Conversation.TYPE_SERVER) {
|
||||
throw new CommandException(service.getString(R.string.close_server_window));
|
||||
}
|
||||
|
||||
if (params.length == 1) {
|
||||
if (conversation.getType() == Conversation.TYPE_CHANNEL) {
|
||||
service.getConnection(server.getId()).partChannel(conversation.getName());
|
||||
}
|
||||
if (conversation.getType() == Conversation.TYPE_QUERY) {
|
||||
server.removeConversation(conversation.getName());
|
||||
|
||||
Intent intent = Broadcast.createConversationIntent(
|
||||
Broadcast.CONVERSATION_REMOVE,
|
||||
server.getId(),
|
||||
conversation.getName()
|
||||
);
|
||||
service.sendBroadcast(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage of /close
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/close";
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of /close
|
||||
*/
|
||||
@Override
|
||||
public String getDescription(Context context)
|
||||
{
|
||||
return context.getString(R.string.command_desc_close);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.command.handler;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.command.BaseHandler;
|
||||
import org.yaaic.exception.CommandException;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.model.Broadcast;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Message;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Command: /dcc SEND <nickname> <file>
|
||||
*
|
||||
* Send a file to a user
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class DCCHandler extends BaseHandler
|
||||
{
|
||||
/**
|
||||
* Execute /dcc
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (params.length == 4) {
|
||||
if (!params[1].equalsIgnoreCase("SEND")) {
|
||||
throw new CommandException(service.getString(R.string.dcc_only_send));
|
||||
}
|
||||
File file = new File(params[3]);
|
||||
if (!file.exists()) {
|
||||
throw new CommandException(service.getString(R.string.dcc_file_not_found, params[3]));
|
||||
}
|
||||
|
||||
service.getConnection(server.getId()).dccSendFile(file, params[2], 60000);
|
||||
|
||||
Message message = new Message(service.getString(R.string.dcc_waiting_accept, params[2]));
|
||||
message.setColor(Message.COLOR_GREY);
|
||||
conversation.addMessage(message);
|
||||
|
||||
service.sendBroadcast(
|
||||
Broadcast.createConversationIntent(Broadcast.CONVERSATION_MESSAGE, server.getId(), conversation.getName())
|
||||
);
|
||||
} else {
|
||||
throw new CommandException(service.getString(R.string.invalid_number_of_params));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage of /dcc
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/dcc SEND <nickname> <file>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of /dcc
|
||||
*/
|
||||
@Override
|
||||
public String getDescription(Context context)
|
||||
{
|
||||
return context.getString(R.string.command_desc_dcc);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.command.handler;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.command.BaseHandler;
|
||||
import org.yaaic.exception.CommandException;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Command: /deop <nickname>
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class DeopHandler extends BaseHandler
|
||||
{
|
||||
/**
|
||||
* Execute /deop
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (conversation.getType() != Conversation.TYPE_CHANNEL) {
|
||||
throw new CommandException(service.getString(R.string.only_usable_from_channel));
|
||||
}
|
||||
|
||||
if (params.length == 2) {
|
||||
service.getConnection(server.getId()).deOp(conversation.getName(), params[1]);
|
||||
} else {
|
||||
throw new CommandException(service.getString(R.string.invalid_number_of_params));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage of /deop
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/deop <nickname>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of /deop
|
||||
*/
|
||||
@Override
|
||||
public String getDescription(Context context)
|
||||
{
|
||||
return context.getString(R.string.command_desc_deop);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2010 Sebastian Kaspari
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
|
@ -17,15 +17,18 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
package org.yaaic.command.handler;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.command.BaseHandler;
|
||||
import org.yaaic.exception.CommandException;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Command: /devoice <nickname>
|
||||
*
|
||||
|
@ -33,38 +36,38 @@ import org.yaaic.model.Server;
|
|||
*/
|
||||
public class DevoiceHandler extends BaseHandler
|
||||
{
|
||||
/**
|
||||
* Execute /devoice
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (conversation.getType() != Conversation.TYPE_CHANNEL) {
|
||||
throw new CommandException("Only usable from within a channel");
|
||||
}
|
||||
|
||||
if (params.length == 2) {
|
||||
service.getConnection(server.getId()).deVoice(conversation.getName(), params[1]);
|
||||
} else {
|
||||
throw new CommandException("Invalid number of params");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage of /devoice
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/devoice <nickname>";
|
||||
}
|
||||
/**
|
||||
* Execute /devoice
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (conversation.getType() != Conversation.TYPE_CHANNEL) {
|
||||
throw new CommandException(service.getString(R.string.only_usable_from_channel));
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of /devoice
|
||||
*/
|
||||
@Override
|
||||
public String getDescription()
|
||||
{
|
||||
return "Remove voice status from a user";
|
||||
}
|
||||
if (params.length == 2) {
|
||||
service.getConnection(server.getId()).deVoice(conversation.getName(), params[1]);
|
||||
} else {
|
||||
throw new CommandException(service.getString(R.string.invalid_number_of_params));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage of /devoice
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/devoice <nickname>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of /devoice
|
||||
*/
|
||||
@Override
|
||||
public String getDescription(Context context)
|
||||
{
|
||||
return context.getString(R.string.command_desc_devoice);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2010 Sebastian Kaspari
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
|
@ -17,9 +17,10 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
package org.yaaic.command.handler;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.command.BaseHandler;
|
||||
import org.yaaic.exception.CommandException;
|
||||
import org.yaaic.irc.IRCService;
|
||||
|
@ -28,6 +29,7 @@ import org.yaaic.model.Conversation;
|
|||
import org.yaaic.model.Message;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
/**
|
||||
|
@ -37,42 +39,42 @@ import android.content.Intent;
|
|||
*/
|
||||
public class EchoHandler extends BaseHandler
|
||||
{
|
||||
/**
|
||||
* Execute /echo
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (params.length > 1) {
|
||||
Message message = new Message(BaseHandler.mergeParams(params));
|
||||
conversation.addMessage(message);
|
||||
|
||||
Intent intent = Broadcast.createConversationIntent(
|
||||
Broadcast.CONVERSATION_MESSAGE,
|
||||
server.getId(),
|
||||
conversation.getName()
|
||||
);
|
||||
service.sendBroadcast(intent);
|
||||
} else {
|
||||
throw new CommandException("Text is missing");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage of /echo
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/echo <text>";
|
||||
}
|
||||
/**
|
||||
* Execute /echo
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (params.length > 1) {
|
||||
Message message = new Message(BaseHandler.mergeParams(params));
|
||||
conversation.addMessage(message);
|
||||
|
||||
/**
|
||||
* Description of /echo
|
||||
*/
|
||||
@Override
|
||||
public String getDescription()
|
||||
{
|
||||
return "Print text to window";
|
||||
}
|
||||
Intent intent = Broadcast.createConversationIntent(
|
||||
Broadcast.CONVERSATION_MESSAGE,
|
||||
server.getId(),
|
||||
conversation.getName()
|
||||
);
|
||||
service.sendBroadcast(intent);
|
||||
} else {
|
||||
throw new CommandException(service.getString(R.string.text_missing));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage of /echo
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/echo <text>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of /echo
|
||||
*/
|
||||
@Override
|
||||
public String getDescription(Context context)
|
||||
{
|
||||
return context.getString(R.string.command_desc_echo);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.command.handler;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.command.BaseHandler;
|
||||
import org.yaaic.command.CommandParser;
|
||||
import org.yaaic.exception.CommandException;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.model.Broadcast;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Message;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
/**
|
||||
* Command: /help
|
||||
*
|
||||
* @author Karol Gliniecki <karol.gliniecki@googlemail.com>
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class HelpHandler extends BaseHandler
|
||||
{
|
||||
/**
|
||||
* Execute /help
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (params.length == 2) {
|
||||
showCommandDetails(service, server, conversation, params[1]);
|
||||
} else if (params.length == 1) {
|
||||
showAllCommands(service, server, conversation);
|
||||
} else {
|
||||
throw new CommandException(service.getString(R.string.invalid_number_of_params));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show all available commands
|
||||
*
|
||||
* @param conversation
|
||||
* @param server
|
||||
* @param service
|
||||
*/
|
||||
private void showAllCommands(IRCService service, Server server, Conversation conversation)
|
||||
{
|
||||
CommandParser cp = CommandParser.getInstance();
|
||||
|
||||
StringBuffer commandList = new StringBuffer(service.getString(R.string.available_commands));
|
||||
commandList.append("\n");
|
||||
|
||||
HashMap<String, BaseHandler> commands = cp.getCommands();
|
||||
HashMap<String, String> aliases = cp.getAliases();
|
||||
|
||||
Set<String> commandKeys = commands.keySet();
|
||||
Set<String> aliasesKeys = aliases.keySet();
|
||||
|
||||
for (Object command : commandKeys) {
|
||||
String alias = "";
|
||||
for (Object aliasCommand : aliasesKeys) {
|
||||
if (command.equals(aliases.get(aliasCommand))) {
|
||||
alias = " " + service.getString(R.string.logical_or) + " /" + aliasCommand;
|
||||
break;
|
||||
}
|
||||
}
|
||||
commandList.append("/" + command.toString() + alias + " - "+commands.get(command).getDescription(service) + "\n");
|
||||
}
|
||||
|
||||
Message message = new Message(commandList.toString());
|
||||
message.setColor(Message.COLOR_YELLOW);
|
||||
conversation.addMessage(message);
|
||||
|
||||
Intent intent = Broadcast.createConversationIntent(
|
||||
Broadcast.CONVERSATION_MESSAGE,
|
||||
server.getId(),
|
||||
conversation.getName()
|
||||
);
|
||||
|
||||
service.sendBroadcast(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show details of a single command
|
||||
*
|
||||
* @param conversation
|
||||
* @param server
|
||||
* @param service
|
||||
* @param command
|
||||
* @throws CommandException
|
||||
*/
|
||||
private void showCommandDetails(IRCService service, Server server, Conversation conversation, String command) throws CommandException
|
||||
{
|
||||
CommandParser cp = CommandParser.getInstance();
|
||||
HashMap<String, BaseHandler> commands = cp.getCommands();
|
||||
|
||||
if (commands.containsKey(command)) {
|
||||
// XXX:I18N - String building salad :)
|
||||
Message message = new Message("Help of /" + command + "\n" + commands.get(command).getUsage() + "\n" + commands.get(command).getDescription(service) + "\n");
|
||||
message.setColor(Message.COLOR_YELLOW);
|
||||
conversation.addMessage(message);
|
||||
|
||||
Intent intent = Broadcast.createConversationIntent(
|
||||
Broadcast.CONVERSATION_MESSAGE,
|
||||
server.getId(),
|
||||
conversation.getName()
|
||||
);
|
||||
|
||||
service.sendBroadcast(intent);
|
||||
} else {
|
||||
throw new CommandException(service.getString(R.string.unknown_command, command));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage of /help
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/help [<command>]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of /help
|
||||
*/
|
||||
@Override
|
||||
public String getDescription(Context context)
|
||||
{
|
||||
return context.getString(R.string.command_desc_help);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2010 Sebastian Kaspari
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
|
@ -17,15 +17,18 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
package org.yaaic.command.handler;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.command.BaseHandler;
|
||||
import org.yaaic.exception.CommandException;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Command: /join <channel> [<key>]
|
||||
*
|
||||
|
@ -33,36 +36,36 @@ import org.yaaic.model.Server;
|
|||
*/
|
||||
public class JoinHandler extends BaseHandler
|
||||
{
|
||||
/**
|
||||
* Execute /join
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (params.length == 2) {
|
||||
service.getConnection(server.getId()).joinChannel(params[1]);
|
||||
} else if (params.length == 3) {
|
||||
service.getConnection(server.getId()).joinChannel(params[1], params[2]);
|
||||
} else {
|
||||
throw new CommandException("Invalid number of params");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage of /join
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/join <channel> [<key>]";
|
||||
}
|
||||
/**
|
||||
* Execute /join
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (params.length == 2) {
|
||||
service.getConnection(server.getId()).joinChannel(params[1]);
|
||||
} else if (params.length == 3) {
|
||||
service.getConnection(server.getId()).joinChannel(params[1], params[2]);
|
||||
} else {
|
||||
throw new CommandException(service.getString(R.string.invalid_number_of_params));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of /join
|
||||
*/
|
||||
@Override
|
||||
public String getDescription()
|
||||
{
|
||||
return "Join a channel";
|
||||
}
|
||||
/**
|
||||
* Usage of /join
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/join <channel> [<key>]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of /join
|
||||
*/
|
||||
@Override
|
||||
public String getDescription(Context context)
|
||||
{
|
||||
return context.getString(R.string.command_desc_join);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2010 Sebastian Kaspari
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
|
@ -17,15 +17,18 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
package org.yaaic.command.handler;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.command.BaseHandler;
|
||||
import org.yaaic.exception.CommandException;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Command: /kick <nickname>
|
||||
*
|
||||
|
@ -35,38 +38,38 @@ import org.yaaic.model.Server;
|
|||
*/
|
||||
public class KickHandler extends BaseHandler
|
||||
{
|
||||
/**
|
||||
* Execute /kick
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (conversation.getType() != Conversation.TYPE_CHANNEL) {
|
||||
throw new CommandException("Only usable from within a channel");
|
||||
}
|
||||
|
||||
if (params.length == 2) {
|
||||
service.getConnection(server.getId()).kick(conversation.getName(), params[1]);
|
||||
} else {
|
||||
throw new CommandException("Invalid number of params");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage of /kick
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/kick <nickname>";
|
||||
}
|
||||
/**
|
||||
* Execute /kick
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (conversation.getType() != Conversation.TYPE_CHANNEL) {
|
||||
throw new CommandException(service.getString(R.string.only_usable_from_channel));
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of /kick
|
||||
*/
|
||||
@Override
|
||||
public String getDescription()
|
||||
{
|
||||
return "Kicks a user";
|
||||
}
|
||||
if (params.length == 2) {
|
||||
service.getConnection(server.getId()).kick(conversation.getName(), params[1]);
|
||||
} else {
|
||||
throw new CommandException(service.getString(R.string.invalid_number_of_params));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage of /kick
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/kick <nickname>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of /kick
|
||||
*/
|
||||
@Override
|
||||
public String getDescription(Context context)
|
||||
{
|
||||
return context.getString(R.string.command_desc_kick);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.command.handler;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.command.BaseHandler;
|
||||
import org.yaaic.exception.CommandException;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.model.Broadcast;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Message;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
/**
|
||||
* Command: /me <action>
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class MeHandler extends BaseHandler
|
||||
{
|
||||
/**
|
||||
* Execute /me
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (conversation.getType() == Conversation.TYPE_SERVER) {
|
||||
throw new CommandException(service.getString(R.string.only_usable_from_channel_or_query));
|
||||
}
|
||||
|
||||
if (params.length > 1) {
|
||||
String action = BaseHandler.mergeParams(params);
|
||||
String nickname = service.getConnection(server.getId()).getNick();
|
||||
|
||||
Message message = new Message(nickname + " " + action);
|
||||
message.setIcon(R.drawable.action);
|
||||
server.getConversation(conversation.getName()).addMessage(message);
|
||||
|
||||
Intent intent = Broadcast.createConversationIntent(
|
||||
Broadcast.CONVERSATION_MESSAGE,
|
||||
server.getId(),
|
||||
conversation.getName()
|
||||
);
|
||||
service.sendBroadcast(intent);
|
||||
|
||||
service.getConnection(server.getId()).sendAction(conversation.getName(), action);
|
||||
} else {
|
||||
throw new CommandException(service.getString(R.string.text_missing));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage of /me
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/me <text>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of /me
|
||||
*/
|
||||
@Override
|
||||
public String getDescription(Context context)
|
||||
{
|
||||
return context.getString(R.string.command_desc_me);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2010 Sebastian Kaspari
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
|
@ -17,15 +17,18 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
package org.yaaic.command.handler;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.command.BaseHandler;
|
||||
import org.yaaic.exception.CommandException;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Command: /mode <channel> <mode>
|
||||
*
|
||||
|
@ -35,36 +38,36 @@ import org.yaaic.model.Server;
|
|||
*/
|
||||
public class ModeHandler extends BaseHandler
|
||||
{
|
||||
/**
|
||||
* Execute /mode
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (params.length > 2) {
|
||||
String modes = BaseHandler.mergeParams(params, 2);
|
||||
|
||||
service.getConnection(server.getId()).setMode(params[1], modes);
|
||||
} else {
|
||||
throw new CommandException("Invalid number of params");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage of /mode
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/mode <channel> <mode>";
|
||||
}
|
||||
/**
|
||||
* Execute /mode
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (params.length > 2) {
|
||||
String modes = BaseHandler.mergeParams(params, 2);
|
||||
|
||||
/**
|
||||
* Description of /mode
|
||||
*/
|
||||
@Override
|
||||
public String getDescription()
|
||||
{
|
||||
return "Change channel modes";
|
||||
}
|
||||
service.getConnection(server.getId()).setMode(params[1], modes);
|
||||
} else {
|
||||
throw new CommandException(service.getString(R.string.invalid_number_of_params));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage of /mode
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/mode <channel> <mode>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of /mode
|
||||
*/
|
||||
@Override
|
||||
public String getDescription(Context context)
|
||||
{
|
||||
return context.getString(R.string.command_desc_mode);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.command.handler;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.command.BaseHandler;
|
||||
import org.yaaic.exception.CommandException;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.model.Broadcast;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Message;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
/**
|
||||
* Command: /msg <target> <message>
|
||||
*
|
||||
* Send a message to a channel or user
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class MsgHandler extends BaseHandler
|
||||
{
|
||||
/**
|
||||
* Execute /msg
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (params.length > 2) {
|
||||
String text = BaseHandler.mergeParams(params, 2);
|
||||
service.getConnection(server.getId()).sendMessage(params[1], text);
|
||||
|
||||
Conversation targetConversation = server.getConversation(params[1]);
|
||||
|
||||
if (targetConversation != null) {
|
||||
Message message = new Message("<" + service.getConnection(server.getId()).getNick() + "> " + text);
|
||||
targetConversation.addMessage(message);
|
||||
|
||||
Intent intent = Broadcast.createConversationIntent(
|
||||
Broadcast.CONVERSATION_MESSAGE,
|
||||
server.getId(),
|
||||
targetConversation.getName()
|
||||
);
|
||||
|
||||
service.sendBroadcast(intent);
|
||||
}
|
||||
} else {
|
||||
throw new CommandException(service.getString(R.string.invalid_number_of_params));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage of /msg
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/msg <target> <message>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of /msg
|
||||
*/
|
||||
@Override
|
||||
public String getDescription(Context context)
|
||||
{
|
||||
return context.getString(R.string.command_desc_msg);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.command.handler;
|
||||
|
||||
import org.jibble.pircbot.User;
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.command.BaseHandler;
|
||||
import org.yaaic.exception.CommandException;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.model.Broadcast;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Message;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
/**
|
||||
* Command: /names
|
||||
* Lists all users currently in the selected channel
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class NamesHandler extends BaseHandler
|
||||
{
|
||||
/**
|
||||
* Execute /names
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (conversation.getType() != Conversation.TYPE_CHANNEL) {
|
||||
throw new CommandException(service.getString(R.string.only_usable_from_channel));
|
||||
}
|
||||
|
||||
StringBuffer userList = new StringBuffer(service.getString(R.string.message_users_on_chan, conversation.getName()));
|
||||
|
||||
User[] mUsers = service.getConnection(server.getId()).getUsers(conversation.getName());
|
||||
int mSize = mUsers.length;
|
||||
for (int i = 0; i < mSize; i++) {
|
||||
userList.append(" ");
|
||||
userList.append(mUsers[i].getPrefix());
|
||||
userList.append(mUsers[i].getNick());
|
||||
}
|
||||
|
||||
Message message = new Message(userList.toString());
|
||||
message.setColor(Message.COLOR_YELLOW);
|
||||
conversation.addMessage(message);
|
||||
|
||||
Intent intent = Broadcast.createConversationIntent(
|
||||
Broadcast.CONVERSATION_MESSAGE,
|
||||
server.getId(),
|
||||
conversation.getName()
|
||||
);
|
||||
service.sendBroadcast(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage of /names
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/names";
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of /names
|
||||
*/
|
||||
@Override
|
||||
public String getDescription(Context context)
|
||||
{
|
||||
return context.getString(R.string.command_desc_names);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2010 Sebastian Kaspari
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
|
@ -17,15 +17,18 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
package org.yaaic.command.handler;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.command.BaseHandler;
|
||||
import org.yaaic.exception.CommandException;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Command: /nick <nickname>
|
||||
*
|
||||
|
@ -33,34 +36,34 @@ import org.yaaic.model.Server;
|
|||
*/
|
||||
public class NickHandler extends BaseHandler
|
||||
{
|
||||
/**
|
||||
* Execute /nick
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (params.length == 2) {
|
||||
service.getConnection(server.getId()).changeNick(params[1]);
|
||||
} else {
|
||||
throw new CommandException("Invalid number of params");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage of /nick
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/nick <nickname>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of /nick
|
||||
*/
|
||||
@Override
|
||||
public String getDescription()
|
||||
{
|
||||
return "change own nickname";
|
||||
}
|
||||
/**
|
||||
* Execute /nick
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (params.length == 2) {
|
||||
service.getConnection(server.getId()).changeNick(params[1]);
|
||||
} else {
|
||||
throw new CommandException(service.getString(R.string.invalid_number_of_params));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage of /nick
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/nick <nickname>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of /nick
|
||||
*/
|
||||
@Override
|
||||
public String getDescription(Context context)
|
||||
{
|
||||
return context.getString(R.string.command_desc_nick);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.command.handler;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.command.BaseHandler;
|
||||
import org.yaaic.exception.CommandException;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.model.Broadcast;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Message;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
/**
|
||||
* Command: /notice <nickname> <message>
|
||||
*
|
||||
* Send a notice to an other user
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class NoticeHandler extends BaseHandler
|
||||
{
|
||||
/**
|
||||
* Execute /notice
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (params.length > 2) {
|
||||
String text = BaseHandler.mergeParams(params);
|
||||
|
||||
Message message = new Message(">" + params[1] + "< " + text);
|
||||
message.setIcon(R.drawable.info);
|
||||
conversation.addMessage(message);
|
||||
|
||||
Intent intent = Broadcast.createConversationIntent(
|
||||
Broadcast.CONVERSATION_MESSAGE,
|
||||
server.getId(),
|
||||
conversation.getName()
|
||||
);
|
||||
service.sendBroadcast(intent);
|
||||
|
||||
service.getConnection(server.getId()).sendNotice(params[1], text);
|
||||
} else {
|
||||
throw new CommandException(service.getString(R.string.invalid_number_of_params));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage of /notice
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/notice <nickname> <message>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of /notice
|
||||
*/
|
||||
@Override
|
||||
public String getDescription(Context context)
|
||||
{
|
||||
return context.getString(R.string.command_desc_notice);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2010 Sebastian Kaspari
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
|
@ -17,15 +17,18 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
package org.yaaic.command.handler;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.command.BaseHandler;
|
||||
import org.yaaic.exception.CommandException;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Command: /deop <nickname>
|
||||
*
|
||||
|
@ -33,38 +36,38 @@ import org.yaaic.model.Server;
|
|||
*/
|
||||
public class OpHandler extends BaseHandler
|
||||
{
|
||||
/**
|
||||
* Execute /deop
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (conversation.getType() != Conversation.TYPE_CHANNEL) {
|
||||
throw new CommandException("Only usable from within a channel");
|
||||
}
|
||||
|
||||
if (params.length == 2) {
|
||||
service.getConnection(server.getId()).op(conversation.getName(), params[1]);
|
||||
} else {
|
||||
throw new CommandException("Invalid number of params");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage of /deop
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/op <nickname>";
|
||||
}
|
||||
/**
|
||||
* Execute /deop
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (conversation.getType() != Conversation.TYPE_CHANNEL) {
|
||||
throw new CommandException(service.getString(R.string.only_usable_from_channel));
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of /deop
|
||||
*/
|
||||
@Override
|
||||
public String getDescription()
|
||||
{
|
||||
return "Give a user operator status";
|
||||
}
|
||||
if (params.length == 2) {
|
||||
service.getConnection(server.getId()).op(conversation.getName(), params[1]);
|
||||
} else {
|
||||
throw new CommandException(service.getString(R.string.invalid_number_of_params));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage of /deop
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/op <nickname>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of /deop
|
||||
*/
|
||||
@Override
|
||||
public String getDescription(Context context)
|
||||
{
|
||||
return context.getString(R.string.command_desc_op);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.command.handler;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.command.BaseHandler;
|
||||
import org.yaaic.exception.CommandException;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Command: /part [<channel>]
|
||||
*
|
||||
* Leave the current or the given channel
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class PartHandler extends BaseHandler
|
||||
{
|
||||
/**
|
||||
* Execute /part
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (params.length == 1) {
|
||||
if (conversation.getType() != Conversation.TYPE_CHANNEL) {
|
||||
throw new CommandException(service.getString(R.string.only_usable_from_channel));
|
||||
}
|
||||
|
||||
service.getConnection(server.getId()).partChannel(conversation.getName());
|
||||
} else if (params.length == 2) {
|
||||
service.getConnection(server.getId()).partChannel(params[1]);
|
||||
} else {
|
||||
throw new CommandException(service.getString(R.string.invalid_number_of_params));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage of /part
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/part [<channel>]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of /part
|
||||
*/
|
||||
@Override
|
||||
public String getDescription(Context context)
|
||||
{
|
||||
return context.getString(R.string.command_desc_part);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.command.handler;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.command.BaseHandler;
|
||||
import org.yaaic.exception.CommandException;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.model.Broadcast;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Query;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
/**
|
||||
* Command: /query <nickname>
|
||||
*
|
||||
* Opens a private chat with the given user
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class QueryHandler extends BaseHandler
|
||||
{
|
||||
/**
|
||||
* Execute /query
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (params.length == 2) {
|
||||
// Simple validation
|
||||
if (params[1].startsWith("#")) {
|
||||
throw new CommandException(service.getString(R.string.query_to_channel));
|
||||
}
|
||||
|
||||
Conversation query = server.getConversation(params[1]);
|
||||
|
||||
if (query != null) {
|
||||
throw new CommandException(service.getString(R.string.query_exists));
|
||||
}
|
||||
|
||||
query = new Query(params[1]);
|
||||
query.setHistorySize(service.getSettings().getHistorySize());
|
||||
server.addConversation(query);
|
||||
|
||||
Intent intent = Broadcast.createConversationIntent(
|
||||
Broadcast.CONVERSATION_NEW,
|
||||
server.getId(),
|
||||
query.getName()
|
||||
);
|
||||
service.sendBroadcast(intent);
|
||||
} else {
|
||||
throw new CommandException(service.getString(R.string.invalid_number_of_params));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage of /query
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/query <nickname>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of /query
|
||||
*/
|
||||
@Override
|
||||
public String getDescription(Context context)
|
||||
{
|
||||
return context.getString(R.string.command_desc_query);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2010 Sebastian Kaspari
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
|
@ -17,15 +17,18 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
package org.yaaic.command.handler;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.command.BaseHandler;
|
||||
import org.yaaic.exception.CommandException;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Command: /quit [<reason>]
|
||||
*
|
||||
|
@ -33,34 +36,34 @@ import org.yaaic.model.Server;
|
|||
*/
|
||||
public class QuitHandler extends BaseHandler
|
||||
{
|
||||
/**
|
||||
* Execute /quit
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (params.length == 1) {
|
||||
service.getConnection(server.getId()).quitServer();
|
||||
} else {
|
||||
service.getConnection(server.getId()).quitServer(BaseHandler.mergeParams(params));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage of /quit
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/quit [<reason>]";
|
||||
}
|
||||
/**
|
||||
* Execute /quit
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (params.length == 1) {
|
||||
service.getConnection(server.getId()).quitServer();
|
||||
} else {
|
||||
service.getConnection(server.getId()).quitServer(BaseHandler.mergeParams(params));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of /quit
|
||||
*/
|
||||
@Override
|
||||
public String getDescription()
|
||||
{
|
||||
return "disconnect from server";
|
||||
}
|
||||
/**
|
||||
* Usage of /quit
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/quit [<reason>]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of /quit
|
||||
*/
|
||||
@Override
|
||||
public String getDescription(Context context)
|
||||
{
|
||||
return context.getString(R.string.command_desc_quit);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2010 Sebastian Kaspari
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
|
@ -17,15 +17,18 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
package org.yaaic.command.handler;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.command.BaseHandler;
|
||||
import org.yaaic.exception.CommandException;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Command: /raw <line>
|
||||
*
|
||||
|
@ -35,35 +38,35 @@ import org.yaaic.model.Server;
|
|||
*/
|
||||
public class RawHandler extends BaseHandler
|
||||
{
|
||||
/**
|
||||
* Execute /raw
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (params.length > 1) {
|
||||
String line = BaseHandler.mergeParams(params);
|
||||
service.getConnection(server.getId()).sendRawLineViaQueue(line);
|
||||
} else {
|
||||
throw new CommandException("Line is missing");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage of /raw
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/raw <line>";
|
||||
}
|
||||
/**
|
||||
* Execute /raw
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (params.length > 1) {
|
||||
String line = BaseHandler.mergeParams(params);
|
||||
service.getConnection(server.getId()).sendRawLineViaQueue(line);
|
||||
} else {
|
||||
throw new CommandException(service.getString(R.string.line_missing));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of /raw
|
||||
*/
|
||||
@Override
|
||||
public String getDescription()
|
||||
{
|
||||
return "Send a raw line to the server";
|
||||
}
|
||||
/**
|
||||
* Usage of /raw
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/raw <line>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of /raw
|
||||
*/
|
||||
@Override
|
||||
public String getDescription(Context context)
|
||||
{
|
||||
return context.getString(R.string.command_desc_raw);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.command.handler;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.command.BaseHandler;
|
||||
import org.yaaic.exception.CommandException;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.model.Channel;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Command: /topic [<topic>]
|
||||
*
|
||||
* Show the current topic or change the topic if a new topic is provided
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class TopicHandler extends BaseHandler
|
||||
{
|
||||
/**
|
||||
* Execute /topic
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (conversation.getType() != Conversation.TYPE_CHANNEL) {
|
||||
throw new CommandException(service.getString(R.string.only_usable_from_channel));
|
||||
}
|
||||
|
||||
Channel channel = (Channel) conversation;
|
||||
|
||||
if (params.length == 1) {
|
||||
// Show topic
|
||||
service.getConnection(server.getId()).onTopic(channel.getName(), channel.getTopic(), "", 0, false);
|
||||
} else if (params.length > 1) {
|
||||
// Change topic
|
||||
service.getConnection(server.getId()).setTopic(channel.getName(), BaseHandler.mergeParams(params));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage of /topic
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/topic [<topic>]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of /topic
|
||||
*/
|
||||
@Override
|
||||
public String getDescription(Context context)
|
||||
{
|
||||
return context.getString(R.string.command_desc_topic);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2010 Sebastian Kaspari
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
|
@ -17,15 +17,18 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
package org.yaaic.command.handler;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.command.BaseHandler;
|
||||
import org.yaaic.exception.CommandException;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Command: /voice <nickname>
|
||||
*
|
||||
|
@ -33,38 +36,38 @@ import org.yaaic.model.Server;
|
|||
*/
|
||||
public class VoiceHandler extends BaseHandler
|
||||
{
|
||||
/**
|
||||
* Execute /voice
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (conversation.getType() != Conversation.TYPE_CHANNEL) {
|
||||
throw new CommandException("Only usable from within a channel");
|
||||
}
|
||||
|
||||
if (params.length == 2) {
|
||||
service.getConnection(server.getId()).voice(conversation.getName(), params[1]);
|
||||
} else {
|
||||
throw new CommandException("Invalid number of params");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage of /voice
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/voice <nickname>";
|
||||
}
|
||||
/**
|
||||
* Execute /voice
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (conversation.getType() != Conversation.TYPE_CHANNEL) {
|
||||
throw new CommandException(service.getString(R.string.only_usable_from_channel));
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of /voice
|
||||
*/
|
||||
@Override
|
||||
public String getDescription()
|
||||
{
|
||||
return "Give a user voice status";
|
||||
}
|
||||
if (params.length == 2) {
|
||||
service.getConnection(server.getId()).voice(conversation.getName(), params[1]);
|
||||
} else {
|
||||
throw new CommandException(service.getString(R.string.invalid_number_of_params));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage of /voice
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/voice <nickname>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of /voice
|
||||
*/
|
||||
@Override
|
||||
public String getDescription(Context context)
|
||||
{
|
||||
return context.getString(R.string.command_desc_voice);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2010 Sebastian Kaspari
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
|
@ -17,15 +17,18 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
package org.yaaic.command.handler;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.command.BaseHandler;
|
||||
import org.yaaic.exception.CommandException;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Command: /whois <nickname>
|
||||
*
|
||||
|
@ -35,34 +38,34 @@ import org.yaaic.model.Server;
|
|||
*/
|
||||
public class WhoisHandler extends BaseHandler
|
||||
{
|
||||
/**
|
||||
* Execute /whois
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (params.length != 2) {
|
||||
throw new CommandException("Invalid number of params");
|
||||
}
|
||||
|
||||
service.getConnection(server.getId()).sendRawLineViaQueue("WHOIS " + params[1]);
|
||||
}
|
||||
/**
|
||||
* Execute /whois
|
||||
*/
|
||||
@Override
|
||||
public void execute(String[] params, Server server, Conversation conversation, IRCService service) throws CommandException
|
||||
{
|
||||
if (params.length != 2) {
|
||||
throw new CommandException(service.getString(R.string.invalid_number_of_params));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get description of /whois
|
||||
*/
|
||||
@Override
|
||||
public String getDescription()
|
||||
{
|
||||
return "Get information about a user";
|
||||
}
|
||||
service.getConnection(server.getId()).sendRawLineViaQueue("WHOIS " + params[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get usage of /whois
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/whois <nickname>";
|
||||
}
|
||||
/**
|
||||
* Get description of /whois
|
||||
*/
|
||||
@Override
|
||||
public String getDescription(Context context)
|
||||
{
|
||||
return context.getString(R.string.command_desc_whois);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get usage of /whois
|
||||
*/
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "/whois <nickname>";
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2010 Sebastian Kaspari
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
|
@ -17,32 +17,31 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.activity;
|
||||
*/
|
||||
package org.yaaic.db;
|
||||
|
||||
import org.yaaic.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.Window;
|
||||
import android.provider.BaseColumns;
|
||||
|
||||
/**
|
||||
* About activity
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
* Constants for the aliases table
|
||||
*
|
||||
* @author Sebastian Kaspari <s.kaspari@googlemail.com>
|
||||
*/
|
||||
public class AboutActivity extends Activity
|
||||
public class AliasConstants implements BaseColumns
|
||||
{
|
||||
/**
|
||||
* On create
|
||||
*/
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
|
||||
setContentView(R.layout.about);
|
||||
}
|
||||
public static final String TABLE_NAME = "aliases";
|
||||
|
||||
// fields
|
||||
public static final String ALIAS = "alias";
|
||||
public static final String IDENTITY = "identity";
|
||||
|
||||
/**
|
||||
* All fields of the table
|
||||
*/
|
||||
public static final String[] ALL = {
|
||||
_ID,
|
||||
ALIAS,
|
||||
IDENTITY,
|
||||
};
|
||||
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2010 Sebastian Kaspari
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
|
@ -17,7 +17,7 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
package org.yaaic.db;
|
||||
|
||||
import android.provider.BaseColumns;
|
||||
|
@ -29,19 +29,19 @@ import android.provider.BaseColumns;
|
|||
*/
|
||||
public interface ChannelConstants extends BaseColumns
|
||||
{
|
||||
public static final String TABLE_NAME = "channels";
|
||||
|
||||
// fields
|
||||
public static final String NAME = "name";
|
||||
public static final String PASSWORD = "password";
|
||||
public static final String SERVER = "server";
|
||||
|
||||
/**
|
||||
* All fields of the table
|
||||
*/
|
||||
public static final String[] ALL = {
|
||||
NAME,
|
||||
PASSWORD,
|
||||
SERVER
|
||||
};
|
||||
public static final String TABLE_NAME = "channels";
|
||||
|
||||
// fields
|
||||
public static final String NAME = "name";
|
||||
public static final String PASSWORD = "password";
|
||||
public static final String SERVER = "server";
|
||||
|
||||
/**
|
||||
* All fields of the table
|
||||
*/
|
||||
public static final String[] ALL = {
|
||||
NAME,
|
||||
PASSWORD,
|
||||
SERVER
|
||||
};
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2010 Sebastian Kaspari
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
|
@ -17,7 +17,7 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
package org.yaaic.db;
|
||||
|
||||
import android.provider.BaseColumns;
|
||||
|
@ -29,17 +29,17 @@ import android.provider.BaseColumns;
|
|||
*/
|
||||
public interface CommandConstants extends BaseColumns
|
||||
{
|
||||
public static final String TABLE_NAME = "commands";
|
||||
|
||||
// fields
|
||||
public static final String COMMAND = "command";
|
||||
public static final String SERVER = "server";
|
||||
|
||||
/**
|
||||
* All fields of the table
|
||||
*/
|
||||
public static final String[] ALL = {
|
||||
COMMAND,
|
||||
SERVER
|
||||
};
|
||||
public static final String TABLE_NAME = "commands";
|
||||
|
||||
// fields
|
||||
public static final String COMMAND = "command";
|
||||
public static final String SERVER = "server";
|
||||
|
||||
/**
|
||||
* All fields of the table
|
||||
*/
|
||||
public static final String[] ALL = {
|
||||
COMMAND,
|
||||
SERVER
|
||||
};
|
||||
}
|
|
@ -0,0 +1,682 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.db;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import org.yaaic.model.Authentication;
|
||||
import org.yaaic.model.Identity;
|
||||
import org.yaaic.model.Server;
|
||||
import org.yaaic.model.Status;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.DatabaseUtils;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
|
||||
/**
|
||||
* Database Helper for the servers and channels tables
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class Database extends SQLiteOpenHelper
|
||||
{
|
||||
private static final String DATABASE_NAME = "servers.db";
|
||||
private static final int DATABASE_VERSION = 5;
|
||||
|
||||
/**
|
||||
* Create a new helper for database access
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
public Database(Context context)
|
||||
{
|
||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create all needed tables on first start
|
||||
*/
|
||||
@Override
|
||||
public void onCreate(SQLiteDatabase db)
|
||||
{
|
||||
db.execSQL("CREATE TABLE " + ServerConstants.TABLE_NAME + " ( "
|
||||
+ ServerConstants._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||
+ ServerConstants.TITLE + " TEXT NOT NULL, "
|
||||
+ ServerConstants.HOST + " TEXT NOT NULL, "
|
||||
+ ServerConstants.PORT + " INTEGER, "
|
||||
+ ServerConstants.PASSWORD + " TEXT, "
|
||||
+ ServerConstants.AUTOCONNECT + " BOOLEAN, "
|
||||
+ ServerConstants.USE_SSL + " BOOLEAN, "
|
||||
+ ServerConstants.CHARSET + " TEXT, "
|
||||
+ ServerConstants.IDENTITY + " INTEGER, "
|
||||
+ ServerConstants.NICKSERV_PASSWORD + " TEXT, "
|
||||
+ ServerConstants.SASL_USERNAME + " TEXT, "
|
||||
+ ServerConstants.SASL_PASSWORD + " TEXT"
|
||||
+ ");"
|
||||
);
|
||||
|
||||
db.execSQL("CREATE TABLE " + ChannelConstants.TABLE_NAME + " ("
|
||||
+ ChannelConstants._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||
+ ChannelConstants.NAME + " TEXT NOT NULL, "
|
||||
+ ChannelConstants.PASSWORD + " TEXT, "
|
||||
+ ChannelConstants.SERVER + " INTEGER"
|
||||
+ ");"
|
||||
);
|
||||
|
||||
db.execSQL("CREATE TABLE " + IdentityConstants.TABLE_NAME +" ("
|
||||
+ IdentityConstants._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||
+ IdentityConstants.NICKNAME + " TEXT NOT NULL,"
|
||||
+ IdentityConstants.IDENT + " TEXT NOT NULL,"
|
||||
+ IdentityConstants.REALNAME + " TEXT NOT NULL"
|
||||
+ ");"
|
||||
);
|
||||
|
||||
db.execSQL("CREATE TABLE " + CommandConstants.TABLE_NAME + " ("
|
||||
+ CommandConstants._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||
+ CommandConstants.COMMAND + " TEXT NOT NULL, "
|
||||
+ ChannelConstants.SERVER + " INTEGER"
|
||||
+ ");"
|
||||
);
|
||||
|
||||
db.execSQL("CREATE TABLE " + AliasConstants.TABLE_NAME + " ("
|
||||
+ AliasConstants._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||
+ AliasConstants.ALIAS + " TEXT NOT NULL, "
|
||||
+ AliasConstants.IDENTITY + " INTEGER"
|
||||
+ ");"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate existing databases to
|
||||
*/
|
||||
@Override
|
||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
|
||||
{
|
||||
// XXX: Do not delete databases (release version)
|
||||
|
||||
// db.execSQL("DROP TABLE IF EXISTS " + ServerConstants.TABLE_NAME + ";");
|
||||
// db.execSQL("DROP TABLE IF EXISTS " + ChannelConstants.TABLE_NAME + ";");
|
||||
// db.execSQL("DROP TABLE IF EXISTS " + IdentityConstants.TABLE_NAME + ";");
|
||||
|
||||
// onCreate(db);
|
||||
|
||||
if (oldVersion == 1) {
|
||||
// Add charset field to server table
|
||||
db.execSQL("ALTER TABLE " + ServerConstants.TABLE_NAME + " ADD " + ServerConstants.CHARSET + " TEXT AFTER " + ServerConstants.USE_SSL + ";");
|
||||
|
||||
oldVersion = 2; // now do the updates for version 2
|
||||
}
|
||||
|
||||
if (oldVersion == 2) {
|
||||
// Add new commands table (copy&paste from onCreate())
|
||||
db.execSQL("CREATE TABLE " + CommandConstants.TABLE_NAME + " ("
|
||||
+ CommandConstants._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||
+ CommandConstants.COMMAND + " TEXT NOT NULL, "
|
||||
+ ChannelConstants.SERVER + " INTEGER"
|
||||
+ ");"
|
||||
);
|
||||
|
||||
oldVersion = 3;
|
||||
}
|
||||
|
||||
if (oldVersion == 3) {
|
||||
db.execSQL("CREATE TABLE " + AliasConstants.TABLE_NAME + " ("
|
||||
+ AliasConstants._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||
+ AliasConstants.ALIAS + " TEXT NOT NULL, "
|
||||
+ AliasConstants.IDENTITY + " INTEGER"
|
||||
+ ");"
|
||||
);
|
||||
|
||||
oldVersion = 4;
|
||||
}
|
||||
|
||||
if (oldVersion == 4) {
|
||||
// Add authentication fields to database
|
||||
db.execSQL("ALTER TABLE " + ServerConstants.TABLE_NAME + " ADD " + ServerConstants.NICKSERV_PASSWORD + " TEXT AFTER " + ServerConstants.CHARSET + ";");
|
||||
db.execSQL("ALTER TABLE " + ServerConstants.TABLE_NAME + " ADD " + ServerConstants.SASL_USERNAME + " TEXT AFTER " + ServerConstants.NICKSERV_PASSWORD + ";");
|
||||
db.execSQL("ALTER TABLE " + ServerConstants.TABLE_NAME + " ADD " + ServerConstants.SASL_PASSWORD + " TEXT AFTER " + ServerConstants.SASL_USERNAME + ";");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new server to the database
|
||||
*
|
||||
* @param server The server to add.
|
||||
* @param identityId The id of the assigned identity
|
||||
*/
|
||||
public long addServer(Server server, int identityId)
|
||||
{
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
values.put(ServerConstants.TITLE, server.getTitle());
|
||||
values.put(ServerConstants.HOST, server.getHost());
|
||||
values.put(ServerConstants.PORT, server.getPort());
|
||||
values.put(ServerConstants.PASSWORD, server.getPassword());
|
||||
values.put(ServerConstants.AUTOCONNECT, false);
|
||||
values.put(ServerConstants.USE_SSL, server.useSSL());
|
||||
values.put(ServerConstants.IDENTITY, identityId);
|
||||
values.put(ServerConstants.CHARSET, server.getCharset());
|
||||
|
||||
Authentication authentication = server.getAuthentication();
|
||||
values.put(ServerConstants.NICKSERV_PASSWORD, authentication.getNickservPassword());
|
||||
values.put(ServerConstants.SASL_USERNAME, authentication.getSaslUsername());
|
||||
values.put(ServerConstants.SASL_PASSWORD, authentication.getSaslPassword());
|
||||
|
||||
return this.getWritableDatabase().insert(ServerConstants.TABLE_NAME, null, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the server record in the database
|
||||
*
|
||||
* @param serverId The primary key of the server to update.
|
||||
* @param server The server to update.
|
||||
* @param identityId The identity of the server record
|
||||
*/
|
||||
public void updateServer(int serverId, Server server, int identityId)
|
||||
{
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
values.put(ServerConstants.TITLE, server.getTitle());
|
||||
values.put(ServerConstants.HOST, server.getHost());
|
||||
values.put(ServerConstants.PORT, server.getPort());
|
||||
values.put(ServerConstants.PASSWORD, server.getPassword());
|
||||
values.put(ServerConstants.AUTOCONNECT, false);
|
||||
values.put(ServerConstants.USE_SSL, server.useSSL());
|
||||
values.put(ServerConstants.IDENTITY, identityId);
|
||||
values.put(ServerConstants.CHARSET, server.getCharset());
|
||||
|
||||
Authentication authentication = server.getAuthentication();
|
||||
|
||||
values.put(ServerConstants.NICKSERV_PASSWORD, authentication.getNickservPassword());
|
||||
values.put(ServerConstants.SASL_USERNAME, authentication.getSaslUsername());
|
||||
values.put(ServerConstants.SASL_PASSWORD, authentication.getSaslPassword());
|
||||
|
||||
this.getWritableDatabase().update(
|
||||
ServerConstants.TABLE_NAME,
|
||||
values,
|
||||
ServerConstants._ID + " = " + serverId,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a channel to the database
|
||||
*
|
||||
* @param serverId Unique id of server
|
||||
* @param name Name of channel
|
||||
* @param password Password to join (if needed)
|
||||
*/
|
||||
public void addChannel(int serverId, String name, String password)
|
||||
{
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
values.put(ChannelConstants.NAME, name);
|
||||
values.put(ChannelConstants.PASSWORD, password);
|
||||
values.put(ChannelConstants.SERVER, serverId);
|
||||
|
||||
this.getWritableDatabase().insert(ChannelConstants.TABLE_NAME, null, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace list of channels for the given server
|
||||
*
|
||||
* @param serverId Unique id of server
|
||||
* @param channels List of channel names
|
||||
*/
|
||||
public void setChannels(int serverId, ArrayList<String> channels)
|
||||
{
|
||||
// Remove old channels
|
||||
this.getWritableDatabase().delete(
|
||||
ChannelConstants.TABLE_NAME,
|
||||
ChannelConstants.SERVER + " = " + serverId,
|
||||
null
|
||||
);
|
||||
|
||||
// Add new channels
|
||||
for (String channel : channels) {
|
||||
addChannel(serverId, channel, "");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all commands to execute on connect
|
||||
*
|
||||
* @param serverId Unique id of server
|
||||
* @return List of commands
|
||||
*/
|
||||
public ArrayList<String> getCommandsByServerId(int serverId)
|
||||
{
|
||||
ArrayList<String> commands = new ArrayList<String>();
|
||||
|
||||
Cursor cursor = this.getReadableDatabase().query(
|
||||
CommandConstants.TABLE_NAME,
|
||||
CommandConstants.ALL,
|
||||
CommandConstants.SERVER + " = " + serverId,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
|
||||
while (cursor.moveToNext()) {
|
||||
String command = cursor.getString(cursor.getColumnIndex(CommandConstants.COMMAND));
|
||||
commands.add(command);
|
||||
}
|
||||
|
||||
cursor.close();
|
||||
|
||||
return commands;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a command to a server
|
||||
*
|
||||
* @param serverId Unique id of server
|
||||
* @param command The command to execute after connect
|
||||
*/
|
||||
public void addCommand(int serverId, String command)
|
||||
{
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
values.put(CommandConstants.COMMAND, command);
|
||||
values.put(CommandConstants.SERVER, serverId);
|
||||
|
||||
this.getWritableDatabase().insert(CommandConstants.TABLE_NAME, null, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace list of commands for the given server
|
||||
*
|
||||
* @param serverId Unique id of server
|
||||
* @param commands List of commands to execute after connect
|
||||
*/
|
||||
public void setCommands(int serverId, ArrayList<String> commands)
|
||||
{
|
||||
// Remove old commands
|
||||
this.getWritableDatabase().delete(
|
||||
CommandConstants.TABLE_NAME,
|
||||
CommandConstants.SERVER + " = " + serverId,
|
||||
null
|
||||
);
|
||||
|
||||
// Add new commands
|
||||
for (String command : commands) {
|
||||
addCommand(serverId, command);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all servers from database
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public HashMap<Integer, Server> getServers()
|
||||
{
|
||||
HashMap<Integer, Server> servers = new HashMap<Integer, Server>();
|
||||
|
||||
Cursor cursor = this.getReadableDatabase().query(
|
||||
ServerConstants.TABLE_NAME,
|
||||
ServerConstants.ALL,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
ServerConstants.TITLE + " ASC"
|
||||
);
|
||||
|
||||
while (cursor.moveToNext()) {
|
||||
Server server = populateServer(cursor);
|
||||
servers.put(server.getId(), server);
|
||||
}
|
||||
cursor.close();
|
||||
|
||||
return servers;
|
||||
}
|
||||
|
||||
public Server getServerById(int serverId)
|
||||
{
|
||||
Server server = null;
|
||||
|
||||
Cursor cursor = this.getReadableDatabase().query(
|
||||
ServerConstants.TABLE_NAME,
|
||||
ServerConstants.ALL,
|
||||
ServerConstants._ID + " = " + serverId,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
ServerConstants.TITLE + " ASC"
|
||||
);
|
||||
|
||||
if (cursor.moveToNext()) {
|
||||
server = populateServer(cursor);
|
||||
}
|
||||
|
||||
cursor.close();
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given server title is currently used
|
||||
*
|
||||
* @param title The server title
|
||||
* @return true if there's a server with this title, false otherwise
|
||||
*/
|
||||
public boolean isTitleUsed(String title)
|
||||
{
|
||||
boolean isTitleUsed = false;
|
||||
|
||||
Cursor cursor = this.getReadableDatabase().query(
|
||||
ServerConstants.TABLE_NAME,
|
||||
ServerConstants.ALL,
|
||||
ServerConstants.TITLE + " = " + DatabaseUtils.sqlEscapeString(title),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
|
||||
if (cursor.moveToNext()) {
|
||||
isTitleUsed = true;
|
||||
}
|
||||
|
||||
cursor.close();
|
||||
|
||||
return isTitleUsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate a server object from the given database cursor
|
||||
* @param cursor
|
||||
* @return
|
||||
*/
|
||||
private Server populateServer(Cursor cursor)
|
||||
{
|
||||
Server server = new Server();
|
||||
|
||||
server.setTitle(cursor.getString(cursor.getColumnIndex((ServerConstants.TITLE))));
|
||||
server.setHost(cursor.getString(cursor.getColumnIndex((ServerConstants.HOST))));
|
||||
server.setPort(cursor.getInt(cursor.getColumnIndex((ServerConstants.PORT))));
|
||||
server.setPassword(cursor.getString(cursor.getColumnIndex(ServerConstants.PASSWORD)));
|
||||
server.setId(cursor.getInt(cursor.getColumnIndex((ServerConstants._ID))));
|
||||
server.setCharset(cursor.getString(cursor.getColumnIndex(ServerConstants.CHARSET)));
|
||||
|
||||
String useSSLvalue = cursor.getString(cursor.getColumnIndex(ServerConstants.USE_SSL));
|
||||
if (useSSLvalue != null && useSSLvalue.equals("1")) {
|
||||
server.setUseSSL(true);
|
||||
}
|
||||
|
||||
server.setStatus(Status.DISCONNECTED);
|
||||
|
||||
Authentication authentication = new Authentication();
|
||||
authentication.setNickservPassword(cursor.getString(cursor.getColumnIndex(ServerConstants.NICKSERV_PASSWORD)));
|
||||
authentication.setSaslUsername(cursor.getString(cursor.getColumnIndex(ServerConstants.SASL_USERNAME)));
|
||||
authentication.setSaslPassword(cursor.getString(cursor.getColumnIndex(ServerConstants.SASL_PASSWORD)));
|
||||
server.setAuthentication(authentication);
|
||||
|
||||
// Load identity for server
|
||||
Identity identity = this.getIdentityById(cursor.getInt(cursor.getColumnIndex(ServerConstants.IDENTITY)));
|
||||
server.setIdentity(identity);
|
||||
|
||||
// Load auto join channels
|
||||
ArrayList<String> channels = this.getChannelsByServerId(server.getId());
|
||||
server.setAutoJoinChannels(channels);
|
||||
|
||||
// Load commands to execute after connect
|
||||
ArrayList<String> commands = this.getCommandsByServerId(server.getId());
|
||||
server.setConnectCommands(commands);
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all servers with autoconnect enabled
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Cursor getAutoConnectServers()
|
||||
{
|
||||
return this.getReadableDatabase().query(
|
||||
ServerConstants.TABLE_NAME,
|
||||
ServerConstants.ALL,
|
||||
ServerConstants.AUTOCONNECT + " = 1",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
ServerConstants.TITLE + " ASC"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all channels of server
|
||||
*
|
||||
* @param server Unique id of server
|
||||
* @return list of channel names
|
||||
*/
|
||||
public ArrayList<String> getChannelsByServerId(int serverId)
|
||||
{
|
||||
ArrayList<String> channels = new ArrayList<String>();
|
||||
|
||||
Cursor cursor = this.getReadableDatabase().query(
|
||||
ChannelConstants.TABLE_NAME,
|
||||
ChannelConstants.ALL,
|
||||
ChannelConstants.SERVER + " = " + serverId,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
ChannelConstants.NAME + " ASC"
|
||||
);
|
||||
|
||||
while (cursor.moveToNext()) {
|
||||
String channel = cursor.getString(cursor.getColumnIndex(ChannelConstants.NAME));
|
||||
channels.add(channel);
|
||||
}
|
||||
|
||||
cursor.close();
|
||||
|
||||
return channels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove server from database by unique id
|
||||
*
|
||||
* @param title
|
||||
*/
|
||||
public void removeServerById(int serverId)
|
||||
{
|
||||
// XXX: Workaround: Remove identity assigned to this server
|
||||
// until we have some kind of identity manager
|
||||
int identityId = this.getIdentityIdByServerId(serverId);
|
||||
if (identityId != -1) {
|
||||
deleteAliases(identityId);
|
||||
this.getWritableDatabase().execSQL(
|
||||
"DELETE FROM " + IdentityConstants.TABLE_NAME + " WHERE " + IdentityConstants._ID + " = " + identityId + ";"
|
||||
);
|
||||
}
|
||||
|
||||
// Now delete the server entry
|
||||
this.getWritableDatabase().execSQL(
|
||||
"DELETE FROM " + ServerConstants.TABLE_NAME + " WHERE " + ServerConstants._ID + " = " + serverId + ";"
|
||||
);
|
||||
}
|
||||
|
||||
protected void setAliases(long identityId, List<String> aliases)
|
||||
{
|
||||
deleteAliases(identityId);
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
for (String alias : aliases) {
|
||||
values.clear();
|
||||
values.put(AliasConstants.ALIAS, alias);
|
||||
values.put(AliasConstants.IDENTITY, identityId);
|
||||
getWritableDatabase().insert(AliasConstants.TABLE_NAME, null, values);
|
||||
}
|
||||
}
|
||||
|
||||
protected void deleteAliases(long identityId)
|
||||
{
|
||||
getWritableDatabase().execSQL(
|
||||
"DELETE FROM " + AliasConstants.TABLE_NAME + " WHERE " + AliasConstants.IDENTITY + " = " + identityId
|
||||
);
|
||||
}
|
||||
|
||||
protected List<String> getAliasesByIdentityId(long identityId)
|
||||
{
|
||||
List<String> aliases = new ArrayList<String>();
|
||||
|
||||
Cursor cursor = this.getReadableDatabase().query(
|
||||
AliasConstants.TABLE_NAME,
|
||||
AliasConstants.ALL,
|
||||
AliasConstants.IDENTITY + " = " + identityId,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
|
||||
while (cursor.moveToNext()) {
|
||||
aliases.add(cursor.getString(cursor.getColumnIndex(AliasConstants.ALIAS)));
|
||||
}
|
||||
cursor.close();
|
||||
|
||||
return aliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new identity
|
||||
*
|
||||
* @param identityId
|
||||
* @param nickname
|
||||
* @param ident
|
||||
* @param realname
|
||||
* @param aliases
|
||||
*/
|
||||
public long addIdentity(String nickname, String ident, String realname, List<String> aliases)
|
||||
{
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
values.put(IdentityConstants.NICKNAME, nickname);
|
||||
values.put(IdentityConstants.IDENT, ident);
|
||||
values.put(IdentityConstants.REALNAME, realname);
|
||||
|
||||
long identityId = this.getWritableDatabase().insert(IdentityConstants.TABLE_NAME, null, values);
|
||||
|
||||
setAliases(identityId, aliases);
|
||||
|
||||
return identityId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the identity with the given id
|
||||
*
|
||||
* @param identityId
|
||||
* @param nickname
|
||||
* @param ident
|
||||
* @param realname
|
||||
*/
|
||||
public void updateIdentity(int identityId, String nickname, String ident, String realname, List<String> aliases)
|
||||
{
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
values.put(IdentityConstants.NICKNAME, nickname);
|
||||
values.put(IdentityConstants.IDENT, ident);
|
||||
values.put(IdentityConstants.REALNAME, realname);
|
||||
|
||||
this.getWritableDatabase().update(
|
||||
IdentityConstants.TABLE_NAME,
|
||||
values,
|
||||
IdentityConstants._ID + " = " + identityId,
|
||||
null
|
||||
);
|
||||
|
||||
setAliases(identityId, aliases);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an identity by its id
|
||||
*
|
||||
* @param identityId
|
||||
* @return
|
||||
*/
|
||||
public Identity getIdentityById(int identityId)
|
||||
{
|
||||
Identity identity = null;
|
||||
|
||||
Cursor cursor = this.getReadableDatabase().query(
|
||||
IdentityConstants.TABLE_NAME,
|
||||
IdentityConstants.ALL,
|
||||
IdentityConstants._ID + "=" + identityId,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
|
||||
if (cursor.moveToNext()) {
|
||||
identity = new Identity();
|
||||
|
||||
identity.setNickname(cursor.getString(cursor.getColumnIndex(IdentityConstants.NICKNAME)));
|
||||
identity.setIdent(cursor.getString(cursor.getColumnIndex(IdentityConstants.IDENT)));
|
||||
identity.setRealName(cursor.getString(cursor.getColumnIndex(IdentityConstants.REALNAME)));
|
||||
|
||||
identity.setAliases(getAliasesByIdentityId(identityId));
|
||||
}
|
||||
|
||||
cursor.close();
|
||||
|
||||
return identity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a server by its id
|
||||
*
|
||||
* @param serverId
|
||||
* @return
|
||||
*/
|
||||
public int getIdentityIdByServerId(int serverId)
|
||||
{
|
||||
int identityId = -1;
|
||||
|
||||
Cursor cursor = this.getReadableDatabase().query(
|
||||
ServerConstants.TABLE_NAME,
|
||||
ServerConstants.ALL,
|
||||
ServerConstants._ID + " = " + serverId,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
|
||||
if (cursor.moveToNext()) {
|
||||
identityId = cursor.getInt(cursor.getColumnIndex(ServerConstants.IDENTITY));
|
||||
}
|
||||
|
||||
cursor.close();
|
||||
|
||||
return identityId;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2010 Sebastian Kaspari
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
|
@ -17,32 +17,32 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
package org.yaaic.db;
|
||||
|
||||
import android.provider.BaseColumns;
|
||||
|
||||
/**
|
||||
* Constants for the identity table
|
||||
*
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class IdentityConstants implements BaseColumns
|
||||
{
|
||||
public static final String TABLE_NAME = "identities";
|
||||
|
||||
// fields
|
||||
public static final String NICKNAME = "nickname";
|
||||
public static final String IDENT = "ident";
|
||||
public static final String REALNAME = "realname";
|
||||
|
||||
/**
|
||||
* All fields of the table
|
||||
*/
|
||||
public static final String[] ALL = {
|
||||
_ID,
|
||||
NICKNAME,
|
||||
IDENT,
|
||||
REALNAME,
|
||||
};
|
||||
public static final String TABLE_NAME = "identities";
|
||||
|
||||
// fields
|
||||
public static final String NICKNAME = "nickname";
|
||||
public static final String IDENT = "ident";
|
||||
public static final String REALNAME = "realname";
|
||||
|
||||
/**
|
||||
* All fields of the table
|
||||
*/
|
||||
public static final String[] ALL = {
|
||||
_ID,
|
||||
NICKNAME,
|
||||
IDENT,
|
||||
REALNAME,
|
||||
};
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.db;
|
||||
|
||||
import android.provider.BaseColumns;
|
||||
|
||||
/**
|
||||
* Constants for the server table
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public interface ServerConstants extends BaseColumns
|
||||
{
|
||||
public static final String TABLE_NAME = "servers";
|
||||
|
||||
// fields
|
||||
public static final String TITLE = "title";
|
||||
public static final String HOST = "host";
|
||||
public static final String PORT = "port";
|
||||
public static final String PASSWORD = "password";
|
||||
public static final String AUTOCONNECT = "autoConnect";
|
||||
public static final String USE_SSL = "useSSL";
|
||||
public static final String CHARSET = "charset";
|
||||
public static final String IDENTITY = "identity";
|
||||
public static final String NICKSERV_PASSWORD = "nickserv_password";
|
||||
public static final String SASL_USERNAME = "sasl_username";
|
||||
public static final String SASL_PASSWORD = "sasl_password";
|
||||
|
||||
/**
|
||||
* All fields of the table
|
||||
*/
|
||||
public static final String[] ALL = {
|
||||
_ID,
|
||||
TITLE,
|
||||
HOST,
|
||||
PORT,
|
||||
PASSWORD,
|
||||
AUTOCONNECT,
|
||||
USE_SSL,
|
||||
CHARSET,
|
||||
IDENTITY,
|
||||
NICKSERV_PASSWORD,
|
||||
SASL_USERNAME,
|
||||
SASL_PASSWORD
|
||||
};
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2010 Sebastian Kaspari
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
|
@ -17,7 +17,7 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
package org.yaaic.exception;
|
||||
|
||||
/**
|
||||
|
@ -28,13 +28,13 @@ package org.yaaic.exception;
|
|||
*/
|
||||
public class CommandException extends Throwable
|
||||
{
|
||||
private static final long serialVersionUID = -8317993941455253288L;
|
||||
|
||||
/**
|
||||
* Create a new CommandException object
|
||||
*/
|
||||
public CommandException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
private static final long serialVersionUID = -8317993941455253288L;
|
||||
|
||||
/**
|
||||
* Create a new CommandException object
|
||||
*/
|
||||
public CommandException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2010 Sebastian Kaspari
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
|
@ -17,25 +17,25 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
package org.yaaic.exception;
|
||||
|
||||
/**
|
||||
* A valiadtion exception is thrown if any user input is invalid
|
||||
* A ValidationException is thrown if any user input is invalid
|
||||
*
|
||||
* @author Sebastian Kaspari
|
||||
*/
|
||||
public class ValidationException extends Exception
|
||||
{
|
||||
private static final long serialVersionUID = 6951535205062761539L;
|
||||
|
||||
/**
|
||||
* Create a new ValidationException with the given message
|
||||
*
|
||||
* @param message The error message
|
||||
*/
|
||||
public ValidationException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
private static final long serialVersionUID = 6951535205062761539L;
|
||||
|
||||
/**
|
||||
* Create a new ValidationException with the given message
|
||||
*
|
||||
* @param message The error message
|
||||
*/
|
||||
public ValidationException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,921 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2015 Sebastian Kaspari
|
||||
Copyright 2012 Daniel E. Moctezuma <democtezuma@gmail.com>
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.fragment;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Fragment;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.ServiceConnection;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.speech.RecognizerIntent;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.text.InputType;
|
||||
import android.text.method.TextKeyListener;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.Yaaic;
|
||||
import org.yaaic.activity.JoinActivity;
|
||||
import org.yaaic.activity.UserActivity;
|
||||
import org.yaaic.activity.UsersActivity;
|
||||
import org.yaaic.activity.YaaicActivity;
|
||||
import org.yaaic.adapter.ConversationPagerAdapter;
|
||||
import org.yaaic.adapter.MessageListAdapter;
|
||||
import org.yaaic.command.CommandParser;
|
||||
import org.yaaic.irc.IRCBinder;
|
||||
import org.yaaic.irc.IRCConnection;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.listener.ConversationListener;
|
||||
import org.yaaic.listener.ServerListener;
|
||||
import org.yaaic.model.Broadcast;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Extra;
|
||||
import org.yaaic.model.Message;
|
||||
import org.yaaic.model.Query;
|
||||
import org.yaaic.model.Scrollback;
|
||||
import org.yaaic.model.Server;
|
||||
import org.yaaic.model.ServerInfo;
|
||||
import org.yaaic.model.Settings;
|
||||
import org.yaaic.model.Status;
|
||||
import org.yaaic.model.User;
|
||||
import org.yaaic.receiver.ConversationReceiver;
|
||||
import org.yaaic.receiver.ServerReceiver;
|
||||
import org.yaaic.view.ConversationTabLayout;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The server view with a scrollable pager of all conversations.
|
||||
*/
|
||||
public class ConversationFragment extends Fragment implements ServerListener, ConversationListener, ServiceConnection {
|
||||
public static final String TRANSACTION_TAG = "fragment_conversation";
|
||||
|
||||
private static final int REQUEST_CODE_JOIN = 1;
|
||||
private static final int REQUEST_CODE_USERS = 2;
|
||||
private static final int REQUEST_CODE_USER = 3;
|
||||
private static final int REQUEST_CODE_NICK_COMPLETION= 4;
|
||||
|
||||
private int serverId;
|
||||
private Server server;
|
||||
private IRCBinder binder;
|
||||
private ConversationReceiver channelReceiver;
|
||||
private ServerReceiver serverReceiver;
|
||||
|
||||
private YaaicActivity activity;
|
||||
|
||||
private EditText input;
|
||||
private ViewPager pager;
|
||||
private ConversationPagerAdapter pagerAdapter;
|
||||
private ConversationTabLayout tabLayout;
|
||||
|
||||
private Scrollback scrollback;
|
||||
|
||||
// XXX: This is ugly. This is a buffer for a channel that should be joined after showing the
|
||||
// JoinActivity. As onActivityResult() is called before onResume() a "channel joined"
|
||||
// broadcast may get lost as the broadcast receivers are registered in onResume() but the
|
||||
// join command would be called in onActivityResult(). joinChannelBuffer will save the
|
||||
// channel name in onActivityResult() and run the join command in onResume().
|
||||
private String joinChannelBuffer;
|
||||
|
||||
private boolean reconnectDialogActive = false;
|
||||
|
||||
private final View.OnKeyListener inputKeyListener = new View.OnKeyListener() {
|
||||
/**
|
||||
* On key pressed (input line)
|
||||
*/
|
||||
@Override
|
||||
public boolean onKey(View view, int keyCode, KeyEvent event) {
|
||||
EditText input = (EditText) view;
|
||||
|
||||
if (event.getAction() != KeyEvent.ACTION_DOWN) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
|
||||
String message = scrollback.goBack();
|
||||
if (message != null) {
|
||||
input.setText(message);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
|
||||
String message = scrollback.goForward();
|
||||
if (message != null) {
|
||||
input.setText(message);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (keyCode == KeyEvent.KEYCODE_ENTER) {
|
||||
sendCurrentMessage();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Nick completion
|
||||
if (keyCode == KeyEvent.KEYCODE_SEARCH) {
|
||||
doNickCompletion(input);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
public ConversationFragment() {
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
|
||||
if (!(activity instanceof YaaicActivity)) {
|
||||
throw new IllegalArgumentException("Activity has to implement YaaicActivity interface");
|
||||
}
|
||||
|
||||
this.activity = (YaaicActivity) activity;
|
||||
}
|
||||
|
||||
/**
|
||||
* On create
|
||||
*/
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
serverId = getArguments().getInt("serverId");
|
||||
server = Yaaic.getInstance().getServerById(serverId);
|
||||
|
||||
scrollback = new Scrollback();
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_conversations, container, false);
|
||||
|
||||
Settings settings = new Settings(getActivity());
|
||||
|
||||
boolean isLandscape = (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE);
|
||||
|
||||
input = (EditText) view.findViewById(R.id.input);
|
||||
input.setOnKeyListener(inputKeyListener);
|
||||
|
||||
pager = (ViewPager) view.findViewById(R.id.pager);
|
||||
|
||||
pagerAdapter = new ConversationPagerAdapter(getActivity(), server);
|
||||
pager.setAdapter(pagerAdapter);
|
||||
|
||||
tabLayout = new ConversationTabLayout(container.getContext());
|
||||
tabLayout.setViewPager(pager);
|
||||
tabLayout.setSelectedIndicatorColors(getResources().getColor(R.color.accent));
|
||||
tabLayout.setDividerColors(getResources().getColor(R.color.divider));
|
||||
|
||||
Toolbar.LayoutParams params = new Toolbar.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT
|
||||
);
|
||||
params.gravity = Gravity.BOTTOM;
|
||||
|
||||
activity.getToolbar().addView(tabLayout, params);
|
||||
|
||||
if (server.getStatus() == Status.PRE_CONNECTING) {
|
||||
server.clearConversations();
|
||||
pagerAdapter.clearConversations();
|
||||
server.getConversation(ServerInfo.DEFAULT_NAME).setHistorySize(
|
||||
settings.getHistorySize()
|
||||
);
|
||||
}
|
||||
|
||||
// Optimization : cache field lookups
|
||||
Collection<Conversation> mConversations = server.getConversations();
|
||||
|
||||
for (Conversation conversation : mConversations) {
|
||||
// Only scroll to new conversation if it was selected before
|
||||
if (conversation.getStatus() == Conversation.STATUS_SELECTED) {
|
||||
onNewConversation(conversation.getName());
|
||||
} else {
|
||||
createNewConversation(conversation.getName());
|
||||
}
|
||||
}
|
||||
|
||||
int setInputTypeFlags = 0;
|
||||
|
||||
setInputTypeFlags |= InputType.TYPE_TEXT_FLAG_AUTO_CORRECT;
|
||||
|
||||
if (settings.autoCapSentences()) {
|
||||
setInputTypeFlags |= InputType.TYPE_TEXT_FLAG_CAP_SENTENCES;
|
||||
}
|
||||
|
||||
if (isLandscape && settings.imeExtract()) {
|
||||
setInputTypeFlags |= InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE;
|
||||
}
|
||||
|
||||
if (!settings.imeExtract()) {
|
||||
input.setImeOptions(input.getImeOptions() | EditorInfo.IME_FLAG_NO_EXTRACT_UI);
|
||||
}
|
||||
|
||||
input.setInputType(input.getInputType() | setInputTypeFlags);
|
||||
|
||||
ImageButton sendButton = (ImageButton) view.findViewById(R.id.send);
|
||||
sendButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (input.getText().length() > 0) {
|
||||
sendCurrentMessage();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
sendButton.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
doNickCompletion(input);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
|
||||
activity.getToolbar().removeView(tabLayout);
|
||||
}
|
||||
|
||||
/**
|
||||
* On resume
|
||||
*/
|
||||
@Override
|
||||
public void onResume() {
|
||||
// register the receivers as early as possible, otherwise we may loose a broadcast message
|
||||
channelReceiver = new ConversationReceiver(server.getId(), this);
|
||||
getActivity().registerReceiver(channelReceiver, new IntentFilter(Broadcast.CONVERSATION_MESSAGE));
|
||||
getActivity().registerReceiver(channelReceiver, new IntentFilter(Broadcast.CONVERSATION_NEW));
|
||||
getActivity().registerReceiver(channelReceiver, new IntentFilter(Broadcast.CONVERSATION_REMOVE));
|
||||
getActivity().registerReceiver(channelReceiver, new IntentFilter(Broadcast.CONVERSATION_TOPIC));
|
||||
|
||||
serverReceiver = new ServerReceiver(this);
|
||||
getActivity().registerReceiver(serverReceiver, new IntentFilter(Broadcast.SERVER_UPDATE));
|
||||
|
||||
super.onResume();
|
||||
|
||||
// Start service
|
||||
Intent intent = new Intent(getActivity(), IRCService.class);
|
||||
intent.setAction(IRCService.ACTION_FOREGROUND);
|
||||
getActivity().startService(intent);
|
||||
getActivity().bindService(intent, this, 0);
|
||||
|
||||
input.setEnabled(server.isConnected());
|
||||
|
||||
// Optimization - cache field lookup
|
||||
Collection<Conversation> mConversations = server.getConversations();
|
||||
MessageListAdapter mAdapter;
|
||||
|
||||
// Fill view with messages that have been buffered while paused
|
||||
for (Conversation conversation : mConversations) {
|
||||
String name = conversation.getName();
|
||||
mAdapter = pagerAdapter.getItemAdapter(name);
|
||||
|
||||
if (mAdapter != null) {
|
||||
mAdapter.addBulkMessages(conversation.getBuffer());
|
||||
conversation.clearBuffer();
|
||||
} else {
|
||||
// Was conversation created while we were paused?
|
||||
if (pagerAdapter.getPositionByName(name) == -1) {
|
||||
onNewConversation(name);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear new message notifications for the selected conversation
|
||||
if (conversation.getStatus() == Conversation.STATUS_SELECTED && conversation.getNewMentions() > 0) {
|
||||
Intent ackIntent = new Intent(getActivity(), IRCService.class);
|
||||
ackIntent.setAction(IRCService.ACTION_ACK_NEW_MENTIONS);
|
||||
ackIntent.putExtra(IRCService.EXTRA_ACK_SERVERID, serverId);
|
||||
ackIntent.putExtra(IRCService.EXTRA_ACK_CONVTITLE, name);
|
||||
getActivity().startService(ackIntent);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove views for conversations that ended while we were paused
|
||||
int numViews = pagerAdapter.getCount();
|
||||
if (numViews > mConversations.size()) {
|
||||
for (int i = 0; i < numViews; ++i) {
|
||||
if (!mConversations.contains(pagerAdapter.getItem(i))) {
|
||||
pagerAdapter.removeConversation(i--);
|
||||
--numViews;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Join channel that has been selected in JoinActivity (onActivityResult())
|
||||
if (joinChannelBuffer != null) {
|
||||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
binder.getService().getConnection(serverId).joinChannel(joinChannelBuffer);
|
||||
joinChannelBuffer = null;
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
server.setIsForeground(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* On Pause
|
||||
*/
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
|
||||
server.setIsForeground(false);
|
||||
|
||||
if (binder != null && binder.getService() != null) {
|
||||
binder.getService().checkServiceStatus();
|
||||
}
|
||||
|
||||
getActivity().unbindService(this);
|
||||
getActivity().unregisterReceiver(channelReceiver);
|
||||
getActivity().unregisterReceiver(serverReceiver);
|
||||
}
|
||||
|
||||
/**
|
||||
* On service connected
|
||||
*/
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
this.binder = (IRCBinder) service;
|
||||
|
||||
// connect to irc server if connect has been requested
|
||||
if (server.getStatus() == Status.PRE_CONNECTING && getArguments().containsKey("connect")) {
|
||||
server.setStatus(Status.CONNECTING);
|
||||
binder.connect(server);
|
||||
} else {
|
||||
onStatusUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On service disconnected
|
||||
*/
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
this.binder = null;
|
||||
}
|
||||
/**
|
||||
* On options menu requested
|
||||
*/
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
|
||||
inflater.inflate(R.menu.conversations, menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.disconnect:
|
||||
server.setStatus(Status.DISCONNECTED);
|
||||
server.setMayReconnect(false);
|
||||
binder.getService().getConnection(serverId).quitServer();
|
||||
server.clearConversations();
|
||||
break;
|
||||
|
||||
case R.id.close:
|
||||
Conversation conversationToClose = pagerAdapter.getItem(pager.getCurrentItem());
|
||||
// Make sure we part a channel when closing the channel conversation
|
||||
if (conversationToClose.getType() == Conversation.TYPE_CHANNEL) {
|
||||
binder.getService().getConnection(serverId).partChannel(conversationToClose.getName());
|
||||
}
|
||||
else if (conversationToClose.getType() == Conversation.TYPE_QUERY) {
|
||||
server.removeConversation(conversationToClose.getName());
|
||||
onRemoveConversation(conversationToClose.getName());
|
||||
} else {
|
||||
Toast.makeText(getActivity(), getResources().getString(R.string.close_server_window), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
break;
|
||||
|
||||
case R.id.join:
|
||||
startActivityForResult(new Intent(getActivity(), JoinActivity.class), REQUEST_CODE_JOIN);
|
||||
break;
|
||||
|
||||
case R.id.users:
|
||||
Conversation conversationForUserList = pagerAdapter.getItem(pager.getCurrentItem());
|
||||
if (conversationForUserList.getType() == Conversation.TYPE_CHANNEL) {
|
||||
Intent intent = new Intent(getActivity(), UsersActivity.class);
|
||||
intent.putExtra(
|
||||
Extra.USERS,
|
||||
binder.getService().getConnection(server.getId()).getUsersAsStringArray(
|
||||
conversationForUserList.getName()
|
||||
)
|
||||
);
|
||||
startActivityForResult(intent, REQUEST_CODE_USERS);
|
||||
} else {
|
||||
Toast.makeText(getActivity(), getResources().getString(R.string.only_usable_from_channel), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get server object assigned to this activity
|
||||
*
|
||||
* @return the server object
|
||||
*/
|
||||
public Server getServer() {
|
||||
return server;
|
||||
}
|
||||
|
||||
/**
|
||||
* On conversation message
|
||||
*/
|
||||
@Override
|
||||
public void onConversationMessage(String target) {
|
||||
Conversation conversation = server.getConversation(target);
|
||||
|
||||
if (conversation == null) {
|
||||
// In an early state it can happen that the conversation object
|
||||
// is not created yet.
|
||||
return;
|
||||
}
|
||||
|
||||
MessageListAdapter adapter = pagerAdapter.getItemAdapter(target);
|
||||
|
||||
while(conversation.hasBufferedMessages()) {
|
||||
Message message = conversation.pollBufferedMessage();
|
||||
|
||||
if (adapter != null && message != null) {
|
||||
adapter.addMessage(message);
|
||||
int status;
|
||||
|
||||
switch (message.getType())
|
||||
{
|
||||
case Message.TYPE_MISC:
|
||||
status = Conversation.STATUS_MISC;
|
||||
break;
|
||||
|
||||
default:
|
||||
status = Conversation.STATUS_MESSAGE;
|
||||
break;
|
||||
}
|
||||
conversation.setStatus(status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On new conversation
|
||||
*/
|
||||
@Override
|
||||
public void onNewConversation(String target) {
|
||||
createNewConversation(target);
|
||||
|
||||
pager.setCurrentItem(pagerAdapter.getCount() - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new conversation in the pager adapter for the
|
||||
* given target conversation.
|
||||
*
|
||||
* @param target
|
||||
*/
|
||||
public void createNewConversation(String target) {
|
||||
pagerAdapter.addConversation(server.getConversation(target));
|
||||
|
||||
tabLayout.update();
|
||||
}
|
||||
|
||||
/**
|
||||
* On conversation remove
|
||||
*/
|
||||
@Override
|
||||
public void onRemoveConversation(String target) {
|
||||
int position = pagerAdapter.getPositionByName(target);
|
||||
|
||||
if (position != -1) {
|
||||
pagerAdapter.removeConversation(position);
|
||||
}
|
||||
|
||||
tabLayout.update();
|
||||
}
|
||||
|
||||
/**
|
||||
* On topic change
|
||||
*/
|
||||
@Override
|
||||
public void onTopicChanged(String target) {
|
||||
// No implementation
|
||||
}
|
||||
|
||||
/**
|
||||
* On server status update
|
||||
*/
|
||||
@Override
|
||||
public void onStatusUpdate() {
|
||||
if (server.isConnected()) {
|
||||
input.setEnabled(true);
|
||||
} else {
|
||||
input.setEnabled(false);
|
||||
|
||||
if (server.getStatus() == Status.CONNECTING) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Service is not connected or initialized yet - See #54
|
||||
if (binder == null || binder.getService() == null || binder.getService().getSettings() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!binder.getService().getSettings().isReconnectEnabled() && !reconnectDialogActive) {
|
||||
reconnectDialogActive = true;
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
builder.setMessage(getResources().getString(R.string.reconnect_after_disconnect, server.getTitle()))
|
||||
.setCancelable(false)
|
||||
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
if (!server.isDisconnected()) {
|
||||
reconnectDialogActive = false;
|
||||
return;
|
||||
}
|
||||
binder.getService().getConnection(server.getId()).setAutojoinChannels(
|
||||
server.getCurrentChannelNames()
|
||||
);
|
||||
server.setStatus(Status.CONNECTING);
|
||||
binder.connect(server);
|
||||
reconnectDialogActive = false;
|
||||
}
|
||||
})
|
||||
.setNegativeButton(getString(R.string.negative_button), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
server.setMayReconnect(false);
|
||||
reconnectDialogActive = false;
|
||||
dialog.cancel();
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On activity result
|
||||
*/
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (resultCode != Activity.RESULT_OK) {
|
||||
// ignore other result codes
|
||||
return;
|
||||
}
|
||||
|
||||
switch (requestCode) {
|
||||
case REQUEST_CODE_JOIN:
|
||||
joinChannelBuffer = data.getExtras().getString("channel");
|
||||
break;
|
||||
case REQUEST_CODE_USERS:
|
||||
Intent intent = new Intent(getActivity(), UserActivity.class);
|
||||
intent.putExtra(Extra.USER, data.getStringExtra(Extra.USER));
|
||||
startActivityForResult(intent, REQUEST_CODE_USER);
|
||||
break;
|
||||
case REQUEST_CODE_NICK_COMPLETION:
|
||||
insertNickCompletion(input, data.getExtras().getString(Extra.USER));
|
||||
break;
|
||||
case REQUEST_CODE_USER:
|
||||
final int actionId = data.getExtras().getInt(Extra.ACTION);
|
||||
final String nickname = data.getExtras().getString(Extra.USER);
|
||||
final IRCConnection connection = binder.getService().getConnection(server.getId());
|
||||
final String conversation = server.getSelectedConversation();
|
||||
final Handler handler = new Handler();
|
||||
|
||||
// XXX: Implement me - The action should be handled after onResume()
|
||||
// to catch the broadcasts... now we just wait a second
|
||||
// Yes .. that's very ugly - we need some kind of queue that is handled after onResume()
|
||||
|
||||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
String nicknameWithoutPrefix = nickname;
|
||||
|
||||
while (
|
||||
nicknameWithoutPrefix.startsWith("@") ||
|
||||
nicknameWithoutPrefix.startsWith("+") ||
|
||||
nicknameWithoutPrefix.startsWith(".") ||
|
||||
nicknameWithoutPrefix.startsWith("%")
|
||||
) {
|
||||
// Strip prefix(es) now
|
||||
nicknameWithoutPrefix = nicknameWithoutPrefix.substring(1);
|
||||
}
|
||||
|
||||
switch (actionId) {
|
||||
case User.ACTION_REPLY:
|
||||
final String replyText = nicknameWithoutPrefix + ": ";
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
input.setText(replyText);
|
||||
input.setSelection(replyText.length());
|
||||
}
|
||||
});
|
||||
break;
|
||||
case User.ACTION_QUERY:
|
||||
Conversation query = server.getConversation(nicknameWithoutPrefix);
|
||||
if (query == null) {
|
||||
// Open a query if there's none yet
|
||||
query = new Query(nicknameWithoutPrefix);
|
||||
query.setHistorySize(binder.getService().getSettings().getHistorySize());
|
||||
server.addConversation(query);
|
||||
|
||||
Intent intent = Broadcast.createConversationIntent(
|
||||
Broadcast.CONVERSATION_NEW,
|
||||
server.getId(),
|
||||
nicknameWithoutPrefix
|
||||
);
|
||||
binder.getService().sendBroadcast(intent);
|
||||
}
|
||||
break;
|
||||
case User.ACTION_OP:
|
||||
connection.op(conversation, nicknameWithoutPrefix);
|
||||
break;
|
||||
case User.ACTION_DEOP:
|
||||
connection.deOp(conversation, nicknameWithoutPrefix);
|
||||
break;
|
||||
case User.ACTION_VOICE:
|
||||
connection.voice(conversation, nicknameWithoutPrefix);
|
||||
break;
|
||||
case User.ACTION_DEVOICE:
|
||||
connection.deVoice(conversation, nicknameWithoutPrefix);
|
||||
break;
|
||||
case User.ACTION_KICK:
|
||||
connection.kick(conversation, nicknameWithoutPrefix);
|
||||
break;
|
||||
case User.ACTION_BAN:
|
||||
connection.ban(conversation, nicknameWithoutPrefix + "!*@*");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void sendCurrentMessage() {
|
||||
sendMessage(input.getText().toString());
|
||||
|
||||
// Workaround for a race condition in EditText
|
||||
// Instead of calling input.setText("");
|
||||
// See:
|
||||
// - https://github.com/pocmo/Yaaic/issues/67
|
||||
// - http://code.google.com/p/android/issues/detail?id=17508
|
||||
TextKeyListener.clear(input.getText());
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message in this conversation
|
||||
*
|
||||
* @param text The text of the message
|
||||
*/
|
||||
private void sendMessage(String text) {
|
||||
if (text.equals("")) {
|
||||
// ignore empty messages
|
||||
return;
|
||||
}
|
||||
|
||||
if (!server.isConnected()) {
|
||||
Message message = new Message(getString(R.string.message_not_connected));
|
||||
message.setColor(Message.COLOR_RED);
|
||||
message.setIcon(R.drawable.error);
|
||||
server.getConversation(server.getSelectedConversation()).addMessage(message);
|
||||
onConversationMessage(server.getSelectedConversation());
|
||||
}
|
||||
|
||||
scrollback.addMessage(text);
|
||||
|
||||
Conversation conversation = pagerAdapter.getItem(pager.getCurrentItem());
|
||||
|
||||
if (conversation != null) {
|
||||
if (!text.trim().startsWith("/")) {
|
||||
if (conversation.getType() != Conversation.TYPE_SERVER) {
|
||||
String nickname = binder.getService().getConnection(serverId).getNick();
|
||||
//conversation.addMessage(new Message("<" + nickname + "> " + text));
|
||||
conversation.addMessage(new Message(text, nickname));
|
||||
binder.getService().getConnection(serverId).sendMessage(conversation.getName(), text);
|
||||
} else {
|
||||
Message message = new Message(getString(R.string.chat_only_form_channel));
|
||||
message.setColor(Message.COLOR_YELLOW);
|
||||
message.setIcon(R.drawable.warning);
|
||||
conversation.addMessage(message);
|
||||
}
|
||||
onConversationMessage(conversation.getName());
|
||||
} else {
|
||||
CommandParser.getInstance().parse(text, server, conversation, binder.getService());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Complete a nick in the input line
|
||||
*/
|
||||
private void doNickCompletion(EditText input) {
|
||||
String text = input.getText().toString();
|
||||
|
||||
if (text.length() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
String[] tokens = text.split("[\\s,.-]+");
|
||||
|
||||
if (tokens.length <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
String word = tokens[tokens.length - 1].toLowerCase();
|
||||
tokens[tokens.length - 1] = null;
|
||||
|
||||
int begin = input.getSelectionStart();
|
||||
int end = input.getSelectionEnd();
|
||||
int cursor = Math.min(begin, end);
|
||||
int sel_end = Math.max(begin, end);
|
||||
|
||||
boolean in_selection = (cursor != sel_end);
|
||||
|
||||
if (in_selection) {
|
||||
word = text.substring(cursor, sel_end);
|
||||
} else {
|
||||
// use the word at the curent cursor position
|
||||
while (true) {
|
||||
cursor -= 1;
|
||||
if (cursor <= 0 || text.charAt(cursor) == ' ') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cursor < 0) {
|
||||
cursor = 0;
|
||||
}
|
||||
|
||||
if (text.charAt(cursor) == ' ') {
|
||||
cursor += 1;
|
||||
}
|
||||
|
||||
sel_end = text.indexOf(' ', cursor);
|
||||
|
||||
if (sel_end == -1) {
|
||||
sel_end = text.length();
|
||||
}
|
||||
|
||||
word = text.substring(cursor, sel_end);
|
||||
}
|
||||
// Log.d("Yaaic", "Trying to complete nick: " + word);
|
||||
|
||||
Conversation conversationForUserList = pagerAdapter.getItem(pager.getCurrentItem());
|
||||
|
||||
String[] users = null;
|
||||
|
||||
if (conversationForUserList.getType() == Conversation.TYPE_CHANNEL) {
|
||||
users = binder.getService().getConnection(server.getId()).getUsersAsStringArray(
|
||||
conversationForUserList.getName()
|
||||
);
|
||||
}
|
||||
|
||||
// go through users and add matches
|
||||
if (users != null) {
|
||||
List<Integer> result = new ArrayList<Integer>();
|
||||
|
||||
for (int i = 0; i < users.length; i++) {
|
||||
String nick = removeStatusChar(users[i].toLowerCase());
|
||||
if (nick.startsWith(word.toLowerCase())) {
|
||||
result.add(Integer.valueOf(i));
|
||||
}
|
||||
}
|
||||
|
||||
if (result.size() == 1) {
|
||||
input.setSelection(cursor, sel_end);
|
||||
insertNickCompletion(input, users[result.get(0).intValue()]);
|
||||
} else if (result.size() > 0) {
|
||||
Intent intent = new Intent(getActivity(), UsersActivity.class);
|
||||
String[] extra = new String[result.size()];
|
||||
int i = 0;
|
||||
|
||||
for (Integer n : result) {
|
||||
extra[i++] = users[n.intValue()];
|
||||
}
|
||||
|
||||
input.setSelection(cursor, sel_end);
|
||||
intent.putExtra(Extra.USERS, extra);
|
||||
startActivityForResult(intent, REQUEST_CODE_NICK_COMPLETION);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a given nick completion into the input line
|
||||
*
|
||||
* @param input The input line widget, with the incomplete nick selected
|
||||
* @param nick The completed nick
|
||||
*/
|
||||
private void insertNickCompletion(final EditText input, String nick) {
|
||||
int start = input.getSelectionStart();
|
||||
int end = input.getSelectionEnd();
|
||||
nick = removeStatusChar(nick);
|
||||
|
||||
if (start == 0) {
|
||||
nick += ":";
|
||||
}
|
||||
|
||||
nick += " ";
|
||||
input.getText().replace(start, end, nick, 0, nick.length());
|
||||
// put cursor after inserted text
|
||||
input.setSelection(start + nick.length());
|
||||
input.clearComposingText();
|
||||
input.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// make the softkeyboard come up again (only if no hw keyboard is attached)
|
||||
openSoftKeyboard(input);
|
||||
}
|
||||
});
|
||||
|
||||
input.requestFocus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the soft keyboard (helper function)
|
||||
*/
|
||||
private void openSoftKeyboard(View view) {
|
||||
((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE))
|
||||
.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the status char off the front of a nick if one is present
|
||||
*
|
||||
* @param nick
|
||||
* @return nick without statuschar
|
||||
*/
|
||||
private String removeStatusChar(String nick) {
|
||||
/* Discard status characters */
|
||||
if (nick.startsWith("@") || nick.startsWith("+")
|
||||
|| nick.startsWith("%")) {
|
||||
nick = nick.substring(1);
|
||||
}
|
||||
return nick;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2015 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.fragment;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.Yaaic;
|
||||
import org.yaaic.activity.AddServerActivity;
|
||||
import org.yaaic.activity.YaaicActivity;
|
||||
import org.yaaic.adapter.ServersAdapter;
|
||||
import org.yaaic.db.Database;
|
||||
import org.yaaic.irc.IRCBinder;
|
||||
import org.yaaic.listener.ServerListener;
|
||||
import org.yaaic.model.Broadcast;
|
||||
import org.yaaic.model.Extra;
|
||||
import org.yaaic.model.Server;
|
||||
import org.yaaic.model.Status;
|
||||
import org.yaaic.receiver.ServerReceiver;
|
||||
|
||||
/**
|
||||
* Fragment showing a list of configured servers.
|
||||
*/
|
||||
public class OverviewFragment extends Fragment implements ServerListener, ServersAdapter.ClickListener, View.OnClickListener {
|
||||
public static final String TRANSACTION_TAG = "fragment_overview";
|
||||
|
||||
private ServersAdapter adapter;
|
||||
private YaaicActivity activity;
|
||||
private BroadcastReceiver receiver;
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
|
||||
if (!(activity instanceof YaaicActivity)) {
|
||||
throw new IllegalArgumentException("Activity has to implement YaaicActivity interface");
|
||||
}
|
||||
|
||||
this.activity = (YaaicActivity) activity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
activity.setToolbarTitle(getString(R.string.app_name));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_servers, container, false);
|
||||
|
||||
adapter = new ServersAdapter(this);
|
||||
|
||||
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
|
||||
recyclerView.setAdapter(adapter);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
|
||||
|
||||
ImageButton button = (ImageButton) view.findViewById(R.id.fab);
|
||||
button.setOnClickListener(this);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
receiver = new ServerReceiver(this);
|
||||
getActivity().registerReceiver(receiver, new IntentFilter(Broadcast.SERVER_UPDATE));
|
||||
|
||||
adapter.loadServers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
|
||||
getActivity().unregisterReceiver(receiver);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
final Context context = view.getContext();
|
||||
|
||||
Intent intent = new Intent(context, AddServerActivity.class);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServerSelected(Server server) {
|
||||
activity.onServerSelected(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectToServer(Server server) {
|
||||
IRCBinder binder = activity.getBinder();
|
||||
|
||||
if (binder != null && server.getStatus() == Status.DISCONNECTED) {
|
||||
binder.connect(server);
|
||||
server.setStatus(Status.CONNECTING);
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnectFromServer(Server server) {
|
||||
IRCBinder binder = activity.getBinder();
|
||||
|
||||
if (binder != null) {
|
||||
server.clearConversations();
|
||||
server.setStatus(Status.DISCONNECTED);
|
||||
server.setMayReconnect(false);
|
||||
binder.getService().getConnection(server.getId()).quitServer();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEditServer(Server server) {
|
||||
if (server.getStatus() != Status.DISCONNECTED) {
|
||||
Toast.makeText(getActivity(), getResources().getString(R.string.disconnect_before_editing), Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Intent intent = new Intent(getActivity(), AddServerActivity.class);
|
||||
intent.putExtra(Extra.SERVER, server.getId());
|
||||
startActivityForResult(intent, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeleteServer(Server server) {
|
||||
IRCBinder binder = activity.getBinder();
|
||||
|
||||
if (binder != null) {
|
||||
binder.getService().getConnection(server.getId()).quitServer();
|
||||
|
||||
Database db = new Database(getActivity());
|
||||
db.removeServerById(server.getId());
|
||||
db.close();
|
||||
|
||||
Yaaic.getInstance().removeServerById(server.getId());
|
||||
adapter.loadServers();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusUpdate() {
|
||||
adapter.loadServers();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package org.yaaic.fragment;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceFragment;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.activity.YaaicActivity;
|
||||
|
||||
/**
|
||||
* Fragment displaying all settings.
|
||||
*/
|
||||
public class SettingsFragment extends PreferenceFragment {
|
||||
public static final String TRANSACTION_TAG = "fragment_settings";
|
||||
|
||||
private YaaicActivity activity;
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
|
||||
if (!(activity instanceof YaaicActivity)) {
|
||||
throw new IllegalArgumentException("Activity has to implement YaaicActivity interface");
|
||||
}
|
||||
|
||||
this.activity = (YaaicActivity) activity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
activity.setToolbarTitle(getString(R.string.navigation_settings));
|
||||
|
||||
addPreferencesFromResource(R.xml.preferences);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2010 Sebastian Kaspari
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
|
@ -17,7 +17,7 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
package org.yaaic.irc;
|
||||
|
||||
import org.yaaic.model.Server;
|
||||
|
@ -26,41 +26,42 @@ import android.os.Binder;
|
|||
|
||||
/**
|
||||
* Binder for service communication
|
||||
*
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class IRCBinder extends Binder
|
||||
{
|
||||
private IRCService service;
|
||||
|
||||
/**
|
||||
* Create a new binder for given service
|
||||
*
|
||||
* @param service
|
||||
*/
|
||||
public IRCBinder(IRCService service)
|
||||
{
|
||||
super();
|
||||
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to given server
|
||||
*
|
||||
* @param server
|
||||
*/
|
||||
public void connect(final Server server)
|
||||
{
|
||||
service.connect(server);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get service associated with this service
|
||||
* @return
|
||||
*/
|
||||
public IRCService getService()
|
||||
{
|
||||
return service;
|
||||
}
|
||||
private final IRCService service;
|
||||
|
||||
/**
|
||||
* Create a new binder for given service
|
||||
*
|
||||
* @param service
|
||||
*/
|
||||
public IRCBinder(IRCService service)
|
||||
{
|
||||
super();
|
||||
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to given server
|
||||
*
|
||||
* @param server
|
||||
*/
|
||||
public void connect(final Server server)
|
||||
{
|
||||
service.connect(server);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get service associated with this binder
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public IRCService getService()
|
||||
{
|
||||
return service;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,637 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
Copyright 2012 Daniel E. Moctezuma <democtezuma@gmail.com>
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.irc;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
import org.jibble.pircbot.IrcException;
|
||||
import org.jibble.pircbot.NickAlreadyInUseException;
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.Yaaic;
|
||||
import org.yaaic.activity.MainActivity;
|
||||
import org.yaaic.db.Database;
|
||||
import org.yaaic.model.Broadcast;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Message;
|
||||
import org.yaaic.model.Server;
|
||||
import org.yaaic.model.ServerInfo;
|
||||
import org.yaaic.model.Settings;
|
||||
import org.yaaic.model.Status;
|
||||
import org.yaaic.receiver.ReconnectReceiver;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.SystemClock;
|
||||
|
||||
/**
|
||||
* The background service for managing the irc connections
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class IRCService extends Service
|
||||
{
|
||||
public static final String ACTION_FOREGROUND = "org.yaaic.service.foreground";
|
||||
public static final String ACTION_BACKGROUND = "org.yaaic.service.background";
|
||||
public static final String ACTION_ACK_NEW_MENTIONS = "org.yaaic.service.ack_new_mentions";
|
||||
public static final String EXTRA_ACK_SERVERID = "org.yaaic.service.ack_serverid";
|
||||
public static final String EXTRA_ACK_CONVTITLE = "org.yaaic.service.ack_convtitle";
|
||||
|
||||
private static final int FOREGROUND_NOTIFICATION = 1;
|
||||
private static final int NOTIFICATION_LED_OFF_MS = 1000;
|
||||
private static final int NOTIFICATION_LED_ON_MS = 300;
|
||||
private static final int NOTIFICATION_LED_COLOR = 0xff00ff00;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private static final Class[] mStartForegroundSignature = new Class[] { int.class, Notification.class };
|
||||
@SuppressWarnings("rawtypes")
|
||||
private static final Class[] mStopForegroundSignature = new Class[] { boolean.class };
|
||||
@SuppressWarnings("rawtypes")
|
||||
private static final Class[] mSetForegroudSignaure = new Class[] { boolean.class };
|
||||
|
||||
private final IRCBinder binder;
|
||||
private final HashMap<Integer, IRCConnection> connections;
|
||||
private boolean foreground = false;
|
||||
private final ArrayList<String> connectedServerTitles;
|
||||
private final LinkedHashMap<String, Conversation> mentions;
|
||||
private int newMentions = 0;
|
||||
|
||||
private NotificationManager notificationManager;
|
||||
private Method mStartForeground;
|
||||
private Method mStopForeground;
|
||||
private final Object[] mStartForegroundArgs = new Object[2];
|
||||
private final Object[] mStopForegroundArgs = new Object[1];
|
||||
private Notification notification;
|
||||
private Settings settings;
|
||||
|
||||
private HashMap<Integer, PendingIntent> alarmIntents;
|
||||
private HashMap<Integer, ReconnectReceiver> alarmReceivers;
|
||||
private final Object alarmIntentsLock;
|
||||
|
||||
/**
|
||||
* Create new service
|
||||
*/
|
||||
public IRCService()
|
||||
{
|
||||
super();
|
||||
|
||||
this.connections = new HashMap<Integer, IRCConnection>();
|
||||
this.binder = new IRCBinder(this);
|
||||
this.connectedServerTitles = new ArrayList<String>();
|
||||
this.mentions = new LinkedHashMap<String, Conversation>();
|
||||
this.alarmIntents = new HashMap<Integer, PendingIntent>();
|
||||
this.alarmReceivers = new HashMap<Integer, ReconnectReceiver>();
|
||||
this.alarmIntentsLock = new Object();
|
||||
}
|
||||
|
||||
/**
|
||||
* On create
|
||||
*/
|
||||
@Override
|
||||
public void onCreate()
|
||||
{
|
||||
super.onCreate();
|
||||
|
||||
settings = new Settings(getBaseContext());
|
||||
notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
||||
|
||||
try {
|
||||
mStartForeground = getClass().getMethod("startForeground", mStartForegroundSignature);
|
||||
mStopForeground = getClass().getMethod("stopForeground", mStopForegroundSignature);
|
||||
} catch (NoSuchMethodException e) {
|
||||
// Running on an older platform.
|
||||
mStartForeground = mStopForeground = null;
|
||||
}
|
||||
|
||||
// Broadcast changed server list
|
||||
sendBroadcast(new Intent(Broadcast.SERVER_UPDATE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Settings object
|
||||
*
|
||||
* @return the settings helper object
|
||||
*/
|
||||
public Settings getSettings()
|
||||
{
|
||||
return settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* On start (will be called on pre-2.0 platform. On 2.0 or later onStartCommand()
|
||||
* will be called)
|
||||
*/
|
||||
@Override
|
||||
public void onStart(Intent intent, int startId)
|
||||
{
|
||||
super.onStart(intent, startId);
|
||||
handleCommand(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* On start command (Android >= 2.0)
|
||||
*
|
||||
* @param intent
|
||||
* @param flags
|
||||
* @param startId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId)
|
||||
{
|
||||
if (intent != null) {
|
||||
handleCommand(intent);
|
||||
}
|
||||
|
||||
// We want this service to continue running until it is explicitly
|
||||
// stopped, so return sticky.
|
||||
//return START_STICKY;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle command
|
||||
*
|
||||
* @param intent
|
||||
*/
|
||||
private void handleCommand(Intent intent)
|
||||
{
|
||||
if (ACTION_FOREGROUND.equals(intent.getAction())) {
|
||||
if (foreground) {
|
||||
return; // XXX: We are already in foreground...
|
||||
}
|
||||
foreground = true;
|
||||
|
||||
// Set the icon, scrolling text and timestamp
|
||||
notification = new Notification(R.drawable.ic_notification, getText(R.string.notification_running), System.currentTimeMillis());
|
||||
|
||||
// The PendingIntent to launch our activity if the user selects this notification
|
||||
Intent notifyIntent = new Intent(this, MainActivity.class);
|
||||
notifyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notifyIntent, 0);
|
||||
|
||||
// Set the info for the views that show in the notification panel.
|
||||
notification.setLatestEventInfo(this, getText(R.string.app_name), getText(R.string.notification_not_connected), contentIntent);
|
||||
|
||||
startForegroundCompat(FOREGROUND_NOTIFICATION, notification);
|
||||
} else if (ACTION_BACKGROUND.equals(intent.getAction()) && !foreground) {
|
||||
stopForegroundCompat(FOREGROUND_NOTIFICATION);
|
||||
} else if (ACTION_ACK_NEW_MENTIONS.equals(intent.getAction())) {
|
||||
ackNewMentions(intent.getIntExtra(EXTRA_ACK_SERVERID, -1), intent.getStringExtra(EXTRA_ACK_CONVTITLE));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update notification and vibrate and/or flash a LED light if needed
|
||||
*
|
||||
* @param text The ticker text to display
|
||||
* @param contentText The text to display in the notification dropdown
|
||||
* @param vibrate True if the device should vibrate, false otherwise
|
||||
* @param sound True if the device should make sound, false otherwise
|
||||
* @param light True if the device should flash a LED light, false otherwise
|
||||
*/
|
||||
private void updateNotification(String text, String contentText, boolean vibrate, boolean sound, boolean light)
|
||||
{
|
||||
if (foreground) {
|
||||
notification = new Notification(R.drawable.ic_notification, text, System.currentTimeMillis());
|
||||
Intent notifyIntent = new Intent(this, MainActivity.class);
|
||||
notifyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notifyIntent, 0);
|
||||
|
||||
if (contentText == null) {
|
||||
if (newMentions >= 1) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Conversation conv : mentions.values()) {
|
||||
sb.append(conv.getName() + " (" + conv.getNewMentions() + "), ");
|
||||
}
|
||||
contentText = getString(R.string.notification_mentions, sb.substring(0, sb.length()-2));
|
||||
} else if (!connectedServerTitles.isEmpty()) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String title : connectedServerTitles) {
|
||||
sb.append(title + ", ");
|
||||
}
|
||||
contentText = getString(R.string.notification_connected, sb.substring(0, sb.length()-2));
|
||||
} else {
|
||||
contentText = getString(R.string.notification_not_connected);
|
||||
}
|
||||
}
|
||||
|
||||
notification.setLatestEventInfo(this, getText(R.string.app_name), contentText, contentIntent);
|
||||
|
||||
if (vibrate) {
|
||||
notification.defaults |= Notification.DEFAULT_VIBRATE;
|
||||
}
|
||||
|
||||
if (sound) {
|
||||
notification.defaults |= Notification.DEFAULT_SOUND;
|
||||
}
|
||||
|
||||
if (light) {
|
||||
notification.ledARGB = NOTIFICATION_LED_COLOR;
|
||||
notification.ledOnMS = NOTIFICATION_LED_ON_MS;
|
||||
notification.ledOffMS = NOTIFICATION_LED_OFF_MS;
|
||||
notification.flags |= Notification.FLAG_SHOW_LIGHTS;
|
||||
}
|
||||
|
||||
notification.number = newMentions;
|
||||
|
||||
notificationManager.notify(FOREGROUND_NOTIFICATION, notification);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a string uniquely identifying a conversation.
|
||||
*/
|
||||
public String getConversationId(int serverId, String title) {
|
||||
return "" + serverId + ":" + title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the service of a new mention (updates the status bar notification)
|
||||
*
|
||||
* @param conversation The conversation where the new mention occurred
|
||||
* @param msg The text of the new message
|
||||
* @param vibrate Whether the notification should include vibration
|
||||
* @param sound Whether the notification should include sound
|
||||
* @param light Whether the notification should include a flashing LED light
|
||||
*/
|
||||
public synchronized void addNewMention(int serverId, Conversation conversation, String msg, boolean vibrate, boolean sound, boolean light)
|
||||
{
|
||||
if (conversation == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
conversation.addNewMention();
|
||||
++newMentions;
|
||||
String convId = getConversationId(serverId, conversation.getName());
|
||||
if (!mentions.containsKey(convId)) {
|
||||
mentions.put(convId, conversation);
|
||||
}
|
||||
|
||||
if (newMentions == 1) {
|
||||
updateNotification(msg, msg, vibrate, sound, light);
|
||||
} else {
|
||||
updateNotification(msg, null, vibrate, sound, light);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the service that new mentions have been viewed (updates the status bar notification)
|
||||
*
|
||||
* @param convTitle The title of the conversation whose new mentions have been read
|
||||
*/
|
||||
public synchronized void ackNewMentions(int serverId, String convTitle)
|
||||
{
|
||||
if (convTitle == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Conversation conversation = mentions.remove(getConversationId(serverId, convTitle));
|
||||
if (conversation == null) {
|
||||
return;
|
||||
}
|
||||
newMentions -= conversation.getNewMentions();
|
||||
conversation.clearNewMentions();
|
||||
if (newMentions < 0) {
|
||||
newMentions = 0;
|
||||
}
|
||||
|
||||
updateNotification(null, null, false, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the service of connection to a server (updates the status bar notification)
|
||||
*
|
||||
* @param title The title of the newly connected server
|
||||
*/
|
||||
public synchronized void notifyConnected(String title)
|
||||
{
|
||||
connectedServerTitles.add(title);
|
||||
updateNotification(getString(R.string.notification_connected, title), null, false, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the service of disconnection from a server (updates the status bar notification)
|
||||
*
|
||||
* @param title The title of the disconnected server
|
||||
*/
|
||||
public synchronized void notifyDisconnected(String title)
|
||||
{
|
||||
connectedServerTitles.remove(title);
|
||||
updateNotification(getString(R.string.notification_disconnected, title), null, false, false, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is a wrapper around the new startForeground method, using the older
|
||||
* APIs if it is not available.
|
||||
*/
|
||||
private void startForegroundCompat(int id, Notification notification)
|
||||
{
|
||||
// If we have the new startForeground API, then use it.
|
||||
if (mStartForeground != null) {
|
||||
mStartForegroundArgs[0] = Integer.valueOf(id);
|
||||
mStartForegroundArgs[1] = notification;
|
||||
try {
|
||||
mStartForeground.invoke(this, mStartForegroundArgs);
|
||||
} catch (InvocationTargetException e) {
|
||||
// Should not happen.
|
||||
} catch (IllegalAccessException e) {
|
||||
// Should not happen.
|
||||
}
|
||||
} else {
|
||||
// Fall back on the old API.
|
||||
try {
|
||||
Method setForeground = getClass().getMethod("setForeground", mSetForegroudSignaure);
|
||||
setForeground.invoke(this, new Object[] { true });
|
||||
} catch (NoSuchMethodException exception) {
|
||||
// Should not happen
|
||||
} catch (InvocationTargetException e) {
|
||||
// Should not happen.
|
||||
} catch (IllegalAccessException e) {
|
||||
// Should not happen.
|
||||
}
|
||||
|
||||
notificationManager.notify(id, notification);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a wrapper around the new stopForeground method, using the older
|
||||
* APIs if it is not available.
|
||||
*/
|
||||
public void stopForegroundCompat(int id)
|
||||
{
|
||||
foreground = false;
|
||||
|
||||
// If we have the new stopForeground API, then use it.
|
||||
if (mStopForeground != null) {
|
||||
mStopForegroundArgs[0] = Boolean.TRUE;
|
||||
try {
|
||||
mStopForeground.invoke(this, mStopForegroundArgs);
|
||||
} catch (InvocationTargetException e) {
|
||||
// Should not happen.
|
||||
} catch (IllegalAccessException e) {
|
||||
// Should not happen.
|
||||
}
|
||||
} else {
|
||||
// Fall back on the old API. Note to cancel BEFORE changing the
|
||||
// foreground state, since we could be killed at that point.
|
||||
notificationManager.cancel(id);
|
||||
|
||||
try {
|
||||
Method setForeground = getClass().getMethod("setForeground", mSetForegroudSignaure);
|
||||
setForeground.invoke(this, new Object[] { true });
|
||||
} catch (NoSuchMethodException exception) {
|
||||
// Should not happen
|
||||
} catch (InvocationTargetException e) {
|
||||
// Should not happen.
|
||||
} catch (IllegalAccessException e) {
|
||||
// Should not happen.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to the given server
|
||||
*/
|
||||
public void connect(final Server server)
|
||||
{
|
||||
final int serverId = server.getId();
|
||||
final int reconnectInterval = settings.getReconnectInterval()*60000;
|
||||
final IRCService service = this;
|
||||
|
||||
if (settings.isReconnectEnabled()) {
|
||||
server.setMayReconnect(true);
|
||||
}
|
||||
|
||||
new Thread("Connect thread for " + server.getTitle()) {
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized(alarmIntentsLock) {
|
||||
alarmIntents.remove(serverId);
|
||||
ReconnectReceiver lastReceiver = alarmReceivers.remove(serverId);
|
||||
if (lastReceiver != null) {
|
||||
unregisterReceiver(lastReceiver);
|
||||
}
|
||||
}
|
||||
|
||||
if (settings.isReconnectEnabled() && !server.mayReconnect()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
IRCConnection connection = getConnection(serverId);
|
||||
|
||||
connection.setNickname(server.getIdentity().getNickname());
|
||||
connection.setAliases(server.getIdentity().getAliases());
|
||||
connection.setIdent(server.getIdentity().getIdent());
|
||||
connection.setRealName(server.getIdentity().getRealName());
|
||||
connection.setUseSSL(server.useSSL());
|
||||
|
||||
if (server.getCharset() != null) {
|
||||
connection.setEncoding(server.getCharset());
|
||||
}
|
||||
|
||||
if (server.getAuthentication().hasSaslCredentials()) {
|
||||
connection.setSaslCredentials(
|
||||
server.getAuthentication().getSaslUsername(),
|
||||
server.getAuthentication().getSaslPassword()
|
||||
);
|
||||
}
|
||||
|
||||
if (server.getPassword() != "") {
|
||||
connection.connect(server.getHost(), server.getPort(), server.getPassword());
|
||||
} else {
|
||||
connection.connect(server.getHost(), server.getPort());
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
server.setStatus(Status.DISCONNECTED);
|
||||
|
||||
Intent sIntent = Broadcast.createServerIntent(Broadcast.SERVER_UPDATE, serverId);
|
||||
sendBroadcast(sIntent);
|
||||
|
||||
IRCConnection connection = getConnection(serverId);
|
||||
|
||||
Message message;
|
||||
|
||||
if (e instanceof NickAlreadyInUseException) {
|
||||
message = new Message(getString(R.string.nickname_in_use, connection.getNick()));
|
||||
server.setMayReconnect(false);
|
||||
} else if (e instanceof IrcException) {
|
||||
message = new Message(getString(R.string.irc_login_error, server.getHost(), server.getPort()));
|
||||
server.setMayReconnect(false);
|
||||
} else {
|
||||
message = new Message(getString(R.string.could_not_connect, server.getHost(), server.getPort()));
|
||||
if (settings.isReconnectEnabled()) {
|
||||
Intent rIntent = new Intent(Broadcast.SERVER_RECONNECT + serverId);
|
||||
PendingIntent pendingRIntent = PendingIntent.getBroadcast(service, 0, rIntent, 0);
|
||||
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
|
||||
ReconnectReceiver receiver = new ReconnectReceiver(service, server);
|
||||
synchronized(alarmIntentsLock) {
|
||||
alarmReceivers.put(serverId, receiver);
|
||||
registerReceiver(receiver, new IntentFilter(Broadcast.SERVER_RECONNECT + serverId));
|
||||
am.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + reconnectInterval, pendingRIntent);
|
||||
alarmIntents.put(serverId, pendingRIntent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
message.setColor(Message.COLOR_RED);
|
||||
message.setIcon(R.drawable.error);
|
||||
server.getConversation(ServerInfo.DEFAULT_NAME).addMessage(message);
|
||||
|
||||
Intent cIntent = Broadcast.createConversationIntent(
|
||||
Broadcast.CONVERSATION_MESSAGE,
|
||||
serverId,
|
||||
ServerInfo.DEFAULT_NAME
|
||||
);
|
||||
sendBroadcast(cIntent);
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get connection for given server
|
||||
*
|
||||
* @param serverId
|
||||
* @return
|
||||
*/
|
||||
public synchronized IRCConnection getConnection(int serverId)
|
||||
{
|
||||
IRCConnection connection = connections.get(serverId);
|
||||
|
||||
if (connection == null) {
|
||||
connection = new IRCConnection(this, serverId);
|
||||
connections.put(serverId, connection);
|
||||
}
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the service keep a connection object for this server?
|
||||
*
|
||||
* @return true if there's a connection object, false otherwise
|
||||
*/
|
||||
public boolean hasConnection(int serverId)
|
||||
{
|
||||
return connections.containsKey(serverId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check status of service
|
||||
*/
|
||||
public void checkServiceStatus()
|
||||
{
|
||||
boolean shutDown = true;
|
||||
ArrayList<Server> mServers = Yaaic.getInstance().getServersAsArrayList();
|
||||
int mSize = mServers.size();
|
||||
Server server;
|
||||
|
||||
for (int i = 0; i < mSize; i++) {
|
||||
server = mServers.get(i);
|
||||
if (server.isDisconnected() && !server.mayReconnect()) {
|
||||
int serverId = server.getId();
|
||||
synchronized(this) {
|
||||
IRCConnection connection = connections.get(serverId);
|
||||
if (connection != null) {
|
||||
connection.dispose();
|
||||
}
|
||||
connections.remove(serverId);
|
||||
}
|
||||
|
||||
synchronized(alarmIntentsLock) {
|
||||
// XXX: alarmIntents can be null
|
||||
PendingIntent pendingRIntent = alarmIntents.get(serverId);
|
||||
if (pendingRIntent != null) {
|
||||
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
|
||||
am.cancel(pendingRIntent);
|
||||
alarmIntents.remove(serverId);
|
||||
}
|
||||
ReconnectReceiver receiver = alarmReceivers.get(serverId);
|
||||
if (receiver != null) {
|
||||
unregisterReceiver(receiver);
|
||||
alarmReceivers.remove(serverId);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
shutDown = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (shutDown) {
|
||||
foreground = false;
|
||||
stopForegroundCompat(R.string.app_name);
|
||||
stopSelf();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On Destroy
|
||||
*/
|
||||
@Override
|
||||
public void onDestroy()
|
||||
{
|
||||
// Make sure our notification is gone.
|
||||
if (foreground) {
|
||||
stopForegroundCompat(R.string.app_name);
|
||||
}
|
||||
|
||||
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
|
||||
synchronized(alarmIntentsLock) {
|
||||
for (PendingIntent pendingRIntent : alarmIntents.values()) {
|
||||
am.cancel(pendingRIntent);
|
||||
}
|
||||
for (ReconnectReceiver receiver : alarmReceivers.values()) {
|
||||
unregisterReceiver(receiver);
|
||||
}
|
||||
alarmIntents.clear();
|
||||
alarmIntents = null;
|
||||
alarmReceivers.clear();
|
||||
alarmReceivers = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On Activity binding to this service
|
||||
*
|
||||
* @param intent
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public IRCBinder onBind(Intent intent)
|
||||
{
|
||||
return binder;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2010 Sebastian Kaspari
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
|
@ -17,29 +17,41 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.activity;
|
||||
|
||||
import org.yaaic.R;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceActivity;
|
||||
*/
|
||||
package org.yaaic.listener;
|
||||
|
||||
/**
|
||||
* Settings
|
||||
* Listener for conversations
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class SettingsActivity extends PreferenceActivity
|
||||
public interface ConversationListener
|
||||
{
|
||||
/**
|
||||
* On create
|
||||
*/
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
addPreferencesFromResource(R.xml.preferences);
|
||||
}
|
||||
/**
|
||||
* On new conversation message for given target
|
||||
*
|
||||
* @param target
|
||||
*/
|
||||
public void onConversationMessage(String target);
|
||||
|
||||
/**
|
||||
* On new conversation created (for given target)
|
||||
*
|
||||
* @param target
|
||||
*/
|
||||
public void onNewConversation(String target);
|
||||
|
||||
/**
|
||||
* On conversation removed (for given target)
|
||||
*
|
||||
* @param target
|
||||
*/
|
||||
public void onRemoveConversation(String target);
|
||||
|
||||
/**
|
||||
* On topic changed (for given target)
|
||||
*
|
||||
* @param target
|
||||
*/
|
||||
public void onTopicChanged(String target);
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.listener;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.support.v4.view.ViewPager.OnPageChangeListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.yaaic.adapter.ConversationPagerAdapter;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.model.Channel;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
/**
|
||||
* Listener for conversation selections.
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class ConversationSelectedListener implements OnPageChangeListener
|
||||
{
|
||||
private final Context context;
|
||||
private final Server server;
|
||||
private final TextView titleView;
|
||||
private final ConversationPagerAdapter adapter;
|
||||
|
||||
/**
|
||||
* Create a new ConversationSelectedListener
|
||||
*
|
||||
* @param server
|
||||
* @param titleView
|
||||
*/
|
||||
public ConversationSelectedListener(Context ctx, Server server, TextView titleView, ConversationPagerAdapter adapter)
|
||||
{
|
||||
this.context = ctx;
|
||||
this.server = server;
|
||||
this.titleView = titleView;
|
||||
this.adapter = adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* On page has been selected.
|
||||
*/
|
||||
@Override
|
||||
public void onPageSelected(int position)
|
||||
{
|
||||
Conversation conversation = adapter.getItem(position);
|
||||
|
||||
if (conversation != null && conversation.getType() != Conversation.TYPE_SERVER) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(server.getTitle() + " - " + conversation.getName());
|
||||
if (conversation.getType() == Conversation.TYPE_CHANNEL && !((Channel)conversation).getTopic().equals("")) {
|
||||
sb.append(" - " + ((Channel)conversation).getTopic());
|
||||
}
|
||||
titleView.setText(sb.toString());
|
||||
} else {
|
||||
titleView.setText(server.getTitle());
|
||||
}
|
||||
|
||||
// Remember selection
|
||||
if (conversation != null) {
|
||||
Conversation previousConversation = server.getConversation(server.getSelectedConversation());
|
||||
|
||||
if (previousConversation != null) {
|
||||
previousConversation.setStatus(Conversation.STATUS_DEFAULT);
|
||||
}
|
||||
|
||||
if (conversation.getNewMentions() > 0) {
|
||||
Intent i = new Intent(context, IRCService.class);
|
||||
i.setAction(IRCService.ACTION_ACK_NEW_MENTIONS);
|
||||
i.putExtra(IRCService.EXTRA_ACK_SERVERID, server.getId());
|
||||
i.putExtra(IRCService.EXTRA_ACK_CONVTITLE, conversation.getName());
|
||||
context.startService(i);
|
||||
}
|
||||
|
||||
conversation.setStatus(Conversation.STATUS_SELECTED);
|
||||
server.setSelectedConversation(conversation.getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On scroll state of pager has been chanaged.
|
||||
*/
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int state)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* On page has been scrolled.
|
||||
*/
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2010 Sebastian Kaspari
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
|
@ -17,7 +17,7 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
package org.yaaic.listener;
|
||||
|
||||
import org.yaaic.activity.MessageActivity;
|
||||
|
@ -36,38 +36,39 @@ import android.widget.AdapterView.OnItemClickListener;
|
|||
*/
|
||||
public class MessageClickListener implements OnItemClickListener
|
||||
{
|
||||
private static MessageClickListener instance;
|
||||
|
||||
/**
|
||||
* Private constructor
|
||||
*/
|
||||
private MessageClickListener()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Get global instance of message click listener
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static synchronized MessageClickListener getInstance()
|
||||
{
|
||||
if (instance == null) {
|
||||
instance = new MessageClickListener();
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* On message item clicked
|
||||
*/
|
||||
public void onItemClick(AdapterView<?> group, View view, int position, long id)
|
||||
{
|
||||
MessageListAdapter adapter = (MessageListAdapter) group.getAdapter();
|
||||
|
||||
Intent intent = new Intent(group.getContext(), MessageActivity.class);
|
||||
intent.putExtra(Extra.MESSAGE, adapter.getItem(position).getText().toString());
|
||||
group.getContext().startActivity(intent);
|
||||
}
|
||||
private static MessageClickListener instance;
|
||||
|
||||
/**
|
||||
* Private constructor
|
||||
*/
|
||||
private MessageClickListener()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Get global instance of message click listener
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static synchronized MessageClickListener getInstance()
|
||||
{
|
||||
if (instance == null) {
|
||||
instance = new MessageClickListener();
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* On message item clicked
|
||||
*/
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> group, View view, int position, long id)
|
||||
{
|
||||
MessageListAdapter adapter = (MessageListAdapter) group.getAdapter();
|
||||
|
||||
Intent intent = new Intent(group.getContext(), MessageActivity.class);
|
||||
intent.putExtra(Extra.MESSAGE, adapter.getItem(position).getText().toString());
|
||||
group.getContext().startActivity(intent);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2010 Sebastian Kaspari
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
|
@ -17,10 +17,18 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
package org.yaaic.listener;
|
||||
|
||||
/**
|
||||
* Listener for changes regarding a server
|
||||
*
|
||||
* @author Sebastian Kaspari
|
||||
*/
|
||||
public interface ServerListener
|
||||
{
|
||||
public void onStatusUpdate();
|
||||
/**
|
||||
* On server status update (disconnected, connecting, connected)
|
||||
*/
|
||||
public void onStatusUpdate();
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.menu;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.PopupMenu;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.adapter.ServersAdapter;
|
||||
import org.yaaic.model.Server;
|
||||
|
||||
/**
|
||||
* Popup menu for the server cards.
|
||||
*/
|
||||
public class ServerPopupMenu extends PopupMenu implements PopupMenu.OnMenuItemClickListener, View.OnClickListener {
|
||||
private Server server;
|
||||
private ServersAdapter.ClickListener listener;
|
||||
|
||||
public ServerPopupMenu(Context context, View anchor, ServersAdapter.ClickListener listener) {
|
||||
super(context, anchor);
|
||||
|
||||
this.listener = listener;
|
||||
|
||||
getMenuInflater().inflate(R.menu.context_server, getMenu());
|
||||
setOnMenuItemClickListener(this);
|
||||
|
||||
anchor.setOnClickListener(this);
|
||||
}
|
||||
|
||||
public void updateServer(Server server) {
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
int id = item.getItemId();
|
||||
|
||||
switch (id) {
|
||||
case R.id.edit:
|
||||
listener.onEditServer(server);
|
||||
break;
|
||||
case R.id.delete:
|
||||
listener.onDeleteServer(server);
|
||||
break;
|
||||
case R.id.connect:
|
||||
listener.onConnectToServer(server);
|
||||
break;
|
||||
case R.id.disconnect:
|
||||
listener.onDisconnectFromServer(server);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void onClick(View v) {
|
||||
show();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.model;
|
||||
|
||||
/**
|
||||
* Authentication credentials for a server.
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class Authentication
|
||||
{
|
||||
private String saslUsername;
|
||||
private String saslPassword;
|
||||
private String nickservPassword;
|
||||
|
||||
/**
|
||||
* Does this instance have credentials for Nickserv authentication?
|
||||
*
|
||||
* @return True if nickserv credentials are present, false otherwise.
|
||||
*/
|
||||
public boolean hasNickservCredentials()
|
||||
{
|
||||
return nickservPassword != null && nickservPassword.length() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this instance have credentials for SASL authentication?
|
||||
*
|
||||
* @return True if nickserv credentials are present, false otherwise.
|
||||
*/
|
||||
public boolean hasSaslCredentials()
|
||||
{
|
||||
return saslUsername != null && saslUsername.length() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the username for SASL authentication.
|
||||
*
|
||||
* @param saslUsername
|
||||
*/
|
||||
public void setSaslUsername(String saslUsername)
|
||||
{
|
||||
if (saslUsername == "") {
|
||||
saslUsername = null;
|
||||
}
|
||||
|
||||
this.saslUsername = saslUsername;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the password for SASL authentication.
|
||||
*
|
||||
* @param saslPassword
|
||||
*/
|
||||
public void setSaslPassword(String saslPassword)
|
||||
{
|
||||
if (saslPassword == "") {
|
||||
saslPassword = null;
|
||||
}
|
||||
|
||||
this.saslPassword = saslPassword;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the password for Nickserv authentication.
|
||||
*
|
||||
* @param nickservPassword
|
||||
*/
|
||||
public void setNickservPassword(String nickservPassword)
|
||||
{
|
||||
if (nickservPassword == "") {
|
||||
nickservPassword = null;
|
||||
}
|
||||
|
||||
this.nickservPassword = nickservPassword;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the username for SASL authentication.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getSaslUsername()
|
||||
{
|
||||
return saslUsername;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the password for SASL authentication.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getSaslPassword()
|
||||
{
|
||||
return saslPassword;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the password for Nickserv authentication.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getNickservPassword()
|
||||
{
|
||||
return nickservPassword;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.model;
|
||||
|
||||
import android.content.Intent;
|
||||
|
||||
/**
|
||||
* Constants and helpers for Broadcasts
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public abstract class Broadcast
|
||||
{
|
||||
public static final String SERVER_UPDATE = "org.yaaic.server.status";
|
||||
public static final String SERVER_RECONNECT = "org.yaaic.server.reconnect.";
|
||||
|
||||
public static final String CONVERSATION_MESSAGE = "org.yaaic.conversation.message";
|
||||
public static final String CONVERSATION_NEW = "org.yaaic.conversation.new";
|
||||
public static final String CONVERSATION_REMOVE = "org.yaaic.conversation.remove";
|
||||
public static final String CONVERSATION_TOPIC = "org.yaaic.conversation.topic";
|
||||
|
||||
/**
|
||||
* Create an Intent for conversation broadcasting
|
||||
*
|
||||
* @param broadcastType The type of the broadcast, some constant of Broadcast.*
|
||||
* @param serverId The id of the server
|
||||
* @param conversationName The unique name of the conversation
|
||||
* @return The created Intent
|
||||
*/
|
||||
public static Intent createConversationIntent(String broadcastType, int serverId, String conversationName)
|
||||
{
|
||||
Intent intent = new Intent(broadcastType);
|
||||
|
||||
intent.putExtra(Extra.SERVER, serverId);
|
||||
intent.putExtra(Extra.CONVERSATION, conversationName);
|
||||
|
||||
return intent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an Intent for server broadcasting
|
||||
*
|
||||
* @param broadcastType The typo of the broadcast, some constant of Broadcast.*
|
||||
* @param serverId The id of the server
|
||||
* @return The created Intent
|
||||
*/
|
||||
public static Intent createServerIntent(String broadcastType, int serverId)
|
||||
{
|
||||
Intent intent = new Intent(broadcastType);
|
||||
|
||||
intent.putExtra(Extra.SERVER, serverId);
|
||||
|
||||
return intent;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2010 Sebastian Kaspari
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
|
@ -17,7 +17,7 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
package org.yaaic.model;
|
||||
|
||||
/**
|
||||
|
@ -27,45 +27,45 @@ package org.yaaic.model;
|
|||
*/
|
||||
public class Channel extends Conversation
|
||||
{
|
||||
private String topic;
|
||||
private String topic;
|
||||
|
||||
/**
|
||||
* Create a new channel object
|
||||
*
|
||||
* @param name of the channel
|
||||
*/
|
||||
public Channel(String name)
|
||||
{
|
||||
super(name);
|
||||
this.topic = "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of this conversation
|
||||
*/
|
||||
@Override
|
||||
public int getType()
|
||||
{
|
||||
return Conversation.TYPE_CHANNEL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the channel's topic
|
||||
*
|
||||
* @param topic The topic of the channel
|
||||
*/
|
||||
public void setTopic(String topic)
|
||||
{
|
||||
this.topic = topic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the topic of the channel
|
||||
*
|
||||
* @return The channel's topic
|
||||
*/
|
||||
public String getTopic()
|
||||
{
|
||||
return topic;
|
||||
}
|
||||
/**
|
||||
* Create a new channel object
|
||||
*
|
||||
* @param name of the channel
|
||||
*/
|
||||
public Channel(String name)
|
||||
{
|
||||
super(name);
|
||||
this.topic = "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of this conversation
|
||||
*/
|
||||
@Override
|
||||
public int getType()
|
||||
{
|
||||
return Conversation.TYPE_CHANNEL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the channel's topic
|
||||
*
|
||||
* @param topic The topic of the channel
|
||||
*/
|
||||
public void setTopic(String topic)
|
||||
{
|
||||
this.topic = topic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the topic of the channel
|
||||
*
|
||||
* @return The channel's topic
|
||||
*/
|
||||
public String getTopic()
|
||||
{
|
||||
return topic;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,235 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.model;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* Base class for conversations
|
||||
*
|
||||
* A conversation can be a channel, a query or server messages
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public abstract class Conversation
|
||||
{
|
||||
public static final int TYPE_CHANNEL = 1;
|
||||
public static final int TYPE_QUERY = 2;
|
||||
public static final int TYPE_SERVER = 3;
|
||||
|
||||
public static final int STATUS_DEFAULT = 1;
|
||||
public static final int STATUS_SELECTED = 2;
|
||||
public static final int STATUS_MESSAGE = 3;
|
||||
public static final int STATUS_HIGHLIGHT = 4;
|
||||
public static final int STATUS_MISC = 5; // join/part/quit
|
||||
|
||||
private static final int DEFAULT_HISTORY_SIZE = 30;
|
||||
|
||||
private final LinkedList<Message> buffer;
|
||||
private final LinkedList<Message> history;
|
||||
private final String name;
|
||||
private int status = 1;
|
||||
private int newMentions = 0;
|
||||
private int historySize = DEFAULT_HISTORY_SIZE;
|
||||
|
||||
/**
|
||||
* Get the type of conversation (channel, query, ..)
|
||||
*
|
||||
* @return See the constants: Conversation.TYPE_*
|
||||
*/
|
||||
public abstract int getType();
|
||||
|
||||
/**
|
||||
* Create a new conversation with the given name
|
||||
*
|
||||
* @param name The name of the conversation (channel, user)
|
||||
*/
|
||||
public Conversation(String name)
|
||||
{
|
||||
this.buffer = new LinkedList<Message>();
|
||||
this.history = new LinkedList<Message>();
|
||||
this.name = name.toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name of the conversation (channel, user)
|
||||
*/
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a message to the channel
|
||||
*/
|
||||
public void addMessage(Message message)
|
||||
{
|
||||
buffer.add(0, message);
|
||||
history.add(message);
|
||||
|
||||
if (history.size() > historySize) {
|
||||
history.remove(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the history
|
||||
*/
|
||||
public LinkedList<Message> getHistory()
|
||||
{
|
||||
return history;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get message of the history at the given position
|
||||
*
|
||||
* @param position
|
||||
* @return The message at the given position
|
||||
*/
|
||||
public Message getHistoryMessage(int position)
|
||||
{
|
||||
return history.get(position);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last buffered message
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Message pollBufferedMessage()
|
||||
{
|
||||
Message message = buffer.get(buffer.size() - 1);
|
||||
buffer.remove(buffer.size() - 1);
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the buffer
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public LinkedList<Message> getBuffer()
|
||||
{
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the channel have buffered messages?
|
||||
*/
|
||||
public boolean hasBufferedMessages()
|
||||
{
|
||||
return buffer.size() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the message buffer
|
||||
*/
|
||||
public void clearBuffer()
|
||||
{
|
||||
buffer.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set status of conversation
|
||||
*
|
||||
* @param status
|
||||
*/
|
||||
public void setStatus(int status)
|
||||
{
|
||||
// Selected status can only be changed by deselecting
|
||||
if (this.status == STATUS_SELECTED && status != STATUS_DEFAULT) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Highlight status can only be changed by selecting
|
||||
if (this.status == STATUS_HIGHLIGHT && status != STATUS_SELECTED) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Misc cannot change any other than default
|
||||
if (this.status != STATUS_DEFAULT && status == STATUS_MISC) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get status of conversation
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getStatus()
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the count of unread mentions in this conversation
|
||||
*/
|
||||
public void addNewMention()
|
||||
{
|
||||
++newMentions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark all new mentions as unread
|
||||
*/
|
||||
public void clearNewMentions()
|
||||
{
|
||||
newMentions = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of unread mentions in this conversation
|
||||
*/
|
||||
public int getNewMentions()
|
||||
{
|
||||
return newMentions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get this conversation's history size.
|
||||
*
|
||||
* @return The conversation's history size.
|
||||
*/
|
||||
public int getHistorySize()
|
||||
{
|
||||
return historySize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this conversation's history size.
|
||||
*
|
||||
* @param size The new history size for this conversation.
|
||||
*/
|
||||
public void setHistorySize(int size)
|
||||
{
|
||||
if (size <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
historySize = size;
|
||||
if (history.size() > size) {
|
||||
history.subList(size, history.size()).clear();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.model;
|
||||
|
||||
/**
|
||||
* Helper class for constants used for bundle params (extras)
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class Extra
|
||||
{
|
||||
public static final String SERVER = "server";
|
||||
public static final String CONVERSATION = "conversation";
|
||||
public static final String USERS = "users";
|
||||
|
||||
public static final String ALIASES = "aliases";
|
||||
public static final String CHANNELS = "channels";
|
||||
public static final String COMMANDS = "commands";
|
||||
public static final String MESSAGE = "message";
|
||||
public static final String USER = "user";
|
||||
public static final String ACTION = "action";
|
||||
|
||||
public static final String NICKSERV_PASSWORD = "nickserv_password";
|
||||
public static final String SASL_USER = "sasl_user";
|
||||
public static final String SASL_PASSWORD = "sasl_password";
|
||||
|
||||
public static final String CONNECT = "connect";
|
||||
public static final String SERVER_ID = "serverId";
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An identity containing a nickname, an ident and a real name
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class Identity
|
||||
{
|
||||
private String nickname;
|
||||
private final List<String> aliases = new ArrayList<String>();
|
||||
private String ident;
|
||||
private String realname;
|
||||
|
||||
/**
|
||||
* Set the nickname of this identity
|
||||
*
|
||||
* @param nickname The nickname to be set
|
||||
*/
|
||||
public void setNickname(String nickname)
|
||||
{
|
||||
this.nickname = nickname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the nickname of this identity
|
||||
*
|
||||
* @return The nickname
|
||||
*/
|
||||
public String getNickname()
|
||||
{
|
||||
return nickname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a collection of aliases for this identity
|
||||
*
|
||||
* @param aliases
|
||||
*/
|
||||
public void setAliases(Collection<String> aliases)
|
||||
{
|
||||
this.aliases.clear();
|
||||
this.aliases.addAll(aliases);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all aliases for this identity
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<String> getAliases()
|
||||
{
|
||||
return Collections.unmodifiableList(aliases);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ident of this identity
|
||||
*
|
||||
* @param ident The ident to be set
|
||||
*/
|
||||
public void setIdent(String ident)
|
||||
{
|
||||
this.ident = ident;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ident of this identity
|
||||
*
|
||||
* @return The identity
|
||||
*/
|
||||
public String getIdent()
|
||||
{
|
||||
return ident;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the real name of this identity
|
||||
*
|
||||
* @param realname The real name to be set
|
||||
*/
|
||||
public void setRealName(String realname)
|
||||
{
|
||||
this.realname = realname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the real name of this identity
|
||||
*
|
||||
* @return The realname
|
||||
*/
|
||||
public String getRealName()
|
||||
{
|
||||
return realname;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,378 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.model;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.yaaic.utils.MircColors;
|
||||
import org.yaaic.utils.Smilies;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.TextUtils;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.text.style.ImageSpan;
|
||||
import android.text.util.Linkify;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* A channel or server message
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class Message
|
||||
{
|
||||
public static final int COLOR_GREEN = 0xFF458509;
|
||||
public static final int COLOR_RED = 0xFFcc0000;
|
||||
public static final int COLOR_BLUE = 0xFF729fcf;
|
||||
public static final int COLOR_YELLOW = 0xFFbe9b01;
|
||||
public static final int COLOR_GREY = 0xFFaaaaaa;
|
||||
public static final int COLOR_DEFAULT = 0xFFeeeeee;
|
||||
|
||||
/* normal message, this is the default */
|
||||
public static final int TYPE_MESSAGE = 0;
|
||||
|
||||
/* join, part or quit */
|
||||
public static final int TYPE_MISC = 1;
|
||||
|
||||
/* Some are light versions because dark colors hardly readable on
|
||||
* Yaaic's dark background */
|
||||
public static final int[] colors = {
|
||||
0xFFffffff, // White
|
||||
0xFFffff00, // Yellow
|
||||
0xFFff00ff, // Fuchsia
|
||||
0xFFff0000, // Red
|
||||
0xFFc0c0c0, // Silver
|
||||
0xFF808080, // Gray
|
||||
0xFF808000, // Olive
|
||||
0xFFC040C0, // Light Purple
|
||||
0xFFC04040, // Light Maroon
|
||||
0xFF00ffff, // Agua
|
||||
0xFF80ff80, // Light Lime
|
||||
0xFF008080, // Teal
|
||||
0xFF008000, // Green
|
||||
0xFF8484FF, // Light Blue
|
||||
0xFF6060D0, // Light Navy
|
||||
0xFF000000, // Black
|
||||
};
|
||||
|
||||
public static final int NO_ICON = -1;
|
||||
public static final int NO_TYPE = -1;
|
||||
public static final int NO_COLOR = -1;
|
||||
|
||||
private final String text;
|
||||
private final String sender;
|
||||
private SpannableString canvas;
|
||||
private long timestamp;
|
||||
|
||||
private int color = NO_COLOR;
|
||||
private int type = NO_ICON;
|
||||
private int icon = NO_TYPE;
|
||||
|
||||
/**
|
||||
* Create a new message without an icon defaulting to TYPE_MESSAGE
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
public Message(String text)
|
||||
{
|
||||
this(text, null, TYPE_MESSAGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new message without an icon with a specific type
|
||||
*
|
||||
* @param text
|
||||
* @param type Message type
|
||||
*/
|
||||
public Message(String text, int type)
|
||||
{
|
||||
this(text, null, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new message sent by a user, without an icon,
|
||||
* defaulting to TYPE_MESSAGE
|
||||
*
|
||||
* @param text
|
||||
* @param sender
|
||||
*/
|
||||
public Message(String text, String sender)
|
||||
{
|
||||
this(text, sender, TYPE_MESSAGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new message sent by a user without an icon
|
||||
*
|
||||
* @param text
|
||||
* @param sender
|
||||
* @param type Message type
|
||||
*/
|
||||
public Message(String text, String sender, int type)
|
||||
{
|
||||
this.text = text;
|
||||
this.sender = sender;
|
||||
this.timestamp = new Date().getTime();
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the message's icon
|
||||
*/
|
||||
public void setIcon(int icon)
|
||||
{
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message's icon
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getIcon()
|
||||
{
|
||||
return icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text of this message
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getText()
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of this message
|
||||
*
|
||||
* @return One of Message.TYPE_*
|
||||
*/
|
||||
public int getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the color of this message
|
||||
*/
|
||||
public void setColor(int color)
|
||||
{
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the timestamp of the message
|
||||
*
|
||||
* @param timestamp
|
||||
*/
|
||||
public void setTimestamp(long timestamp)
|
||||
{
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate a color with a sender name
|
||||
*
|
||||
* @return a color hexa
|
||||
*/
|
||||
private int getSenderColor()
|
||||
{
|
||||
/* It might be worth to use some hash table here */
|
||||
if (sender == null) {
|
||||
return COLOR_DEFAULT;
|
||||
}
|
||||
|
||||
int color = 0;
|
||||
|
||||
for(int i = 0; i < sender.length(); i++){
|
||||
color += sender.charAt(i);
|
||||
}
|
||||
|
||||
/* we dont want color[colors.length-1] which is black */
|
||||
color = color % (colors.length - 1);
|
||||
|
||||
return colors[color];
|
||||
}
|
||||
|
||||
/**
|
||||
* Render message as spannable string
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public SpannableString render(Context context)
|
||||
{
|
||||
Settings settings = new Settings(context);
|
||||
|
||||
if (canvas == null) {
|
||||
String prefix = hasIcon() && settings.showIcons() ? " " : "";
|
||||
String nick = hasSender() ? "<" + sender + "> " : "";
|
||||
String timestamp = settings.showTimestamp() ? renderTimeStamp(settings.use24hFormat(), settings.includeSeconds()) : "";
|
||||
|
||||
canvas = new SpannableString(prefix + timestamp + nick);
|
||||
SpannableString renderedText;
|
||||
|
||||
if (settings.showMircColors()) {
|
||||
renderedText = MircColors.toSpannable(text);
|
||||
} else {
|
||||
renderedText = new SpannableString(
|
||||
MircColors.removeStyleAndColors(text)
|
||||
);
|
||||
}
|
||||
|
||||
if (settings.showGraphicalSmilies()) {
|
||||
renderedText = Smilies.toSpannable(renderedText, context);
|
||||
}
|
||||
|
||||
canvas = new SpannableString(TextUtils.concat(canvas, renderedText));
|
||||
|
||||
if (hasSender()) {
|
||||
int start = (prefix + timestamp).length() + 1;
|
||||
int end = start + sender.length();
|
||||
|
||||
if (settings.showColorsNick()) {
|
||||
canvas.setSpan(new ForegroundColorSpan(getSenderColor()), start, end , Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
}
|
||||
|
||||
if (hasIcon() && settings.showIcons()) {
|
||||
Drawable drawable = context.getResources().getDrawable(icon);
|
||||
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
|
||||
canvas.setSpan(new ImageSpan(drawable, ImageSpan.ALIGN_BOTTOM), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
|
||||
if (hasColor() && settings.showColors()) {
|
||||
// Only apply the foreground color to areas that don't already have a foreground color.
|
||||
ForegroundColorSpan[] spans = canvas.getSpans(0, canvas.length(), ForegroundColorSpan.class);
|
||||
int start = 0;
|
||||
|
||||
for (int i = 0; i < spans.length; i++) {
|
||||
canvas.setSpan(new ForegroundColorSpan(color), start, canvas.getSpanStart(spans[i]), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
start = canvas.getSpanEnd(spans[i]);
|
||||
}
|
||||
|
||||
canvas.setSpan(new ForegroundColorSpan(color), start, canvas.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
}
|
||||
|
||||
return canvas;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this message have a sender?
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private boolean hasSender()
|
||||
{
|
||||
return sender != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this message have a color assigned?
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private boolean hasColor()
|
||||
{
|
||||
return color != NO_COLOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this message have an icon assigned?
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private boolean hasIcon()
|
||||
{
|
||||
return icon != NO_ICON;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render message as text view
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
public TextView renderTextView(Context context)
|
||||
{
|
||||
TextView canvas = new TextView(context);
|
||||
|
||||
canvas.setAutoLinkMask(Linkify.ALL);
|
||||
canvas.setLinksClickable(true);
|
||||
canvas.setLinkTextColor(COLOR_BLUE);
|
||||
|
||||
canvas.setText(this.render(context));
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
setupViewForHoneycombAndLater(canvas);
|
||||
}
|
||||
|
||||
return canvas;
|
||||
}
|
||||
|
||||
@TargetApi(11)
|
||||
private void setupViewForHoneycombAndLater(TextView canvas) {
|
||||
canvas.setTextIsSelectable(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a timestamp
|
||||
*
|
||||
* @param use24hFormat
|
||||
* @return
|
||||
*/
|
||||
public String renderTimeStamp(boolean use24hFormat, boolean includeSeconds)
|
||||
{
|
||||
Date date = new Date(timestamp);
|
||||
|
||||
int hours = date.getHours();
|
||||
int minutes = date.getMinutes();
|
||||
int seconds = date.getSeconds();
|
||||
|
||||
if (!use24hFormat) {
|
||||
hours = Math.abs(12 - hours);
|
||||
if (hours == 12) {
|
||||
hours = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (includeSeconds) {
|
||||
return String.format(
|
||||
"[%02d:%02d:%02d]",
|
||||
hours,
|
||||
minutes,
|
||||
seconds);
|
||||
} else {
|
||||
return String.format(
|
||||
"[%02d:%02d]",
|
||||
hours,
|
||||
minutes);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2010 Sebastian Kaspari
|
||||
Copyright 2009-2013 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
|
@ -17,7 +17,7 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
package org.yaaic.model;
|
||||
|
||||
/**
|
||||
|
@ -27,21 +27,22 @@ package org.yaaic.model;
|
|||
*/
|
||||
public class Query extends Conversation
|
||||
{
|
||||
/**
|
||||
* Create a new query
|
||||
*
|
||||
* @param name The user's nickname
|
||||
*/
|
||||
public Query(String name)
|
||||
{
|
||||
super(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of this conversation
|
||||
*/
|
||||
public int getType()
|
||||
{
|
||||
return Conversation.TYPE_QUERY;
|
||||
}
|
||||
/**
|
||||
* Create a new query
|
||||
*
|
||||
* @param name The user's nickname
|
||||
*/
|
||||
public Query(String name)
|
||||
{
|
||||
super(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of this conversation
|
||||
*/
|
||||
@Override
|
||||
public int getType()
|
||||
{
|
||||
return Conversation.TYPE_QUERY;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue