ASCII emoji support

Fixes #2943
Closes #3283
// FREEBIE
This commit is contained in:
Jake McGinty 2015-05-21 17:29:23 -07:00 committed by Moxie Marlinspike
parent 0cf9206170
commit 9408579862
16 changed files with 341 additions and 991 deletions

View File

Before

Width:  |  Height:  |  Size: 332 KiB

After

Width:  |  Height:  |  Size: 332 KiB

View File

Before

Width:  |  Height:  |  Size: 283 KiB

After

Width:  |  Height:  |  Size: 283 KiB

View File

Before

Width:  |  Height:  |  Size: 227 KiB

After

Width:  |  Height:  |  Size: 227 KiB

View File

Before

Width:  |  Height:  |  Size: 177 KiB

After

Width:  |  Height:  |  Size: 177 KiB

View File

Before

Width:  |  Height:  |  Size: 206 KiB

After

Width:  |  Height:  |  Size: 206 KiB

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:enterFadeDuration="200"
android:exitFadeDuration="300">
<item android:state_selected="true" android:drawable="@drawable/ic_emoji_emoticons_activated_light" />
<item android:drawable="@drawable/ic_emoji_emoticons_normal_light" />
</selector>

View File

@ -1,890 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer-array name="emoji_nature">
<item>0x1f415</item>
<item>0x1f436</item>
<item>0x1f429</item>
<item>0x1f408</item>
<item>0x1f431</item>
<item>0x1f400</item>
<item>0x1f401</item>
<item>0x1f42d</item>
<item>0x1f439</item>
<item>0x1f422</item>
<item>0x1f407</item>
<item>0x1f430</item>
<item>0x1f413</item>
<item>0x1f414</item>
<item>0x1f423</item>
<item>0x1f424</item>
<item>0x1f425</item>
<item>0x1f426</item>
<item>0x1f40f</item>
<item>0x1f411</item>
<item>0x1f410</item>
<item>0x1f43a</item>
<item>0x1f403</item>
<item>0x1f402</item>
<item>0x1f404</item>
<item>0x1f42e</item>
<item>0x1f434</item>
<item>0x1f417</item>
<item>0x1f416</item>
<item>0x1f437</item>
<item>0x1f43d</item>
<item>0x1f438</item>
<item>0x1f40d</item>
<item>0x1f43c</item>
<item>0x1f427</item>
<item>0x1f418</item>
<item>0x1f428</item>
<item>0x1f412</item>
<item>0x1f435</item>
<item>0x1f406</item>
<item>0x1f42f</item>
<item>0x1f43b</item>
<item>0x1f42b</item>
<item>0x1f42a</item>
<item>0x1f40a</item>
<item>0x1f433</item>
<item>0x1f40b</item>
<item>0x1f41f</item>
<item>0x1f420</item>
<item>0x1f421</item>
<item>0x1f419</item>
<item>0x1f41a</item>
<item>0x1f42c</item>
<item>0x1f40c</item>
<item>0x1f41b</item>
<item>0x1f41c</item>
<item>0x1f41d</item>
<item>0x1f41e</item>
<item>0x1f432</item>
<item>0x1f409</item>
<item>0x1f43e</item>
<item>0x1f378</item>
<item>0x1f37a</item>
<item>0x1f37b</item>
<item>0x1f377</item>
<item>0x1f379</item>
<item>0x1f376</item>
<item>0x2615</item>
<item>0x1f375</item>
<item>0x1f37c</item>
<item>0x1f374</item>
<item>0x1f368</item>
<item>0x1f367</item>
<item>0x1f366</item>
<item>0x1f369</item>
<item>0x1f370</item>
<item>0x1f36a</item>
<item>0x1f36b</item>
<item>0x1f36c</item>
<item>0x1f36d</item>
<item>0x1f36e</item>
<item>0x1f36f</item>
<item>0x1f373</item>
<item>0x1f354</item>
<item>0x1f35f</item>
<item>0x1f35d</item>
<item>0x1f355</item>
<item>0x1f356</item>
<item>0x1f357</item>
<item>0x1f364</item>
<item>0x1f363</item>
<item>0x1f371</item>
<item>0x1f35e</item>
<item>0x1f35c</item>
<item>0x1f359</item>
<item>0x1f35a</item>
<item>0x1f35b</item>
<item>0x1f372</item>
<item>0x1f365</item>
<item>0x1f362</item>
<item>0x1f361</item>
<item>0x1f358</item>
<item>0x1f360</item>
<item>0x1f34c</item>
<item>0x1f34e</item>
<item>0x1f34f</item>
<item>0x1f34a</item>
<item>0x1f34b</item>
<item>0x1f344</item>
<item>0x1f345</item>
<item>0x1f346</item>
<item>0x1f347</item>
<item>0x1f348</item>
<item>0x1f349</item>
<item>0x1f350</item>
<item>0x1f351</item>
<item>0x1f352</item>
<item>0x1f353</item>
<item>0x1f34d</item>
<item>0x1f330</item>
<item>0x1f331</item>
<item>0x1f332</item>
<item>0x1f333</item>
<item>0x1f334</item>
<item>0x1f335</item>
<item>0x1f337</item>
<item>0x1f338</item>
<item>0x1f339</item>
<item>0x1f340</item>
<item>0x1f341</item>
<item>0x1f342</item>
<item>0x1f343</item>
<item>0x1f33a</item>
<item>0x1f33b</item>
<item>0x1f33c</item>
<item>0x1f33d</item>
<item>0x1f33e</item>
<item>0x1f33f</item>
<item>0x2600</item>
<item>0x1f308</item>
<item>0x26c5</item>
<item>0x2601</item>
<item>0x1f301</item>
<item>0x1f302</item>
<item>0x2614</item>
<item>0x1f4a7</item>
<item>0x26a1</item>
<item>0x1f300</item>
<item>0x2744</item>
<item>0x26c4</item>
<item>0x1f319</item>
<item>0x1f31e</item>
<item>0x1f31d</item>
<item>0x1f31a</item>
<item>0x1f31b</item>
<item>0x1f31c</item>
<item>0x1f311</item>
<item>0x1f312</item>
<item>0x1f313</item>
<item>0x1f314</item>
<item>0x1f315</item>
<item>0x1f316</item>
<item>0x1f317</item>
<item>0x1f318</item>
<item>0x1f391</item>
<item>0x1f304</item>
<item>0x1f305</item>
<item>0x1f307</item>
<item>0x1f306</item>
<item>0x1f303</item>
<item>0x1f30c</item>
<item>0x1f309</item>
<item>0x1f30a</item>
<item>0x1f30b</item>
<item>0x1f30e</item>
<item>0x1f30f</item>
<item>0x1f30d</item>
<item>0x1f310</item>
</integer-array>
<integer-array name="emoji_symbols">
<!--item>0xfe82e|0031,20e3|99</item>
<item>0xfe82f|0032,20e3|99</item>
<item>0xfe830|0033,20e3|99</item>
<item>0xfe831|0034,20e3|99</item>
<item>0xfe832|0035,20e3|99</item>
<item>0xfe833|0036,20e3|99</item>
<item>0xfe834|0037,20e3|99</item>
<item>0xfe835|0038,20e3|99</item>
<item>0xfe836|0039,20e3|99</item>
<item>0xfe837|0030,20e3|99</item>
<item>0x1f51f||99</item>
<item>0xfe82c|0023,20e3|99</item-->
<item>0x1f51d</item>
<item>0x1f519</item>
<item>0x1f51b</item>
<item>0x1f51c</item>
<item>0x1f51a</item>
<item>0x23f3</item>
<item>0x231b</item>
<item>0x23f0</item>
<item>0x2648</item>
<item>0x2649</item>
<item>0x264a</item>
<item>0x264b</item>
<item>0x264c</item>
<item>0x264d</item>
<item>0x264e</item>
<item>0x264f</item>
<item>0x2650</item>
<item>0x2651</item>
<item>0x2652</item>
<item>0x2653</item>
<item>0x26ce</item>
<item>0x1f531</item>
<item>0x1f52f</item>
<item>0x1f6bb</item>
<item>0x1f6ae</item>
<item>0x1f6af</item>
<item>0x1f6b0</item>
<item>0x1f6b1</item>
<item>0x1f170</item>
<item>0x1f171</item>
<item>0x1f18e</item>
<item>0x1f17e</item>
<item>0x1f4ae</item>
<item>0x1f4af</item>
<item>0x1f520</item>
<item>0x1f521</item>
<item>0x1f522</item>
<item>0x1f523</item>
<item>0x1f524</item>
<item>0x27bf</item>
<item>0x1f4f6</item>
<item>0x1f4f3</item>
<item>0x1f4f4</item>
<item>0x1f4f5</item>
<item>0x1f6b9</item>
<item>0x1f6ba</item>
<item>0x1f6bc</item>
<item>0x267f</item>
<item>0x267b</item>
<item>0x1f6ad</item>
<item>0x1f6a9</item>
<item>0x26a0</item>
<item>0x1f201</item>
<item>0x1f51e</item>
<item>0x26d4</item>
<item>0x1f192</item>
<item>0x1f197</item>
<item>0x1f195</item>
<item>0x1f198</item>
<item>0x1f199</item>
<item>0x1f193</item>
<item>0x1f196</item>
<item>0x1f19a</item>
<item>0x1f232</item>
<item>0x1f233</item>
<item>0x1f234</item>
<item>0x1f235</item>
<item>0x1f236</item>
<item>0x1f237</item>
<item>0x1f238</item>
<item>0x1f239</item>
<item>0x1f202</item>
<item>0x1f23a</item>
<item>0x1f250</item>
<item>0x1f251</item>
<item>0x3299</item>
<item>0x00ae</item>
<item>0x00a9</item>
<item>0x2122</item>
<item>0x1f21a</item>
<item>0x1f22f</item>
<item>0x3297</item>
<item>0x2b55</item>
<item>0x274c</item>
<item>0x274e</item>
<item>0x2139</item>
<item>0x1f6ab</item>
<item>0x2705</item>
<item>0x2714</item>
<item>0x1f517</item>
<item>0x2734</item>
<item>0x2733</item>
<item>0x2795</item>
<item>0x2796</item>
<item>0x2716</item>
<item>0x2797</item>
<item>0x1f4a0</item>
<item>0x1f4a1</item>
<item>0x1f4a4</item>
<item>0x1f4a2</item>
<item>0x1f525</item>
<item>0x1f4a5</item>
<item>0x1f4a8</item>
<item>0x1f4a6</item>
<item>0x1f4ab</item>
<item>0x1f55b</item>
<item>0x1f567</item>
<item>0x1f550</item>
<item>0x1f55c</item>
<item>0x1f551</item>
<item>0x1f55d</item>
<item>0x1f552</item>
<item>0x1f55e</item>
<item>0x1f553</item>
<item>0x1f55f</item>
<item>0x1f554</item>
<item>0x1f560</item>
<item>0x1f555</item>
<item>0x1f561</item>
<item>0x1f556</item>
<item>0x1f562</item>
<item>0x1f557</item>
<item>0x1f563</item>
<item>0x1f558</item>
<item>0x1f564</item>
<item>0x1f559</item>
<item>0x1f565</item>
<item>0x1f55a</item>
<item>0x1f566</item>
<item>0x2195</item>
<item>0x2b06</item>
<item>0x2197</item>
<item>0x27a1</item>
<item>0x2198</item>
<item>0x2b07</item>
<item>0x2199</item>
<item>0x2b05</item>
<item>0x2196</item>
<item>0x2194</item>
<item>0x2934</item>
<item>0x2935</item>
<item>0x23ea</item>
<item>0x23eb</item>
<item>0x23ec</item>
<item>0x23e9</item>
<item>0x25c0</item>
<item>0x25b6</item>
<item>0x1f53d</item>
<item>0x1f53c</item>
<item>0x2747</item>
<item>0x2728</item>
<item>0x1f534</item>
<item>0x1f535</item>
<item>0x26aa</item>
<item>0x26ab</item>
<item>0x1f533</item>
<item>0x1f532</item>
<item>0x2b50</item>
<item>0x1f31f</item>
<item>0x1f320</item>
<item>0x25ab</item>
<item>0x25aa</item>
<item>0x25fd</item>
<item>0x25fe</item>
<item>0x25fb</item>
<item>0x25fc</item>
<item>0x2b1c</item>
<item>0x2b1b</item>
<item>0x1f538</item>
<item>0x1f539</item>
<item>0x1f536</item>
<item>0x1f537</item>
<item>0x1f53a</item>
<item>0x1f53b</item>
<item>0x2754</item>
<item>0x2753</item>
<item>0x2755</item>
<item>0x2757</item>
<item>0x203c</item>
<item>0x2049</item>
<item>0x3030</item>
<item>0x27b0</item>
<item>0x2660</item>
<item>0x2665</item>
<item>0x2663</item>
<item>0x2666</item>
<item>0x1f194</item>
<item>0x1f511</item>
<item>0x21a9</item>
<item>0x1f191</item>
<item>0x1f50d</item>
<item>0x1f512</item>
<item>0x1f513</item>
<item>0x21aa</item>
<item>0x1f510</item>
<item>0x2611</item>
<item>0x1f518</item>
<item>0x1f50e</item>
<item>0x1f516</item>
<item>0x1f50f</item>
<item>0x1f503</item>
<item>0x1f500</item>
<item>0x1f501</item>
<item>0x1f502</item>
<item>0x1f504</item>
<item>0x1f4e7</item>
<item>0x1f505</item>
<item>0x1f506</item>
<item>0x1f507</item>
<item>0x1f508</item>
<item>0x1f509</item>
<item>0x1f50a</item>
</integer-array>
<integer-array name="emoji_people">
<item>0x263a</item>
<item>0x1f60a</item>
<item>0x1f600</item>
<item>0x1f601</item>
<item>0x1f602</item>
<item>0x1f603</item>
<item>0x1f604</item>
<item>0x1f605</item>
<item>0x1f606</item>
<item>0x1f607</item>
<item>0x1f608</item>
<item>0x1f609</item>
<item>0x1f62f</item>
<item>0x1f610</item>
<item>0x1f611</item>
<item>0x1f615</item>
<item>0x1f620</item>
<item>0x1f62c</item>
<item>0x1f621</item>
<item>0x1f622</item>
<item>0x1f634</item>
<item>0x1f62e</item>
<item>0x1f623</item>
<item>0x1f624</item>
<item>0x1f625</item>
<item>0x1f626</item>
<item>0x1f627</item>
<item>0x1f628</item>
<item>0x1f629</item>
<item>0x1f630</item>
<item>0x1f61f</item>
<item>0x1f631</item>
<item>0x1f632</item>
<item>0x1f633</item>
<item>0x1f635</item>
<item>0x1f636</item>
<item>0x1f637</item>
<item>0x1f61e</item>
<item>0x1f612</item>
<item>0x1f60d</item>
<item>0x1f61b</item>
<item>0x1f61c</item>
<item>0x1f61d</item>
<item>0x1f60b</item>
<item>0x1f617</item>
<item>0x1f619</item>
<item>0x1f618</item>
<item>0x1f61a</item>
<item>0x1f60e</item>
<item>0x1f62d</item>
<item>0x1f60c</item>
<item>0x1f616</item>
<item>0x1f614</item>
<item>0x1f62a</item>
<item>0x1f60f</item>
<item>0x1f613</item>
<item>0x1f62b</item>
<item>0x1f64b</item>
<item>0x1f64c</item>
<item>0x1f64d</item>
<item>0x1f645</item>
<item>0x1f646</item>
<item>0x1f647</item>
<item>0x1f64e</item>
<item>0x1f64f</item>
<item>0x1f63a</item>
<item>0x1f63c</item>
<item>0x1f638</item>
<item>0x1f639</item>
<item>0x1f63b</item>
<item>0x1f63d</item>
<item>0x1f63f</item>
<item>0x1f63e</item>
<item>0x1f640</item>
<item>0x1f648</item>
<item>0x1f649</item>
<item>0x1f64a</item>
<item>0x1f4a9</item>
<item>0x1f476</item>
<item>0x1f466</item>
<item>0x1f467</item>
<item>0x1f468</item>
<item>0x1f469</item>
<item>0x1f474</item>
<item>0x1f475</item>
<item>0x1f48f</item>
<item>0x1f491</item>
<item>0x1f46a</item>
<item>0x1f46b</item>
<item>0x1f46c</item>
<item>0x1f46d</item>
<item>0x1f464</item>
<item>0x1f465</item>
<item>0x1f46e</item>
<item>0x1f477</item>
<item>0x1f481</item>
<item>0x1f482</item>
<item>0x1f46f</item>
<item>0x1f470</item>
<item>0x1f478</item>
<item>0x1f385</item>
<item>0x1f47c</item>
<item>0x1f471</item>
<item>0x1f472</item>
<item>0x1f473</item>
<item>0x1f483</item>
<item>0x1f486</item>
<item>0x1f487</item>
<item>0x1f485</item>
<item>0x1f47b</item>
<item>0x1f479</item>
<item>0x1f47a</item>
<item>0x1f47d</item>
<item>0x1f47e</item>
<item>0x1f47f</item>
<item>0x1f480</item>
<item>0x1f4aa</item>
<item>0x1f440</item>
<item>0x1f442</item>
<item>0x1f443</item>
<item>0x1f463</item>
<item>0x1f444</item>
<item>0x1f445</item>
<item>0x1f48b</item>
<item>0x2764</item>
<item>0x1f499</item>
<item>0x1f49a</item>
<item>0x1f49b</item>
<item>0x1f49c</item>
<item>0x1f493</item>
<item>0x1f494</item>
<item>0x1f495</item>
<item>0x1f496</item>
<item>0x1f497</item>
<item>0x1f498</item>
<item>0x1f49d</item>
<item>0x1f49e</item>
<item>0x1f49f</item>
<item>0x1f44d</item>
<item>0x1f44e</item>
<item>0x1f44c</item>
<item>0x270a</item>
<item>0x270c</item>
<item>0x270b</item>
<item>0x1f44a</item>
<item>0x261d</item>
<item>0x1f446</item>
<item>0x1f447</item>
<item>0x1f448</item>
<item>0x1f449</item>
<item>0x1f44b</item>
<item>0x1f44f</item>
<item>0x1f450</item>
</integer-array>
<integer-array name="emoji_objects">
<item>0x1f530</item>
<item>0x1f484</item>
<item>0x1f45e</item>
<item>0x1f45f</item>
<item>0x1f451</item>
<item>0x1f452</item>
<item>0x1f3a9</item>
<item>0x1f393</item>
<item>0x1f453</item>
<item>0x231a</item>
<item>0x1f454</item>
<item>0x1f455</item>
<item>0x1f456</item>
<item>0x1f457</item>
<item>0x1f458</item>
<item>0x1f459</item>
<item>0x1f460</item>
<item>0x1f461</item>
<item>0x1f462</item>
<item>0x1f45a</item>
<item>0x1f45c</item>
<item>0x1f4bc</item>
<item>0x1f392</item>
<item>0x1f45d</item>
<item>0x1f45b</item>
<item>0x1f4b0</item>
<item>0x1f4b3</item>
<item>0x1f4b2</item>
<item>0x1f4b5</item>
<item>0x1f4b4</item>
<item>0x1f4b6</item>
<item>0x1f4b7</item>
<item>0x1f4b8</item>
<item>0x1f4b1</item>
<item>0x1f4b9</item>
<item>0x1f52b</item>
<item>0x1f52a</item>
<item>0x1f4a3</item>
<item>0x1f489</item>
<item>0x1f48a</item>
<item>0x1f6ac</item>
<item>0x1f514</item>
<item>0x1f515</item>
<item>0x1f6aa</item>
<item>0x1f52c</item>
<item>0x1f52d</item>
<item>0x1f52e</item>
<item>0x1f526</item>
<item>0x1f50b</item>
<item>0x1f50c</item>
<item>0x1f4dc</item>
<item>0x1f4d7</item>
<item>0x1f4d8</item>
<item>0x1f4d9</item>
<item>0x1f4da</item>
<item>0x1f4d4</item>
<item>0x1f4d2</item>
<item>0x1f4d1</item>
<item>0x1f4d3</item>
<item>0x1f4d5</item>
<item>0x1f4d6</item>
<item>0x1f4f0</item>
<item>0x1f4db</item>
<item>0x1f383</item>
<item>0x1f384</item>
<item>0x1f380</item>
<item>0x1f381</item>
<item>0x1f382</item>
<item>0x1f388</item>
<item>0x1f386</item>
<item>0x1f387</item>
<item>0x1f389</item>
<item>0x1f38a</item>
<item>0x1f38d</item>
<item>0x1f38f</item>
<item>0x1f38c</item>
<item>0x1f390</item>
<item>0x1f38b</item>
<item>0x1f38e</item>
<item>0x1f4f1</item>
<item>0x1f4f2</item>
<item>0x1f4df</item>
<item>0x260e</item>
<item>0x1f4de</item>
<item>0x1f4e0</item>
<item>0x1f4e6</item>
<item>0x2709</item>
<item>0x1f4e8</item>
<item>0x1f4e9</item>
<item>0x1f4ea</item>
<item>0x1f4eb</item>
<item>0x1f4ed</item>
<item>0x1f4ec</item>
<item>0x1f4ee</item>
<item>0x1f4e4</item>
<item>0x1f4e5</item>
<item>0x1f4ef</item>
<item>0x1f4e2</item>
<item>0x1f4e3</item>
<item>0x1f4e1</item>
<item>0x1f4ac</item>
<item>0x1f4ad</item>
<item>0x2712</item>
<item>0x270f</item>
<item>0x1f4dd</item>
<item>0x1f4cf</item>
<item>0x1f4d0</item>
<item>0x1f4cd</item>
<item>0x1f4cc</item>
<item>0x1f4ce</item>
<item>0x2702</item>
<item>0x1f4ba</item>
<item>0x1f4bb</item>
<item>0x1f4bd</item>
<item>0x1f4be</item>
<item>0x1f4bf</item>
<item>0x1f4c6</item>
<item>0x1f4c5</item>
<item>0x1f4c7</item>
<item>0x1f4cb</item>
<item>0x1f4c1</item>
<item>0x1f4c2</item>
<item>0x1f4c3</item>
<item>0x1f4c4</item>
<item>0x1f4ca</item>
<item>0x1f4c8</item>
<item>0x1f4c9</item>
<item>0x26fa</item>
<item>0x1f3a1</item>
<item>0x1f3a2</item>
<item>0x1f3a0</item>
<item>0x1f3aa</item>
<item>0x1f3a8</item>
<item>0x1f3ac</item>
<item>0x1f3a5</item>
<item>0x1f4f7</item>
<item>0x1f4f9</item>
<item>0x1f3a6</item>
<item>0x1f3ad</item>
<item>0x1f3ab</item>
<item>0x1f3ae</item>
<item>0x1f3b2</item>
<item>0x1f3b0</item>
<item>0x1f0cf</item>
<item>0x1f3b4</item>
<item>0x1f004</item>
<item>0x1f3af</item>
<item>0x1f4fa</item>
<item>0x1f4fb</item>
<item>0x1f4c0</item>
<item>0x1f4fc</item>
<item>0x1f3a7</item>
<item>0x1f3a4</item>
<item>0x1f3b5</item>
<item>0x1f3b6</item>
<item>0x1f3bc</item>
<item>0x1f3bb</item>
<item>0x1f3b9</item>
<item>0x1f3b7</item>
<item>0x1f3ba</item>
<item>0x1f3b8</item>
<item>0x303d</item>
</integer-array>
<integer-array name="emoji_places">
<item>0x1f3e0</item>
<item>0x1f3e1</item>
<item>0x1f3e2</item>
<item>0x1f3e3</item>
<item>0x1f3e4</item>
<item>0x1f3e5</item>
<item>0x1f3e6</item>
<item>0x1f3e7</item>
<item>0x1f3e8</item>
<item>0x1f3e9</item>
<item>0x1f3ea</item>
<item>0x1f3eb</item>
<item>0x26ea</item>
<item>0x26f2</item>
<item>0x1f3ec</item>
<item>0x1f3ef</item>
<item>0x1f3f0</item>
<item>0x1f3ed</item>
<item>0x1f5fb</item>
<item>0x1f5fc</item>
<item>0x1f5fd</item>
<item>0x1f5fe</item>
<item>0x1f5ff</item>
<item>0x2693</item>
<item>0x1f3ee</item>
<item>0x1f488</item>
<item>0x1f527</item>
<item>0x1f528</item>
<item>0x1f529</item>
<item>0x1f6bf</item>
<item>0x1f6c1</item>
<item>0x1f6c0</item>
<item>0x1f6bd</item>
<item>0x1f6be</item>
<item>0x1f3bd</item>
<item>0x1f3a3</item>
<item>0x1f3b1</item>
<item>0x1f3b3</item>
<item>0x26be</item>
<item>0x26f3</item>
<item>0x1f3be</item>
<item>0x26bd</item>
<item>0x1f3bf</item>
<item>0x1f3c0</item>
<item>0x1f3c1</item>
<item>0x1f3c2</item>
<item>0x1f3c3</item>
<item>0x1f3c4</item>
<item>0x1f3c6</item>
<item>0x1f3c7</item>
<item>0x1f40e</item>
<item>0x1f3c8</item>
<item>0x1f3c9</item>
<item>0x1f3ca</item>
<item>0x1f682</item>
<item>0x1f683</item>
<item>0x1f684</item>
<item>0x1f685</item>
<item>0x1f686</item>
<item>0x1f687</item>
<item>0x24c2</item>
<item>0x1f688</item>
<item>0x1f68a</item>
<item>0x1f68b</item>
<item>0x1f68c</item>
<item>0x1f68d</item>
<item>0x1f68e</item>
<item>0x1f68f</item>
<item>0x1f690</item>
<item>0x1f691</item>
<item>0x1f692</item>
<item>0x1f693</item>
<item>0x1f694</item>
<item>0x1f695</item>
<item>0x1f696</item>
<item>0x1f697</item>
<item>0x1f698</item>
<item>0x1f699</item>
<item>0x1f69a</item>
<item>0x1f69b</item>
<item>0x1f69c</item>
<item>0x1f69d</item>
<item>0x1f69e</item>
<item>0x1f69f</item>
<item>0x1f6a0</item>
<item>0x1f6a1</item>
<item>0x1f6a2</item>
<item>0x1f6a3</item>
<item>0x1f681</item>
<item>0x2708</item>
<item>0x1f6c2</item>
<item>0x1f6c3</item>
<item>0x1f6c4</item>
<item>0x1f6c5</item>
<item>0x26f5</item>
<item>0x1f6b2</item>
<item>0x1f6b3</item>
<item>0x1f6b4</item>
<item>0x1f6b5</item>
<item>0x1f6b7</item>
<item>0x1f6b8</item>
<item>0x1f689</item>
<item>0x1f680</item>
<item>0x1f6a4</item>
<item>0x1f6b6</item>
<item>0x26fd</item>
<item>0x1f17f</item>
<item>0x1f6a5</item>
<item>0x1f6a6</item>
<item>0x1f6a7</item>
<item>0x1f6a8</item>
<item>0x2668</item>
<item>0x1f48c</item>
<item>0x1f48d</item>
<item>0x1f48e</item>
<item>0x1f490</item>
<item>0x1f492</item>
<!--item>fe4e5|1f1ef,1f1f5|99</item>
<item>fe4e6|1f1fa,1f1f8|99</item>
<item>fe4e7|1f1eb,1f1f7|99</item>
<item>fe4e8|1f1e9,1f1ea|99</item>
<item>fe4e9|1f1ee,1f1f9|99</item>
<item>fe4ea|1f1ec,1f1e7|99</item>
<item>fe4eb|1f1ea,1f1f8|99</item>
<item>fe4ec|1f1f7,1f1fa|99</item>
<item>fe4ed|1f1e8,1f1f3|99</item>
<item>fe4ee|1f1f0,1f1f7|99</item-->
</integer-array>
<string-array name="emoji_emoticons">
<item>=-O</item>
<item>:-P</item>
<item>;-)</item>
<item>:-(</item>
<item>:-)</item>
<item>:-!</item>
<item>:-$</item>
<item>B-)</item>
<item>:O</item>
<item>:-*</item>
<item>:-D</item>
<item>":'("</item>
<item>:-\\</item>
<item>O:-)</item>
<item>:-[</item>
</string-array>
<integer-array name="emoji_categories">
<item>@array/emoji_people</item>
<item>@array/emoji_objects</item>
<item>@array/emoji_nature</item>
<item>@array/emoji_places</item>
<item>@array/emoji_symbols</item>
</integer-array>
<integer-array name="emoji_category_icons">
<item>@drawable/emoji_category_people</item>
<item>@drawable/emoji_category_objects</item>
<item>@drawable/emoji_category_nature</item>
<item>@drawable/emoji_category_places</item>
<item>@drawable/emoji_category_symbol</item>
</integer-array>
</resources>

View File

@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.components.emoji;
import android.content.Context;
import android.support.annotation.ArrayRes;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.view.PagerAdapter;
@ -62,7 +63,7 @@ public class EmojiDrawer extends KeyboardAwareLinearLayout {
private void init() {
final View v = LayoutInflater.from(getContext()).inflate(R.layout.emoji_drawer, this, true);
initializeResources(v);
initializePageModels(R.array.emoji_categories, R.array.emoji_category_icons);
initializePageModels();
initializeEmojiGrid();
}
@ -102,27 +103,23 @@ public class EmojiDrawer extends KeyboardAwareLinearLayout {
pager.setAdapter(new EmojiPagerAdapter(getContext(),
models,
new EmojiSelectionListener() {
@Override public void onEmojiSelected(int emojiCode) {
recentModel.onCodePointSelected(emojiCode);
composeText.insertEmoji(emojiCode);
@Override public void onEmojiSelected(String emoji) {
recentModel.onCodePointSelected(emoji);
composeText.insertEmoji(emoji);
}
}));
if (recentModel.getCodePoints().length == 0) {
if (recentModel.getEmoji().length == 0) {
pager.setCurrentItem(1);
}
strip.setViewPager(pager);
}
private void initializePageModels(@ArrayRes int pagesRes, @ArrayRes int iconsRes) {
final int[] icons = ResUtil.getResourceIds(getContext(), iconsRes);
final int[] pages = ResUtil.getResourceIds(getContext(), pagesRes);
private void initializePageModels() {
this.models = new LinkedList<>();
this.recentModel = new RecentEmojiPageModel(getContext());
this.models.add(recentModel);
for (int i = 0; i < icons.length; i++) {
this.models.add(new StaticEmojiPageModel(icons[i], getResources().getIntArray(pages[i])));
}
this.models.addAll(EmojiPages.PAGES);
}
public static class EmojiPagerAdapter extends PagerAdapter

View File

@ -22,19 +22,18 @@ public class EmojiEditText extends AppCompatEditText {
}
@Override public void setText(CharSequence text, BufferType type) {
super.setText(EmojiProvider.getInstance(getContext()).emojify(text, EmojiProvider.EMOJI_SMALL, new PostInvalidateCallback(this)),
super.setText(EmojiProvider.getInstance(getContext()).emojify(text, EmojiProvider.EMOJI_SMALL, callback),
BufferType.SPANNABLE);
}
public void insertEmoji(int codePoint) {
public void insertEmoji(String emoji) {
final int start = getSelectionStart();
final int end = getSelectionEnd();
final char[] chars = Character.toChars(codePoint);
final CharSequence text = EmojiProvider.getInstance(getContext()).emojify(new String(chars),
final CharSequence text = EmojiProvider.getInstance(getContext()).emojify(emoji,
EmojiProvider.EMOJI_SMALL,
callback);
getText().replace(Math.min(start, end), Math.max(start, end), text);
setSelection(end + chars.length);
setSelection(end + emoji.length());
}
}

View File

@ -2,6 +2,8 @@ package org.thoughtcrime.securesms.components.emoji;
public interface EmojiPageModel {
int getIconRes();
int[] getCodePoints();
String[] getEmoji();
boolean hasSpriteMap();
String getSprite();
boolean isDynamic();
}

View File

@ -14,7 +14,6 @@ import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.FrameLayout;
import android.widget.GridView;
import android.widget.ImageView;
import org.thoughtcrime.securesms.R;
@ -58,7 +57,7 @@ public class EmojiPageView extends FrameLayout {
grid.setColumnWidth(getResources().getDimensionPixelSize(R.dimen.emoji_drawer_size) + 2 * getResources().getDimensionPixelSize(R.dimen.emoji_drawer_item_padding));
grid.setOnItemClickListener(new OnItemClickListener() {
@Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (listener != null) listener.onEmojiSelected((Integer)view.getTag());
if (listener != null) listener.onEmojiSelected((String)view.getTag());
}
});
}
@ -85,7 +84,7 @@ public class EmojiPageView extends FrameLayout {
}
@Override public int getCount() {
return model.getCodePoints().length;
return model.getEmoji().length;
}
@Override
@ -100,29 +99,24 @@ public class EmojiPageView extends FrameLayout {
@Override
public View getView(final int position, final View convertView, final ViewGroup parent) {
final ImageView view;
final EmojiView view;
final int pad = context.getResources().getDimensionPixelSize(R.dimen.emoji_drawer_item_padding);
if (convertView != null && convertView instanceof ImageView) {
view = (ImageView)convertView;
if (convertView != null && convertView instanceof EmojiView) {
view = (EmojiView)convertView;
} else {
ImageView imageView = new ImageView(context);
imageView.setPadding(pad, pad, pad, pad);
imageView.setLayoutParams(new AbsListView.LayoutParams(emojiSize + 2 * pad, emojiSize + 2 * pad));
view = imageView;
EmojiView emojiView = new EmojiView(context);
emojiView.setPadding(pad, pad, pad, pad);
emojiView.setLayoutParams(new AbsListView.LayoutParams(emojiSize + 2 * pad, emojiSize + 2 * pad));
view = emojiView;
}
final Integer unicodeTag = model.getCodePoints()[position];
final EmojiProvider provider = EmojiProvider.getInstance(context);
final Drawable drawable = provider.getEmojiDrawable(unicodeTag, EmojiProvider.EMOJI_FULL);
view.setImageDrawable(drawable);
view.setPadding(pad, pad, pad, pad);
view.setTag(unicodeTag);
view.setEmoji(model.getEmoji()[position]);
view.setTag(model.getEmoji()[position]);
return view;
}
}
public interface EmojiSelectionListener {
void onEmojiSelected(int emojiCode);
void onEmojiSelected(String emoji);
}
}

View File

@ -0,0 +1,164 @@
package org.thoughtcrime.securesms.components.emoji;
import org.thoughtcrime.securesms.R;
import java.util.Arrays;
import java.util.List;
public class EmojiPages {
public static final List<EmojiPageModel> PAGES = Arrays.<EmojiPageModel>asList(
new StaticEmojiPageModel(R.drawable.emoji_category_people, new String[] {
"\u263a", "\ud83d\ude0a", "\ud83d\ude00", "\ud83d\ude01", "\ud83d\ude02", "\ud83d\ude03",
"\ud83d\ude04", "\ud83d\ude05", "\ud83d\ude06", "\ud83d\ude07", "\ud83d\ude08", "\ud83d\ude09",
"\ud83d\ude2f", "\ud83d\ude10", "\ud83d\ude11", "\ud83d\ude15", "\ud83d\ude20", "\ud83d\ude2c",
"\ud83d\ude21", "\ud83d\ude22", "\ud83d\ude34", "\ud83d\ude2e", "\ud83d\ude23", "\ud83d\ude24",
"\ud83d\ude25", "\ud83d\ude26", "\ud83d\ude27", "\ud83d\ude28", "\ud83d\ude29", "\ud83d\ude30",
"\ud83d\ude1f", "\ud83d\ude31", "\ud83d\ude32", "\ud83d\ude33", "\ud83d\ude35", "\ud83d\ude36",
"\ud83d\ude37", "\ud83d\ude1e", "\ud83d\ude12", "\ud83d\ude0d", "\ud83d\ude1b", "\ud83d\ude1c",
"\ud83d\ude1d", "\ud83d\ude0b", "\ud83d\ude17", "\ud83d\ude19", "\ud83d\ude18", "\ud83d\ude1a",
"\ud83d\ude0e", "\ud83d\ude2d", "\ud83d\ude0c", "\ud83d\ude16", "\ud83d\ude14", "\ud83d\ude2a",
"\ud83d\ude0f", "\ud83d\ude13", "\ud83d\ude2b", "\ud83d\ude4b", "\ud83d\ude4c", "\ud83d\ude4d",
"\ud83d\ude45", "\ud83d\ude46", "\ud83d\ude47", "\ud83d\ude4e", "\ud83d\ude4f", "\ud83d\ude3a",
"\ud83d\ude3c", "\ud83d\ude38", "\ud83d\ude39", "\ud83d\ude3b", "\ud83d\ude3d", "\ud83d\ude3f",
"\ud83d\ude3e", "\ud83d\ude40", "\ud83d\ude48", "\ud83d\ude49", "\ud83d\ude4a", "\ud83d\udca9",
"\ud83d\udc76", "\ud83d\udc66", "\ud83d\udc67", "\ud83d\udc68", "\ud83d\udc69", "\ud83d\udc74",
"\ud83d\udc75", "\ud83d\udc8f", "\ud83d\udc91", "\ud83d\udc6a", "\ud83d\udc6b", "\ud83d\udc6c",
"\ud83d\udc6d", "\ud83d\udc64", "\ud83d\udc65", "\ud83d\udc6e", "\ud83d\udc77", "\ud83d\udc81",
"\ud83d\udc82", "\ud83d\udc6f", "\ud83d\udc70", "\ud83d\udc78", "\ud83c\udf85", "\ud83d\udc7c",
"\ud83d\udc71", "\ud83d\udc72", "\ud83d\udc73", "\ud83d\udc83", "\ud83d\udc86", "\ud83d\udc87",
"\ud83d\udc85", "\ud83d\udc7b", "\ud83d\udc79", "\ud83d\udc7a", "\ud83d\udc7d", "\ud83d\udc7e",
"\ud83d\udc7f", "\ud83d\udc80", "\ud83d\udcaa", "\ud83d\udc40", "\ud83d\udc42", "\ud83d\udc43",
"\ud83d\udc63", "\ud83d\udc44", "\ud83d\udc45", "\ud83d\udc8b", "\u2764", "\ud83d\udc99",
"\ud83d\udc9a", "\ud83d\udc9b", "\ud83d\udc9c", "\ud83d\udc93", "\ud83d\udc94", "\ud83d\udc95",
"\ud83d\udc96", "\ud83d\udc97", "\ud83d\udc98", "\ud83d\udc9d", "\ud83d\udc9e", "\ud83d\udc9f",
"\ud83d\udc4d", "\ud83d\udc4e", "\ud83d\udc4c", "\u270a", "\u270c", "\u270b",
"\ud83d\udc4a", "\u261d", "\ud83d\udc46", "\ud83d\udc47", "\ud83d\udc48", "\ud83d\udc49",
"\ud83d\udc4b", "\ud83d\udc4f", "\ud83d\udc50",
}, "emoji-people.png"),
new StaticEmojiPageModel(R.drawable.emoji_category_objects, new String[] {
"\ud83d\udd30", "\ud83d\udc84", "\ud83d\udc5e", "\ud83d\udc5f", "\ud83d\udc51", "\ud83d\udc52",
"\ud83c\udfa9", "\ud83c\udf93", "\ud83d\udc53", "\u231a", "\ud83d\udc54", "\ud83d\udc55",
"\ud83d\udc56", "\ud83d\udc57", "\ud83d\udc58", "\ud83d\udc59", "\ud83d\udc60", "\ud83d\udc61",
"\ud83d\udc62", "\ud83d\udc5a", "\ud83d\udc5c", "\ud83d\udcbc", "\ud83c\udf92", "\ud83d\udc5d",
"\ud83d\udc5b", "\ud83d\udcb0", "\ud83d\udcb3", "\ud83d\udcb2", "\ud83d\udcb5", "\ud83d\udcb4",
"\ud83d\udcb6", "\ud83d\udcb7", "\ud83d\udcb8", "\ud83d\udcb1", "\ud83d\udcb9", "\ud83d\udd2b",
"\ud83d\udd2a", "\ud83d\udca3", "\ud83d\udc89", "\ud83d\udc8a", "\ud83d\udeac", "\ud83d\udd14",
"\ud83d\udd15", "\ud83d\udeaa", "\ud83d\udd2c", "\ud83d\udd2d", "\ud83d\udd2e", "\ud83d\udd26",
"\ud83d\udd0b", "\ud83d\udd0c", "\ud83d\udcdc", "\ud83d\udcd7", "\ud83d\udcd8", "\ud83d\udcd9",
"\ud83d\udcda", "\ud83d\udcd4", "\ud83d\udcd2", "\ud83d\udcd1", "\ud83d\udcd3", "\ud83d\udcd5",
"\ud83d\udcd6", "\ud83d\udcf0", "\ud83d\udcdb", "\ud83c\udf83", "\ud83c\udf84", "\ud83c\udf80",
"\ud83c\udf81", "\ud83c\udf82", "\ud83c\udf88", "\ud83c\udf86", "\ud83c\udf87", "\ud83c\udf89",
"\ud83c\udf8a", "\ud83c\udf8d", "\ud83c\udf8f", "\ud83c\udf8c", "\ud83c\udf90", "\ud83c\udf8b",
"\ud83c\udf8e", "\ud83d\udcf1", "\ud83d\udcf2", "\ud83d\udcdf", "\u260e", "\ud83d\udcde",
"\ud83d\udce0", "\ud83d\udce6", "\u2709", "\ud83d\udce8", "\ud83d\udce9", "\ud83d\udcea",
"\ud83d\udceb", "\ud83d\udced", "\ud83d\udcec", "\ud83d\udcee", "\ud83d\udce4", "\ud83d\udce5",
"\ud83d\udcef", "\ud83d\udce2", "\ud83d\udce3", "\ud83d\udce1", "\ud83d\udcac", "\ud83d\udcad",
"\u2712", "\u270f", "\ud83d\udcdd", "\ud83d\udccf", "\ud83d\udcd0", "\ud83d\udccd",
"\ud83d\udccc", "\ud83d\udcce", "\u2702", "\ud83d\udcba", "\ud83d\udcbb", "\ud83d\udcbd",
"\ud83d\udcbe", "\ud83d\udcbf", "\ud83d\udcc6", "\ud83d\udcc5", "\ud83d\udcc7", "\ud83d\udccb",
"\ud83d\udcc1", "\ud83d\udcc2", "\ud83d\udcc3", "\ud83d\udcc4", "\ud83d\udcca", "\ud83d\udcc8",
"\ud83d\udcc9", "\u26fa", "\ud83c\udfa1", "\ud83c\udfa2", "\ud83c\udfa0", "\ud83c\udfaa",
"\ud83c\udfa8", "\ud83c\udfac", "\ud83c\udfa5", "\ud83d\udcf7", "\ud83d\udcf9", "\ud83c\udfa6",
"\ud83c\udfad", "\ud83c\udfab", "\ud83c\udfae", "\ud83c\udfb2", "\ud83c\udfb0", "\ud83c\udccf",
"\ud83c\udfb4", "\ud83c\udc04", "\ud83c\udfaf", "\ud83d\udcfa", "\ud83d\udcfb", "\ud83d\udcc0",
"\ud83d\udcfc", "\ud83c\udfa7", "\ud83c\udfa4", "\ud83c\udfb5", "\ud83c\udfb6", "\ud83c\udfbc",
"\ud83c\udfbb", "\ud83c\udfb9", "\ud83c\udfb7", "\ud83c\udfba", "\ud83c\udfb8", "\u303d",
}, "emoji-objects.png"),
new StaticEmojiPageModel(R.drawable.emoji_category_nature, new String[] {
"\ud83d\udc15", "\ud83d\udc36", "\ud83d\udc29", "\ud83d\udc08", "\ud83d\udc31", "\ud83d\udc00",
"\ud83d\udc01", "\ud83d\udc2d", "\ud83d\udc39", "\ud83d\udc22", "\ud83d\udc07", "\ud83d\udc30",
"\ud83d\udc13", "\ud83d\udc14", "\ud83d\udc23", "\ud83d\udc24", "\ud83d\udc25", "\ud83d\udc26",
"\ud83d\udc0f", "\ud83d\udc11", "\ud83d\udc10", "\ud83d\udc3a", "\ud83d\udc03", "\ud83d\udc02",
"\ud83d\udc04", "\ud83d\udc2e", "\ud83d\udc34", "\ud83d\udc17", "\ud83d\udc16", "\ud83d\udc37",
"\ud83d\udc3d", "\ud83d\udc38", "\ud83d\udc0d", "\ud83d\udc3c", "\ud83d\udc27", "\ud83d\udc18",
"\ud83d\udc28", "\ud83d\udc12", "\ud83d\udc35", "\ud83d\udc06", "\ud83d\udc2f", "\ud83d\udc3b",
"\ud83d\udc2b", "\ud83d\udc2a", "\ud83d\udc0a", "\ud83d\udc33", "\ud83d\udc0b", "\ud83d\udc1f",
"\ud83d\udc20", "\ud83d\udc21", "\ud83d\udc19", "\ud83d\udc1a", "\ud83d\udc2c", "\ud83d\udc0c",
"\ud83d\udc1b", "\ud83d\udc1c", "\ud83d\udc1d", "\ud83d\udc1e", "\ud83d\udc32", "\ud83d\udc09",
"\ud83d\udc3e", "\ud83c\udf78", "\ud83c\udf7a", "\ud83c\udf7b", "\ud83c\udf77", "\ud83c\udf79",
"\ud83c\udf76", "\u2615", "\ud83c\udf75", "\ud83c\udf7c", "\ud83c\udf74", "\ud83c\udf68",
"\ud83c\udf67", "\ud83c\udf66", "\ud83c\udf69", "\ud83c\udf70", "\ud83c\udf6a", "\ud83c\udf6b",
"\ud83c\udf6c", "\ud83c\udf6d", "\ud83c\udf6e", "\ud83c\udf6f", "\ud83c\udf73", "\ud83c\udf54",
"\ud83c\udf5f", "\ud83c\udf5d", "\ud83c\udf55", "\ud83c\udf56", "\ud83c\udf57", "\ud83c\udf64",
"\ud83c\udf63", "\ud83c\udf71", "\ud83c\udf5e", "\ud83c\udf5c", "\ud83c\udf59", "\ud83c\udf5a",
"\ud83c\udf5b", "\ud83c\udf72", "\ud83c\udf65", "\ud83c\udf62", "\ud83c\udf61", "\ud83c\udf58",
"\ud83c\udf60", "\ud83c\udf4c", "\ud83c\udf4e", "\ud83c\udf4f", "\ud83c\udf4a", "\ud83c\udf4b",
"\ud83c\udf44", "\ud83c\udf45", "\ud83c\udf46", "\ud83c\udf47", "\ud83c\udf48", "\ud83c\udf49",
"\ud83c\udf50", "\ud83c\udf51", "\ud83c\udf52", "\ud83c\udf53", "\ud83c\udf4d", "\ud83c\udf30",
"\ud83c\udf31", "\ud83c\udf32", "\ud83c\udf33", "\ud83c\udf34", "\ud83c\udf35", "\ud83c\udf37",
"\ud83c\udf38", "\ud83c\udf39", "\ud83c\udf40", "\ud83c\udf41", "\ud83c\udf42", "\ud83c\udf43",
"\ud83c\udf3a", "\ud83c\udf3b", "\ud83c\udf3c", "\ud83c\udf3d", "\ud83c\udf3e", "\ud83c\udf3f",
"\u2600", "\ud83c\udf08", "\u26c5", "\u2601", "\ud83c\udf01", "\ud83c\udf02",
"\u2614", "\ud83d\udca7", "\u26a1", "\ud83c\udf00", "\u2744", "\u26c4",
"\ud83c\udf19", "\ud83c\udf1e", "\ud83c\udf1d", "\ud83c\udf1a", "\ud83c\udf1b", "\ud83c\udf1c",
"\ud83c\udf11", "\ud83c\udf12", "\ud83c\udf13", "\ud83c\udf14", "\ud83c\udf15", "\ud83c\udf16",
"\ud83c\udf17", "\ud83c\udf18", "\ud83c\udf91", "\ud83c\udf04", "\ud83c\udf05", "\ud83c\udf07",
"\ud83c\udf06", "\ud83c\udf03", "\ud83c\udf0c", "\ud83c\udf09", "\ud83c\udf0a", "\ud83c\udf0b",
"\ud83c\udf0e", "\ud83c\udf0f", "\ud83c\udf0d", "\ud83c\udf10",
}, "emoji-nature.png"),
new StaticEmojiPageModel(R.drawable.emoji_category_places, new String[] {
"\ud83c\udfe0", "\ud83c\udfe1", "\ud83c\udfe2", "\ud83c\udfe3", "\ud83c\udfe4", "\ud83c\udfe5",
"\ud83c\udfe6", "\ud83c\udfe7", "\ud83c\udfe8", "\ud83c\udfe9", "\ud83c\udfea", "\ud83c\udfeb",
"\u26ea", "\u26f2", "\ud83c\udfec", "\ud83c\udfef", "\ud83c\udff0", "\ud83c\udfed",
"\ud83d\uddfb", "\ud83d\uddfc", "\ud83d\uddfd", "\ud83d\uddfe", "\ud83d\uddff", "\u2693",
"\ud83c\udfee", "\ud83d\udc88", "\ud83d\udd27", "\ud83d\udd28", "\ud83d\udd29", "\ud83d\udebf",
"\ud83d\udec1", "\ud83d\udec0", "\ud83d\udebd", "\ud83d\udebe", "\ud83c\udfbd", "\ud83c\udfa3",
"\ud83c\udfb1", "\ud83c\udfb3", "\u26be", "\u26f3", "\ud83c\udfbe", "\u26bd",
"\ud83c\udfbf", "\ud83c\udfc0", "\ud83c\udfc1", "\ud83c\udfc2", "\ud83c\udfc3", "\ud83c\udfc4",
"\ud83c\udfc6", "\ud83c\udfc7", "\ud83d\udc0e", "\ud83c\udfc8", "\ud83c\udfc9", "\ud83c\udfca",
"\ud83d\ude82", "\ud83d\ude83", "\ud83d\ude84", "\ud83d\ude85", "\ud83d\ude86", "\ud83d\ude87",
"\u24c2", "\ud83d\ude88", "\ud83d\ude8a", "\ud83d\ude8b", "\ud83d\ude8c", "\ud83d\ude8d",
"\ud83d\ude8e", "\ud83d\ude8f", "\ud83d\ude90", "\ud83d\ude91", "\ud83d\ude92", "\ud83d\ude93",
"\ud83d\ude94", "\ud83d\ude95", "\ud83d\ude96", "\ud83d\ude97", "\ud83d\ude98", "\ud83d\ude99",
"\ud83d\ude9a", "\ud83d\ude9b", "\ud83d\ude9c", "\ud83d\ude9d", "\ud83d\ude9e", "\ud83d\ude9f",
"\ud83d\udea0", "\ud83d\udea1", "\ud83d\udea2", "\ud83d\udea3", "\ud83d\ude81", "\u2708",
"\ud83d\udec2", "\ud83d\udec3", "\ud83d\udec4", "\ud83d\udec5", "\u26f5", "\ud83d\udeb2",
"\ud83d\udeb3", "\ud83d\udeb4", "\ud83d\udeb5", "\ud83d\udeb7", "\ud83d\udeb8", "\ud83d\ude89",
"\ud83d\ude80", "\ud83d\udea4", "\ud83d\udeb6", "\u26fd", "\ud83c\udd7f", "\ud83d\udea5",
"\ud83d\udea6", "\ud83d\udea7", "\ud83d\udea8", "\u2668", "\ud83d\udc8c", "\ud83d\udc8d",
"\ud83d\udc8e", "\ud83d\udc90", "\ud83d\udc92",
}, "emoji-places.png"),
new StaticEmojiPageModel(R.drawable.emoji_category_symbol, new String[] {
"\ud83d\udd1d", "\ud83d\udd19", "\ud83d\udd1b", "\ud83d\udd1c", "\ud83d\udd1a", "\u23f3",
"\u231b", "\u23f0", "\u2648", "\u2649", "\u264a", "\u264b",
"\u264c", "\u264d", "\u264e", "\u264f", "\u2650", "\u2651",
"\u2652", "\u2653", "\u26ce", "\ud83d\udd31", "\ud83d\udd2f", "\ud83d\udebb",
"\ud83d\udeae", "\ud83d\udeaf", "\ud83d\udeb0", "\ud83d\udeb1", "\ud83c\udd70", "\ud83c\udd71",
"\ud83c\udd8e", "\ud83c\udd7e", "\ud83d\udcae", "\ud83d\udcaf", "\ud83d\udd20", "\ud83d\udd21",
"\ud83d\udd22", "\ud83d\udd23", "\ud83d\udd24", "\u27bf", "\ud83d\udcf6", "\ud83d\udcf3",
"\ud83d\udcf4", "\ud83d\udcf5", "\ud83d\udeb9", "\ud83d\udeba", "\ud83d\udebc", "\u267f",
"\u267b", "\ud83d\udead", "\ud83d\udea9", "\u26a0", "\ud83c\ude01", "\ud83d\udd1e",
"\u26d4", "\ud83c\udd92", "\ud83c\udd97", "\ud83c\udd95", "\ud83c\udd98", "\ud83c\udd99",
"\ud83c\udd93", "\ud83c\udd96", "\ud83c\udd9a", "\ud83c\ude32", "\ud83c\ude33", "\ud83c\ude34",
"\ud83c\ude35", "\ud83c\ude36", "\ud83c\ude37", "\ud83c\ude38", "\ud83c\ude39", "\ud83c\ude02",
"\ud83c\ude3a", "\ud83c\ude50", "\ud83c\ude51", "\u3299", "\u00ae", "\u00a9",
"\u2122", "\ud83c\ude1a", "\ud83c\ude2f", "\u3297", "\u2b55", "\u274c",
"\u274e", "\u2139", "\ud83d\udeab", "\u2705", "\u2714", "\ud83d\udd17",
"\u2734", "\u2733", "\u2795", "\u2796", "\u2716", "\u2797",
"\ud83d\udca0", "\ud83d\udca1", "\ud83d\udca4", "\ud83d\udca2", "\ud83d\udd25", "\ud83d\udca5",
"\ud83d\udca8", "\ud83d\udca6", "\ud83d\udcab", "\ud83d\udd5b", "\ud83d\udd67", "\ud83d\udd50",
"\ud83d\udd5c", "\ud83d\udd51", "\ud83d\udd5d", "\ud83d\udd52", "\ud83d\udd5e", "\ud83d\udd53",
"\ud83d\udd5f", "\ud83d\udd54", "\ud83d\udd60", "\ud83d\udd55", "\ud83d\udd61", "\ud83d\udd56",
"\ud83d\udd62", "\ud83d\udd57", "\ud83d\udd63", "\ud83d\udd58", "\ud83d\udd64", "\ud83d\udd59",
"\ud83d\udd65", "\ud83d\udd5a", "\ud83d\udd66", "\u2195", "\u2b06", "\u2197",
"\u27a1", "\u2198", "\u2b07", "\u2199", "\u2b05", "\u2196",
"\u2194", "\u2934", "\u2935", "\u23ea", "\u23eb", "\u23ec",
"\u23e9", "\u25c0", "\u25b6", "\ud83d\udd3d", "\ud83d\udd3c", "\u2747",
"\u2728", "\ud83d\udd34", "\ud83d\udd35", "\u26aa", "\u26ab", "\ud83d\udd33",
"\ud83d\udd32", "\u2b50", "\ud83c\udf1f", "\ud83c\udf20", "\u25ab", "\u25aa",
"\u25fd", "\u25fe", "\u25fb", "\u25fc", "\u2b1c", "\u2b1b",
"\ud83d\udd38", "\ud83d\udd39", "\ud83d\udd36", "\ud83d\udd37", "\ud83d\udd3a", "\ud83d\udd3b",
"\u2754", "\u2753", "\u2755", "\u2757", "\u203c", "\u2049",
"\u3030", "\u27b0", "\u2660", "\u2665", "\u2663", "\u2666",
"\ud83c\udd94", "\ud83d\udd11", "\u21a9", "\ud83c\udd91", "\ud83d\udd0d", "\ud83d\udd12",
"\ud83d\udd13", "\u21aa", "\ud83d\udd10", "\u2611", "\ud83d\udd18", "\ud83d\udd0e",
"\ud83d\udd16", "\ud83d\udd0f", "\ud83d\udd03", "\ud83d\udd00", "\ud83d\udd01", "\ud83d\udd02",
"\ud83d\udd04", "\ud83d\udce7", "\ud83d\udd05", "\ud83d\udd06", "\ud83d\udd07", "\ud83d\udd08",
"\ud83d\udd09", "\ud83d\udd0a",
}, "emoji-symbol.png"),
new StaticEmojiPageModel(R.drawable.emoji_category_emoticons, new String[] {
"=-O", ":-P", ";-)", ":-(", ":-)", ":-!",
":-$", "B-)", ":O", ":-*", ":-D", ":'(",
":-\\", "O:-)", ":-[",
}, null));
}

View File

@ -13,7 +13,6 @@ import android.graphics.drawable.Drawable.Callback;
import android.os.AsyncTask;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.support.annotation.Nullable;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.util.Log;
@ -24,7 +23,6 @@ import org.thoughtcrime.securesms.util.BitmapDecodingException;
import org.thoughtcrime.securesms.util.BitmapUtil;
import org.thoughtcrime.securesms.util.FutureTaskListener;
import org.thoughtcrime.securesms.util.ListenableFutureTask;
import org.thoughtcrime.securesms.util.ResUtil;
import org.thoughtcrime.securesms.util.Util;
import java.io.IOException;
@ -70,19 +68,18 @@ public class EmojiProvider {
}
private EmojiProvider(Context context) {
int[] pages = ResUtil.getResourceIds(context, R.array.emoji_categories);
this.context = context.getApplicationContext();
this.drawHeight = Math.min(context.getResources().getDimension(R.dimen.emoji_drawer_size), EMOJI_RAW_HEIGHT);
double drawScale = drawHeight / EMOJI_RAW_HEIGHT;
this.drawWidth = EMOJI_RAW_WIDTH * drawScale;
this.verticalPad = EMOJI_VERT_PAD * drawScale;
Log.w(TAG, "draw size: " + drawWidth + "x" + drawHeight);
for (int i = 0; i < pages.length; i++) {
final EmojiPageBitmap page = new EmojiPageBitmap(i);
final int[] codePoints = context.getResources().getIntArray(pages[i]);
for (int j = 0; j < codePoints.length; j++) {
offsets.put(codePoints[j], new DrawInfo(page, j));
for (EmojiPageModel page : EmojiPages.PAGES) {
if (page.hasSpriteMap()) {
final EmojiPageBitmap pageBitmap = new EmojiPageBitmap(page);
for (int i=0; i < page.getEmoji().length; i++) {
offsets.put(Character.codePointAt(page.getEmoji()[i], 0), new DrawInfo(pageBitmap, i));
}
}
}
}
@ -108,7 +105,9 @@ public class EmojiProvider {
}
private Drawable getEmojiDrawable(DrawInfo drawInfo, double size) {
if (drawInfo == null) return null;
if (drawInfo == null) {
return null;
}
final EmojiDrawable drawable = new EmojiDrawable(drawInfo, drawWidth, drawHeight);
drawable.setBounds(0, 0, (int)(drawWidth * size), (int)(drawHeight * size));
@ -151,7 +150,6 @@ public class EmojiProvider {
@Override
public void draw(Canvas canvas) {
if (bmp == null) {
Log.w(TAG, "no-op draw(" + info.page + ", " + info.index + ")");
return;
}
@ -170,7 +168,6 @@ public class EmojiProvider {
@TargetApi(VERSION_CODES.HONEYCOMB_MR1)
public void setBitmap(Bitmap bitmap) {
Util.assertMainThread();
Log.w(TAG, "setBitmap(" + info.page + ", " + info.index + ")");
if (VERSION.SDK_INT < VERSION_CODES.HONEYCOMB_MR1 || bmp == null || !bmp.sameAs(bitmap)) {
bmp = bitmap;
invalidateSelf();
@ -208,12 +205,12 @@ public class EmojiProvider {
}
private class EmojiPageBitmap {
private int page;
private EmojiPageModel model;
private SoftReference<Bitmap> bitmapReference;
private ListenableFutureTask<Bitmap> task;
public EmojiPageBitmap(int page) {
this.page = page;
public EmojiPageBitmap(EmojiPageModel model) {
this.model = model;
}
private ListenableFutureTask<Bitmap> get() {
@ -227,7 +224,7 @@ public class EmojiProvider {
Callable<Bitmap> callable = new Callable<Bitmap>() {
@Override public Bitmap call() throws Exception {
try {
Log.w(TAG, "loading page " + page);
Log.w(TAG, "loading page " + model.getSprite());
return loadPage();
} catch (IOException ioe) {
Log.w(TAG, ioe);
@ -254,25 +251,24 @@ public class EmojiProvider {
if (bitmapReference != null && bitmapReference.get() != null) return bitmapReference.get();
try {
final String file = "emoji-" + page + ".png";
final InputStream measureStream = context.getAssets().open(file);
final InputStream bitmapStream = context.getAssets().open(file);
final InputStream measureStream = context.getAssets().open(model.getSprite());
final InputStream bitmapStream = context.getAssets().open(model.getSprite());
final Bitmap bitmap = BitmapUtil.createScaledBitmap(measureStream, bitmapStream, (float) drawHeight / (float) EMOJI_RAW_HEIGHT);
bitmapReference = new SoftReference<>(bitmap);
Log.w(TAG, "onPageLoaded(" + page + ")");
Log.w(TAG, "onPageLoaded(" + model.getSprite() + ")");
return bitmap;
} catch (IOException ioe) {
Log.w(TAG, ioe);
throw ioe;
} catch (BitmapDecodingException bde) {
Log.w(TAG, "page " + page + " failed.");
Log.w(TAG, "page " + model + " failed.");
Log.w(TAG, bde);
throw new AssertionError("emoji sprite asset is corrupted or android decoding is broken");
}
}
@Override public String toString() {
return Integer.toString(page);
return model.getSprite();
}
}
}

View File

@ -0,0 +1,79 @@
package org.thoughtcrime.securesms.components.emoji;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build.VERSION_CODES;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.view.View;
import com.google.common.base.Optional;
public class EmojiView extends View implements Drawable.Callback {
private String emoji;
private Drawable drawable;
private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Rect textBounds = new Rect();
public EmojiView(Context context) {
super(context);
}
public EmojiView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public EmojiView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(VERSION_CODES.LOLLIPOP)
public EmojiView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public void setEmoji(String emoji) {
this.emoji = emoji;
this.drawable = EmojiProvider.getInstance(getContext())
.getEmojiDrawable(Character.codePointAt(emoji, 0),
EmojiProvider.EMOJI_FULL);
postInvalidate();
}
@Override protected void onDraw(Canvas canvas) {
if (drawable != null) {
drawable.setBounds(getPaddingLeft(),
getPaddingTop(),
getWidth() - getPaddingRight(),
getHeight() - getPaddingBottom());
drawable.setCallback(this);
drawable.draw(canvas);
} else {
float targetFontSize = 0.75f * getHeight() - getPaddingTop() - getPaddingBottom();
paint.setTextSize(targetFontSize);
paint.setColor(Color.BLACK);
paint.getTextBounds(emoji, 0, emoji.length(), textBounds);
float overflow = textBounds.width() / (getWidth() - getPaddingLeft() - getPaddingRight());
if (overflow > 1f) {
paint.setTextSize(targetFontSize / overflow);
}
canvas.drawText(emoji, 0.5f * (getWidth() - textBounds.width()), 0.5f * (getHeight() + textBounds.height()), paint);
}
}
@Override public void invalidateDrawable(@NonNull Drawable drawable) {
super.invalidateDrawable(drawable);
postInvalidate();
}
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}

View File

@ -5,7 +5,6 @@ import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import com.fasterxml.jackson.databind.type.CollectionType;
@ -20,25 +19,23 @@ import java.util.LinkedHashSet;
public class RecentEmojiPageModel implements EmojiPageModel {
private static final String TAG = RecentEmojiPageModel.class.getSimpleName();
private static final String EMOJI_LRU_PREFERENCE = "pref_recent_emoji";
private static final String EMOJI_LRU_PREFERENCE = "pref_recent_emoji2";
private static final int EMOJI_LRU_SIZE = 50;
private final SharedPreferences prefs;
private final LinkedHashSet<Integer> recentlyUsed;
private final SharedPreferences prefs;
private final LinkedHashSet<String> recentlyUsed;
public RecentEmojiPageModel(Context context) {
this.prefs = PreferenceManager.getDefaultSharedPreferences(context);
this.recentlyUsed = getPersistedCache();
}
private LinkedHashSet<Integer> getPersistedCache() {
private LinkedHashSet<String> getPersistedCache() {
String serialized = prefs.getString(EMOJI_LRU_PREFERENCE, "[]");
LinkedHashSet<String> recentlyUsedStrings;
try {
CollectionType collectionType = TypeFactory.defaultInstance()
.constructCollectionType(LinkedHashSet.class, String.class);
recentlyUsedStrings = JsonUtils.getMapper().readValue(serialized, collectionType);
return fromHexString(recentlyUsedStrings);
return JsonUtils.getMapper().readValue(serialized, collectionType);
} catch (IOException e) {
Log.w(TAG, e);
return new LinkedHashSet<>();
@ -49,32 +46,40 @@ public class RecentEmojiPageModel implements EmojiPageModel {
return R.drawable.emoji_category_recent;
}
@Override public int[] getCodePoints() {
@Override public String[] getEmoji() {
return toReversePrimitiveArray(recentlyUsed);
}
@Override public boolean hasSpriteMap() {
return false;
}
@Override public String getSprite() {
return null;
}
@Override public boolean isDynamic() {
return true;
}
public void onCodePointSelected(int codePoint) {
Log.w(TAG, "onCodePointSelected(" + codePoint + ")");
recentlyUsed.remove(codePoint);
recentlyUsed.add(codePoint);
public void onCodePointSelected(String emoji) {
Log.w(TAG, "onCodePointSelected(" + emoji + ")");
recentlyUsed.remove(emoji);
recentlyUsed.add(emoji);
if (recentlyUsed.size() > EMOJI_LRU_SIZE) {
Iterator<Integer> iterator = recentlyUsed.iterator();
Iterator<String> iterator = recentlyUsed.iterator();
iterator.next();
iterator.remove();
}
final LinkedHashSet<Integer> latestRecentlyUsed = new LinkedHashSet<>(recentlyUsed);
final LinkedHashSet<String> latestRecentlyUsed = new LinkedHashSet<>(recentlyUsed);
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
try {
String serialized = JsonUtils.toJson(toHexString(latestRecentlyUsed));
String serialized = JsonUtils.toJson(latestRecentlyUsed);
prefs.edit()
.putString(EMOJI_LRU_PREFERENCE, serialized)
.apply();
@ -87,30 +92,12 @@ public class RecentEmojiPageModel implements EmojiPageModel {
}.execute();
}
private LinkedHashSet<Integer> fromHexString(@Nullable LinkedHashSet<String> stringSet) {
final LinkedHashSet<Integer> integerSet = new LinkedHashSet<>(stringSet != null ? stringSet.size() : 0);
if (stringSet != null) {
for (String hexString : stringSet) {
integerSet.add(Integer.valueOf(hexString, 16));
}
private String[] toReversePrimitiveArray(@NonNull LinkedHashSet<String> emojiSet) {
String[] emojis = new String[emojiSet.size()];
int i = emojiSet.size() - 1;
for (String emoji : emojiSet) {
emojis[i--] = emoji;
}
return integerSet;
}
private LinkedHashSet<String> toHexString(@NonNull LinkedHashSet<Integer> integerSet) {
final LinkedHashSet<String> stringSet = new LinkedHashSet<>(integerSet.size());
for (Integer integer : integerSet) {
stringSet.add(Integer.toHexString(integer));
}
return stringSet;
}
private int[] toReversePrimitiveArray(@NonNull LinkedHashSet<Integer> integerSet) {
int[] ints = new int[integerSet.size()];
int i = integerSet.size() - 1;
for (Integer integer : integerSet) {
ints[i--] = integer;
}
return ints;
return emojis;
}
}

View File

@ -2,22 +2,33 @@ package org.thoughtcrime.securesms.components.emoji;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
public class StaticEmojiPageModel implements EmojiPageModel {
@DrawableRes private final int icon;
@NonNull private final int[] codePoints;
@DrawableRes private final int icon;
@NonNull private final String[] emoji;
@Nullable private final String sprite;
public StaticEmojiPageModel(@DrawableRes int icon, @NonNull int[] codePoints) {
this.icon = icon;
this.codePoints = codePoints;
public StaticEmojiPageModel(@DrawableRes int icon, @NonNull String[] emoji, @Nullable String sprite) {
this.icon = icon;
this.emoji = emoji;
this.sprite = sprite;
}
public int getIconRes() {
return icon;
}
@NonNull public int[] getCodePoints() {
return codePoints;
@NonNull public String[] getEmoji() {
return emoji;
}
@Override public boolean hasSpriteMap() {
return sprite != null;
}
@Override @Nullable public String getSprite() {
return sprite;
}
@Override public boolean isDynamic() {