Compare commits

...

238 Commits

Author SHA1 Message Date
B. Petersen fab24ee956 Update messenger-backend submodule. 2017-03-22 23:26:07 +01:00
B. Petersen 94f4c8b302 Update changelog. 2017-03-22 23:25:50 +01:00
B. Petersen 008a2410a7 Update changelog. 2017-03-22 15:55:46 +01:00
B. Petersen b43f337af9 Show language name in english in language select activity. 2017-03-22 15:49:56 +01:00
Björn Petersen 21895cf00f Merge pull request #59 from aligitor/master
Add Hungarian translation.
2017-03-22 15:31:53 +01:00
aligitor 721d016d86 Create strings.xml
Hungarian translation file.
2017-03-22 12:42:38 +01:00
B. Petersen 89aaa9c072 Show percentage in the configuration progress dialog. 2017-03-22 00:04:27 +01:00
B. Petersen bcb00a9d23 Add IMAP/SMTP security options. 2017-03-20 21:11:59 +01:00
B. Petersen 34cd40fdd9 Support HTML-only messages. 2017-03-18 11:18:35 +01:00
B. Petersen c8001cedce Provide an http/https-get function for the backend. 2017-03-15 22:23:28 +01:00
B. Petersen 880353888b Add input types for the account configuration dialog. 2017-03-15 21:04:10 +01:00
B. Petersen 2c67d20233 Add options for SSL/TLS and STARTTLS. 2017-03-15 16:32:15 +01:00
B. Petersen 42c08a4d5b Test IMAP and SMTP server when calling the configure-function. 2017-03-14 18:25:20 +01:00
B. Petersen 01bf0f3af5 Remove unused notifications. 2017-03-14 11:41:29 +01:00
B. Petersen e765968c2c Language (do not show 'configuring account' message as the may be interpreted as we do something with the server settings). 2017-03-14 11:09:49 +01:00
B. Petersen 3837463e41 Use larger labels for the basic account settings. 2017-03-13 23:37:13 +01:00
B. Petersen 545a2ddc24 Hide advanced account settings by default (in general, we'll try to find them out automatically). 2017-03-13 23:12:56 +01:00
B. Petersen 4f6f0b4685 Cleanup cache settings code. 2017-03-13 19:36:41 +01:00
B. Petersen 1d1bad8b3b Fine-tuning error handling. 2017-03-13 14:00:30 +01:00
B. Petersen af5769f231 Improve error handling. 2017-03-12 21:03:28 +01:00
B. Petersen 42c6337c4d Show popup errors. 2017-03-12 00:33:08 +01:00
B. Petersen 37a49c9d39 Add Korean. 2017-03-11 22:41:45 +01:00
B. Petersen 3b2f778114 Repair 'Default language' option and cleanup some language stuff. 2017-03-11 21:10:31 +01:00
B. Petersen b55cc03f6d Correct string. 2017-03-11 18:31:02 +01:00
B. Petersen 2e6eead045 Change the order of the account input fields. 2017-03-11 18:17:44 +01:00
B. Petersen e77c3303a1 Show versionCode in about dialog. 2017-03-11 11:55:32 +01:00
B. Petersen e83c4f315c Force unique video names in the blob directory. 2017-03-11 11:35:34 +01:00
B. Petersen 833c75d874 Change order of 'new group icons'. 2017-03-11 10:45:47 +01:00
B. Petersen 9688003648 Force video-recoding for videos which size is okay but the bitrate is too high. Correct maximum bitrate handing (was checked too son before and scaled down afterwards, on typical devices, this resulted in a bitrate of about 500 kbit which we use as a maximum now; everyone is welcome to improve all this stuff). 2017-03-10 19:15:54 +01:00
B. Petersen a2609d5bbe Catch video thumbnail creation errors. 2017-03-10 19:11:49 +01:00
B. Petersen 227f129455 Update changelog. 2017-03-10 13:43:32 +01:00
B. Petersen 4e683e5b37 Update messenger-backend submodule. 2017-03-10 13:29:38 +01:00
B. Petersen c5a0a00dd8 In video editor, show resulting length and size in action bar. 2017-03-10 13:25:46 +01:00
B. Petersen de0bce163f Move 'done' button in the group-creation dialog to the very most right position. 2017-03-10 12:05:46 +01:00
B. Petersen 9dcb58c1ea Use SI-prefix for file sizes. 2017-03-10 11:30:33 +01:00
B. Petersen 4729642f87 Show play-button overlay in video preview. 2017-03-10 01:28:58 +01:00
B. Petersen 751cbfa635 Create and use video thumbnails. 2017-03-10 01:17:26 +01:00
B. Petersen e40cae149b Mark some members as being final or remove them. 2017-03-09 21:33:49 +01:00
B. Petersen 758dfbaa67 Remove unneeded FileDidUpload and FileDidFailUpload notifications. 2017-03-09 19:08:48 +01:00
B. Petersen 29ec49b806 Show sended video messages immediately by using the new .increation method (before, video messages are shown after compression is done; this may take several 10th's seconds). 2017-03-09 18:43:07 +01:00
B. Petersen 8afb5595d0 Read bytes from file system, not from database. 2017-03-09 12:25:33 +01:00
B. Petersen 8430e9ddc6 In full-screen-dialogs with okay-checkmarks, we use a cancel-button instead of an ambiguous back-button, see the Material Design Guidelines, https://material.io/guidelines/components/dialogs.html#dialogs-alerts . 2017-03-09 11:44:29 +01:00
B. Petersen 7439fafe2b Name passcode activity screens. 2017-03-09 11:33:51 +01:00
B. Petersen e1655a40bd Start showing MiB already at 999 KiB, this avoids confusion with four digit KiB which may be being already Megabytes ... 2017-03-09 10:00:04 +01:00
B. Petersen 92fc521d5b If we're not playing, a long press on the waveform selects the whole message as usual. 2017-03-09 09:30:49 +01:00
B. Petersen 023d34f2b6 Simplify size formatting.. 2017-03-09 09:15:58 +01:00
B. Petersen 8fc064a5a4 Show videos using the system player, this seems to be more reliable. 2017-03-08 22:04:17 +01:00
B. Petersen b9a329f416 Recode and send videos. 2017-03-08 21:59:39 +01:00
B. Petersen 4997fa7301 Prepare sendMessage() function for async messages (needed for videos which must be recorded first). 2017-03-08 20:51:14 +01:00
B. Petersen e267d67d6e Stop playback if the playing message gets deleted. 2017-03-08 20:48:02 +01:00
B. Petersen 83b04a97ef Recode videos with the same size but different rotation. 2017-03-08 20:44:06 +01:00
B. Petersen 7852c9e9f9 Light video editor layout. 2017-03-08 16:09:54 +01:00
B. Petersen 009adc09bc Removed unneeded image search function, cleanup gallery code. 2017-03-08 13:57:18 +01:00
B. Petersen 4d3929576d Use light gallery theme, use default colors. 2017-03-08 12:23:39 +01:00
B. Petersen 7712def225 Prepare sending videos. 2017-03-08 00:19:28 +01:00
B. Petersen 9509919431 Repeat the normal play/pause buttons in the status-bar-player for internal consistence. 2017-03-07 23:13:26 +01:00
B. Petersen 15cc62f559 Make status-bar-player layout more compatible. 2017-03-07 22:44:26 +01:00
B. Petersen ae46cbbf5e Remove content intent for status-bar-player (unexpected behaviour). 2017-03-07 19:20:00 +01:00
B. Petersen 1664fcdc84 Remove suspicious voice proximity commands. 2017-03-07 19:17:16 +01:00
B. Petersen 2c45f4af37 Allow generating waveforms without a messsage object. 2017-03-07 19:00:14 +01:00
B. Petersen b3d1747c0b Fix a redrawing bug on Kit Kat. 2017-03-07 18:05:40 +01:00
B. Petersen 693952d0eb Show waveform for voice messages. 2017-03-07 17:17:37 +01:00
B. Petersen 0ad5bd6e48 Update some colors and measures. 2017-03-07 14:47:34 +01:00
B. Petersen 89c34f89c9 Remove screenshot observer. We do not want to observe the users of the app; moreover, this is useless and results in false security. 2017-03-07 13:13:20 +01:00
B. Petersen 70971a73ad Remove unused download queues, this stuff goes to the backend, if needed. 2017-03-07 12:39:28 +01:00
B. Petersen 2c5b377712 Check permission on raise-to-speak. 2017-03-07 12:06:35 +01:00
B. Petersen ae4b5a711b Go to previous/next media. 2017-03-06 19:31:52 +01:00
B. Petersen 252bc52d47 Show correct media information from the backend. 2017-03-06 17:11:12 +01:00
B. Petersen 655783db1e Make mrpoortext_t more general-purpose-use. 2017-03-05 16:53:16 +01:00
B. Petersen 10b2af3656 Simplify audio select dialog. 2017-03-05 14:23:31 +01:00
B. Petersen 54c3a963a4 Smarter voice message preview. 2017-03-03 21:32:56 +01:00
B. Petersen a7836eaded Sending voice messages using 'Raise to speak' :-) 2017-03-03 19:20:25 +01:00
B. Petersen 10fcbdc81d Bump version. 2017-03-03 16:33:32 +01:00
B. Petersen b2a5885787 Show ABI separated from version. 2017-03-03 16:15:35 +01:00
B. Petersen 9886a4feb4 Add advanced settings dialog, remove some upload functions. 2017-03-03 15:26:17 +01:00
B. Petersen dcd04f7064 Remove always-empty-objects. 2017-03-03 15:05:37 +01:00
B. Petersen 5773ce8b83 Update gradle. 2017-03-03 14:38:46 +01:00
B. Petersen 0c3eb19de6 Rewrite settings dialogs. 2017-03-03 14:37:30 +01:00
B. Petersen 5e72e30d58 Fix endless redraw loop for voice message showing. 2017-03-02 23:23:48 +01:00
B. Petersen c9d8ad3d4a Show the status-bar-player for music as well as for voice messages. 2017-03-02 22:26:57 +01:00
B. Petersen 62bd4f6d9f Cleanup some ChatMessageCell conditions. 2017-03-02 21:48:02 +01:00
B. Petersen 15e1d55a77 Send voice messages as voice messages. 2017-03-02 21:22:34 +01:00
B. Petersen 04cab2ee0c Remove webpage message types. 2017-03-02 21:19:51 +01:00
B. Petersen fd28868ea8 Stop player when deselecting an audio track in the audio-select-activity. 2017-03-02 17:43:00 +01:00
B. Petersen 129e6ad487 Do not hide the default-send-key if send-by-enter is enables (looks like a bug). 2017-03-02 16:43:37 +01:00
B. Petersen 082f7229f2 Visualise enabled send-by-enter-function by hiding the normal send-button and showing a send key instead of a new-line-key on the keyboard. 2017-03-02 15:09:29 +01:00
B. Petersen 1c6001ed92 Remove unused top-view from ChatActivityEnterView. 2017-03-02 13:43:27 +01:00
B. Petersen 2ec48ef1e6 Remove unused cancelBotButton. 2017-03-02 13:19:43 +01:00
B. Petersen 04397f3cb0 Remove unused caption-text-view-layout. 2017-03-02 12:51:18 +01:00
B. Petersen 8697756083 Cleanup setting page. 2017-03-02 11:32:07 +01:00
B. Petersen 7be5ec589c Remove unneded permissions. 2017-03-01 22:05:57 +01:00
B. Petersen d3fbf529eb Remove (hopefully) unneeded AbstractThreadedSyncAdapter. 2017-03-01 20:14:39 +01:00
B. Petersen e47818b5df Remove currently unused and not implemented ChooserTargetService. 2017-03-01 18:56:23 +01:00
B. Petersen 201c9ebf4c Remove currently unused AccountAuthenticator service. 2017-03-01 18:36:14 +01:00
B. Petersen 0626192659 Allow 'Open messages' only for messages with an attachment. 2017-03-01 17:57:10 +01:00
B. Petersen 0acdd3f885 Enable basic voice message recording. 2017-03-01 15:18:26 +01:00
B. Petersen 6f0fd1072d Remove disturbing 'big' notification-music-player. Update notification-music-player logo and colors. 2017-03-01 14:22:36 +01:00
B. Petersen d17579b928 Do not expose data through MediaBrowserService, this seems unexpected for an messenger. Instead, the user can use 'save to music' or 'share' explicitly for items not privacy related. 2017-03-01 11:30:39 +01:00
B. Petersen 090039ec29 Remove internal player and rely on the MusicService 2017-02-28 23:18:07 +01:00
B. Petersen df8bbcd00a Orange audio seekbar. 2017-02-28 22:19:23 +01:00
B. Petersen fffc77cc82 Play audio files. 2017-02-28 21:53:49 +01:00
B. Petersen 9ee5af9fd2 Update German. 2017-02-28 20:53:45 +01:00
B. Petersen 5462f3d341 Add 'Open' command for all file types. 2017-02-28 19:15:31 +01:00
B. Petersen 46dca0d212 Remove unused resources. 2017-02-28 18:39:25 +01:00
B. Petersen 603572c796 Remove (hopefully) unneeded ShareBroadcastReceiver class. 2017-02-28 17:45:11 +01:00
B. Petersen db6c2d9d7c Show 'File not found' hint. 2017-02-28 17:03:25 +01:00
B. Petersen b6c6375492 More senseful name for new-chat-from-deaddrop-button. 2017-02-28 16:08:52 +01:00
B. Petersen 3f5255c116 Remove load and cancel buttons from ChatMessageCell, cleanup. 2017-02-28 15:59:15 +01:00
B. Petersen 68f3974aa2 Name button states. 2017-02-28 14:26:45 +01:00
B. Petersen 2c062d8d51 Select and send audio attachments via the music browser. 2017-02-27 22:35:20 +01:00
B. Petersen 1097157f69 Show icon for incoming audio files. 2017-02-27 22:01:52 +01:00
B. Petersen 21784aa951 Simplify and rework message sending. 2017-02-27 19:24:55 +01:00
B. Petersen f980f7285a Remove unused 'Reply'-parameters, continued. 2017-02-27 17:12:04 +01:00
B. Petersen 622b6bc786 Remove unused 'Reply'-parameters. 2017-02-27 16:26:44 +01:00
B. Petersen 61fc0485b7 Unify attach icons. 2017-02-27 12:25:22 +01:00
B. Petersen be2af9c871 Name the request codes. Wondering how this was editable before. 2017-02-24 21:42:31 +01:00
B. Petersen 898e4a45e3 Remove unneeded merge-dialog option. 2017-02-24 20:48:04 +01:00
B. Petersen e47c6406f8 Implement share from chat/photo view. 2017-02-24 19:41:18 +01:00
B. Petersen 1d0ed83bad Implement save to downloads/music/gallery. 2017-02-24 17:34:54 +01:00
Björn Petersen 404f6ea9da Update CHANGELOG.md 2017-02-24 12:00:52 +01:00
B. Petersen 8d75f867fd Add menu buttons for saving and sharing attachments. 2017-02-23 23:59:45 +01:00
B. Petersen 83f60e6252 Remove unused file observers. 2017-02-23 22:44:03 +01:00
B. Petersen c4bd6576d8 Simplify object creation. 2017-02-23 22:43:31 +01:00
B. Petersen 12df911162 Use the standard text view for pincode entering; otherwise, the last entered number is always shown for a moment, independently of the system setting (in fact, for pincodes, currently, the number is _never_ shown as setText() does not work this way; however, this is just fine, much better). 2017-02-23 21:06:53 +01:00
B. Petersen f5a37ee185 Redo false commit. 2017-02-23 20:36:01 +01:00
B. Petersen 92d71ad150 When locking the app, try to clear the screenshot that is shown in the task switcher. 2017-02-23 20:30:15 +01:00
B. Petersen 8824b30c4a Remove unused import. 2017-02-23 16:38:37 +01:00
B. Petersen 741e281a37 Dismiss app when touching the lock-symbol. 2017-02-23 16:37:22 +01:00
B. Petersen 354295ae7a Unify passcode-enter-dialog background. 2017-02-23 15:15:43 +01:00
B. Petersen 09af0640c7 Simplify fingerprint dialog. 2017-02-23 14:50:28 +01:00
B. Petersen 1485eeecf6 Do not use the new AttachmentsContentProvider for pulic URLs as used when attaching local files. 2017-02-23 13:28:31 +01:00
B. Petersen 8b78df6a14 Remove attach size limit. 2017-02-22 23:09:56 +01:00
B. Petersen 686ee6c246 Coloize attachment file name in chat view. 2017-02-22 22:56:32 +01:00
B. Petersen ca8114d9af Simplify and beautify file selector. 2017-02-22 22:33:23 +01:00
B. Petersen b2392c90c2 Use the same colors for the time and for the forward title. 2017-02-22 21:18:51 +01:00
B. Petersen d207fa67e5 Remove unused URL-searching when entering text. 2017-02-22 20:53:13 +01:00
B. Petersen 2e41fe756a Show correct error box when an attachment cannot be opened. 2017-02-22 20:43:05 +01:00
B. Petersen d533ea5c37 Open attachments by using a content provider. 2017-02-22 19:26:18 +01:00
B. Petersen 4365e176d8 Remove dead code. 2017-02-22 17:53:21 +01:00
B. Petersen 486b03e031 Update messenger-backend submodule. 2017-02-22 17:34:15 +01:00
B. Petersen 1dbf08327c Ignore some files. 2017-02-22 16:56:30 +01:00
B. Petersen 0d15bb3544 Add missing file, ignore files marked as .prv (useful for scripts etc.). 2017-02-22 16:18:57 +01:00
B. Petersen e3b48206e9 Remove 'Done'-hint after message deletion; as normally at least one of the selected message is in view when this function is used, there is enough visual feedback (we want the 'Done'-hint only for actions without visual feedback as copy-to-clipboard). 2017-02-22 15:50:25 +01:00
B. Petersen a0e364a50f Show any documents attached (opening still not working). 2017-02-21 23:21:09 +01:00
B. Petersen 0db3fc55c6 Use binary prefix for file sizes. 2017-02-21 22:18:47 +01:00
B. Petersen 95c3fca389 Show some hints on silent actions as copy-to-clipboard or delete-contact. 2017-02-21 21:52:24 +01:00
B. Petersen 68a72fb8fd Typo. 2017-02-21 18:43:15 +01:00
B. Petersen 473410ece2 Change urls to https://getdelta.org . 2017-02-21 18:40:42 +01:00
B. Petersen 4f760a790a Differ betweend music and voice messages. 2017-02-21 17:02:49 +01:00
B. Petersen ad7ee4428f Remove duplicate strings. 2017-02-21 14:28:31 +01:00
B. Petersen 92cf756ad2 Cleanup reply option in ChatMessageCell. 2017-02-20 22:38:24 +01:00
B. Petersen 3d746f08ba Remove unused message object types. 2017-02-20 21:58:25 +01:00
B. Petersen e272459fc9 Use named values for MessageObject.type; wondering how and by whom this was ever usable before. 2017-02-20 21:43:50 +01:00
B. Petersen a793ae52f9 Make file selection dialog usable. 2017-02-20 20:43:18 +01:00
B. Petersen f2349a9bdd Accept vcards shared to us by external apps. Remove unused contact and location code. 2017-02-20 19:12:29 +01:00
B. Petersen 7082798c03 Swap File- and Contact-attach icons. 2017-02-20 14:44:35 +01:00
B. Petersen f4fc5fae2b Cleanup camera preview code. 2017-02-20 13:57:36 +01:00
B. Petersen 5799e43b3a Update Polish. 2017-02-20 11:54:51 +01:00
B. Petersen f929d6cc31 Cleanup SendMessagesHelper.sendMessage__(), fix a crash when trying to send music files. 2017-02-19 13:04:17 +01:00
B. Petersen 9f92efc554 More neutral language when choosing contacts. 2017-02-19 12:14:23 +01:00
B. Petersen 3338b83910 Pimp attach gui. 2017-02-18 23:57:43 +01:00
B. Petersen a4c104431d Show a hint after deletion of a contact. 2017-02-18 22:49:08 +01:00
B. Petersen 31ba521244 Prefer the term 'contact' over 'user', unify usage. 2017-02-18 22:26:16 +01:00
B. Petersen 50dfe15f09 Show a hint if a user is already in a group. 2017-02-18 21:38:04 +01:00
Dr. Tobias Quathamer 4b06d19787 Add item to changelog for v0.1.20 2017-02-18 16:58:27 +01:00
B. Petersen 66d147eb8b Implement sending contact's addresses. 2017-02-17 21:50:31 +01:00
Björn Petersen d2591922a6 Update CHANGELOG.md 2017-02-17 21:14:34 +01:00
B. Petersen bcc6f79373 More options in URL's context menu: Create chat, create user, open externally, copy to clipboard. 2017-02-17 21:03:25 +01:00
B. Petersen 015edd6053 Create a new chat by clicking on email-links. 2017-02-17 19:26:25 +01:00
B. Petersen bec562bfb2 Linkify email-addresses. 2017-02-17 19:08:32 +01:00
B. Petersen 01a7c93771 If an avatar is shown for a message in group layout, make the bubble a little bit smaller. 2017-02-17 17:06:18 +01:00
B. Petersen 502bae625f Cleanup MessageObject. 2017-02-17 16:33:48 +01:00
B. Petersen a34d511922 Update Polish. 2017-02-17 15:50:57 +01:00
B. Petersen e65aa19109 Fix a null-pointer exception when using tablets. 2017-02-17 13:38:23 +01:00
B. Petersen 30585b8de4 More background wallpaper dynamic. 2017-02-16 23:19:09 +01:00
B. Petersen 0bd4234214 Cleanup drawer profile cell. 2017-02-16 22:42:07 +01:00
B. Petersen db4ceb6d68 Prepare release v0.1.20 (we forgot to update the submodule in v0.1.19). 2017-02-16 20:49:29 +01:00
B. Petersen 1612a5d7cd Update messenger-backend submodule. 2017-02-16 20:42:11 +01:00
B. Petersen f60f4539b5 Prepare release v0.1.19 2017-02-16 16:30:38 +01:00
B. Petersen db7c8a9dfc Update changelog. 2017-02-16 15:19:45 +01:00
B. Petersen 9d1f4266c2 Update changelog. 2017-02-15 22:46:07 +01:00
Björn Petersen 0614c4fc32 Update README.md 2017-02-14 19:57:56 +01:00
B. Petersen 58e452b711 Update polish. 2017-02-14 15:26:58 +01:00
Dr. Tobias Quathamer b478696bed Target API level 25 (Nougat 7.1) 2017-02-13 21:19:47 +01:00
B. Petersen f3584d9eaf Update Portuguese. 2017-02-13 20:37:35 +01:00
B. Petersen d9998167f4 Colorize the background image. 2017-02-13 17:59:06 +01:00
Dr. Tobias Quathamer 874e300220 Remove LocaleController calls 2017-02-11 17:48:41 +01:00
Dr. Tobias Quathamer 49e4b90cc3 Remove unused code 2017-02-11 17:42:35 +01:00
Dr. Tobias Quathamer f492f2cd71 Prepare release 0.1.18 2017-02-11 17:23:49 +01:00
Dr. Tobias Quathamer 2800a282ec Update backend to v0.1.18 2017-02-11 17:16:57 +01:00
Dr. Tobias Quathamer 593e93304c Update changelog 2017-02-10 21:43:36 +01:00
Dr. Tobias Quathamer 77b6108ca8 Fix lint warning, use apply() instead of commit().
commit() writes its data to persistent storage immediately,
whereas apply() will handle it in the background.
2017-02-10 21:43:11 +01:00
Dr. Tobias Quathamer 90bf2b6b19 Update changelog 2017-02-10 21:15:05 +01:00
B. Petersen dd91d52df4 Merge branch 'master' of https://github.com/r10s/messenger-android 2017-02-10 21:07:04 +01:00
B. Petersen de29317fa6 Use standard placeholders in local files. 2017-02-10 21:06:54 +01:00
Dr. Tobias Quathamer 44faee6208 Update backend for plural handling 2017-02-10 21:04:45 +01:00
Dr. Tobias Quathamer 41ccf19e58 Fix typo 2017-02-10 21:03:31 +01:00
B. Petersen 05c390980a Support 'plurals'-strings in the backend. 2017-02-10 20:11:02 +01:00
B. Petersen 4446ed0792 Remove unused peer/empty class. 2017-02-10 16:29:58 +01:00
Dr. Tobias Quathamer 11942da0c0 Update changelog 2017-02-10 16:25:24 +01:00
B. Petersen 9a0604a1a8 Update polish translation. 2017-02-10 16:07:11 +01:00
B. Petersen 93ca874e61 Merge branch 'master' of https://github.com/r10s/messenger-android 2017-02-10 15:47:25 +01:00
B. Petersen 9ba21c4346 Colorize settings headlines. 2017-02-10 15:47:08 +01:00
Dr. Tobias Quathamer c0e7798cad Remove class AndroidAuthenticator.
The class is never used and requires the permission USE_CREDENTIALS.
That permission has never been requested, so the code would fail anyway.
2017-02-10 14:40:20 +01:00
Dr. Tobias Quathamer 0aea5a2201 Replace LocaleController 2017-02-10 14:35:27 +01:00
B. Petersen 63873ec1d5 Slightly optimize colors. 2017-02-10 13:58:16 +01:00
B. Petersen 23f269d4b3 Remove complicated and unreliable calculation of shading colors. 2017-02-10 02:01:41 +01:00
B. Petersen 9ebacb23c4 Bold date headlines. 2017-02-10 00:55:38 +01:00
B. Petersen d1e83f46d8 Improve typography, do not mix system font with resource font which looks ugly when not using 'Roboto'. 2017-02-10 00:14:34 +01:00
B. Petersen 5f2dd23a6e Remove unused chat alert and profile search cell. 2017-02-09 22:48:51 +01:00
B. Petersen d29b24e9a6 Cleanup code in the chat activitie's date headlines. 2017-02-09 18:52:01 +01:00
Dr. Tobias Quathamer 4f1415e127 Remove condition which is always true 2017-02-09 14:32:55 +01:00
Dr. Tobias Quathamer c604313c09 Replace LocaleController with android methods 2017-02-09 14:32:08 +01:00
Dr. Tobias Quathamer e6bc14a8de Replace LocaleController with android methods 2017-02-09 14:14:27 +01:00
Dr. Tobias Quathamer 4a5729d371 Remove unneeded translations 2017-02-09 14:06:40 +01:00
Dr. Tobias Quathamer d9ac76a317 Remove custom plural handling from LocaleController 2017-02-09 13:54:39 +01:00
Dr. Tobias Quathamer 867df35d44 Remove unused strings 2017-02-09 11:25:00 +01:00
Dr. Tobias Quathamer e946d61b92 Use android plural handling for 'Times' 2017-02-09 10:30:42 +01:00
Dr. Tobias Quathamer fa2ffbd70f Rewrite more plural handling of 'Days' 2017-02-09 10:03:45 +01:00
Dr. Tobias Quathamer 1123f03134 Use android plural handling for 'Days' 2017-02-09 10:00:09 +01:00
Dr. Tobias Quathamer 49e86d08bf Remove unneeded string 'MuteFor' 2017-02-09 09:50:03 +01:00
Dr. Tobias Quathamer 5f00826e65 Rewrite more plural handling of 'Hours' 2017-02-09 09:48:22 +01:00
Dr. Tobias Quathamer 82382f31f1 Use android plural handling for 'Hours' 2017-02-09 09:37:09 +01:00
Dr. Tobias Quathamer 833cbf7302 Rewrite more plural handling of 'Minutes' 2017-02-09 09:31:53 +01:00
Dr. Tobias Quathamer 4e329adaca Use android plural handling for 'Minutes' 2017-02-08 22:39:31 +01:00
Dr. Tobias Quathamer dbc9e4c3c2 Add German translation 2017-02-08 22:05:33 +01:00
Dr. Tobias Quathamer d9cff40fd5 Remove unneeded translation 'FromChats' 2017-02-08 22:04:20 +01:00
Dr. Tobias Quathamer ef248712d6 Use android plural handling 2017-02-08 22:03:45 +01:00
Dr. Tobias Quathamer 9765ba1bac Remove unneeded plural string 'Stickers' 2017-02-08 19:35:52 +01:00
Dr. Tobias Quathamer afcccaa864 Remove unused class 'StickerSetCell' 2017-02-08 19:34:37 +01:00
Dr. Tobias Quathamer 7caef2ceb9 Remove unneeded plural string 'Photos' 2017-02-08 19:28:25 +01:00
Dr. Tobias Quathamer cb4480ad78 Remove accidentally translated unused strings 2017-02-08 19:27:42 +01:00
Dr. Tobias Quathamer 6388349c16 Remove unneeded tools hints 2017-02-08 19:27:42 +01:00
B. Petersen 73a111aeac Update default wallpaper, get rid of telegram logo there. 2017-02-08 18:15:04 +01:00
Björn Petersen 5869bdc9dd Update CHANGELOG.md 2017-02-08 16:19:39 +01:00
B. Petersen ff7f75abed Add Polish translation file. 2017-02-08 12:13:57 +01:00
B. Petersen 28ac3bd9eb Add Polish translation. 2017-02-08 12:12:33 +01:00
Dr. Tobias Quathamer 49f07874f8 Fix version number in changelog 2017-02-07 22:12:08 +01:00
648 changed files with 4924 additions and 17145 deletions
+3
View File
@@ -6,3 +6,6 @@ obj/
local.properties
*.keystore
libs/
# ignore private scripts and directories, eg. local2github.prv.sh
*.prv*
+51 -3
View File
@@ -1,6 +1,54 @@
# Delta Chat Changelog
## v0.1.16
## v0.1.22
2017-03-22
* Show HTML-only messages
* Show connection errors
* Add options for SSL/TLS and STARTTLS
* Automatic account configuration, if possible
* Recode large videos
* Add Hungarian translation
* Add Korean translation
## v0.1.21
2017-03-10
* Record and send voice messages
* Record and send videos
* Send and play music
* Send contacts and email addresses
* Sending and opening attachments of any type
* Share and open commands for all attachments
* Accept VCards send to us by other apps
* Clickable email addresses
* Update Polish translation
* Fix tablet startup bug
* Close the app when using the lock-app-via-pincode function
* Protect data by using a content provider for sharing
* Try to clear the task switcher's screenshots when locking the app via pincode
* Pimp GUI
## v0.1.20
2017-02-16
* Avoid unwanted downloads of lots of old messages
* Make the "Chats" folder visible if the server hides new folders by default
* Fix a crash when the server returns empty folders
* Update Polish and Portuguese translations
* Use API level 25 (Nougat 7.1) as target
## v0.1.18
2017-02-11
* Add Polish translation
* Use a new default background for chats
* Improve typography by using the system font instead of a custom resource font
* Remove custom plural handling, use Android's routines instead
* Remove unused source code and strings
* More fixes of lint errors and warnings
## v0.1.17
2017-02-07
* Drop two unnecessary permissions: ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION
@@ -12,8 +60,8 @@
## v0.1.16
2017-02-06
* Added French translation
* Fixed some lint errors and warnings
* Add French translation
* Fix some lint errors and warnings
## v0.1.15
2017-01-31
+6 -6
View File
@@ -24,15 +24,15 @@ tasks.withType(JavaCompile) {
}
dependencies {
compile 'com.android.support:support-v4:23.4.0'
compile 'com.android.support:appcompat-v7:25.1.1'
compile 'com.googlecode.mp4parser:isoparser:1.0.6'
compile 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
compile fileTree(dir: "$buildDir/native-libs", include: 'native-libs.jar')
}
android {
compileSdkVersion 23
buildToolsVersion '23.0.3'
compileSdkVersion 25
buildToolsVersion '25.0.2'
useLibrary 'org.apache.http.legacy'
defaultConfig.applicationId = "com.b44t.messenger"
@@ -76,7 +76,7 @@ android {
}
}
defaultConfig.versionCode = 16
defaultConfig.versionCode = 21
sourceSets.main {
jniLibs.srcDir 'libs'
@@ -116,7 +116,7 @@ android {
defaultConfig {
minSdkVersion 14 // 14: Android 4.0 Ice Cream Sandwich 2011 (Telegram default), 21: Android 5.0 Lollipop 2014 (recommended for InstantRun)
targetSdkVersion 23
versionName "0.1.17"
targetSdkVersion 25
versionName "0.1.22" // do NOT forget to increase defaultConfig.versionCode!
}
}
+3 -1
View File
@@ -1611,14 +1611,16 @@ LOCAL_SRC_FILES += \
./messenger-backend/src/mre2ee.c \
./messenger-backend/src/mrimap.c \
./messenger-backend/src/mrjob.c \
./messenger-backend/src/mrlog.c \
./messenger-backend/src/mrloginparam.c \
./messenger-backend/src/mrmailbox.c \
./messenger-backend/src/mrmailbox_configure.c \
./messenger-backend/src/mrmailbox_log.c \
./messenger-backend/src/mrmimeparser.c \
./messenger-backend/src/mrmsg.c \
./messenger-backend/src/mrosnative.c \
./messenger-backend/src/mrparam.c \
./messenger-backend/src/mrpoortext.c \
./messenger-backend/src/mrsaxparser.c \
./messenger-backend/src/mrsimplify.c \
./messenger-backend/src/mrsmtp.c \
./messenger-backend/src/mrsqlite3.c \
+146 -74
View File
@@ -66,45 +66,49 @@ static jstring jstring_new__(JNIEnv* env, const char* a)
}
/* our log handler */
static void s_log_callback_(int type, const char* msg)
{
int prio;
switch( type ) {
case 'd': prio = ANDROID_LOG_DEBUG; break;
case 'i': prio = ANDROID_LOG_INFO; break;
case 'w': prio = ANDROID_LOG_WARN; break;
default: prio = ANDROID_LOG_ERROR; break;
}
__android_log_print(prio, "DeltaChat", "%s\n", msg); /* on problems, add `-llog` to `Android.mk` */
}
/* global stuff */
static JavaVM* s_jvm = NULL;
static jclass s_MrMailbox_class = NULL;
static jmethodID s_MrCallback_methodID = NULL;
static int s_global_init_done = 0;
static void s_init_globals(JNIEnv *env, jclass MrMailbox_class)
{
/* make sure, the intialisation is done only once */
static bool s_global_init_done = 0;
if( s_global_init_done ) { return; }
s_global_init_done = 1;
/* init global callback */
mrlog_set_handler(s_log_callback_);
/* prepare calling back a Java function */
(*env)->GetJavaVM(env, &s_jvm); /* JNIEnv cannot be shared between threads, so we share the JavaVM object */
s_MrMailbox_class = (*env)->NewGlobalRef(env, MrMailbox_class);
s_MrCallback_methodID = (*env)->GetStaticMethodID(env, MrMailbox_class, "MrCallback","(IJJ)J" /*signature as "(param)ret" with I=int, J=long*/ );
}
/* system-specific backend initialisations */
mrosnative_init_android(env); /*this should be called before any other "important" routine is called*/
/* setup threads, only called directly by the backed */
int mrosnative_setup_thread(mrmailbox_t* mailbox)
{
if( s_jvm == NULL ) {
mrmailbox_log_error(mailbox, 0, "Not ready, cannot setup thread.");
return 0;
}
mrmailbox_log_info(mailbox, 0, "Attaching C-thread to Java VM...");
JNIEnv* env = NULL;
(*s_jvm)->AttachCurrentThread(s_jvm, &env, NULL);
mrmailbox_log_info(mailbox, 0, "Attaching ok.");
return 1;
}
void mrosnative_unsetup_thread(mrmailbox_t* mailbox)
{
mrmailbox_log_info(mailbox, 0, "Detaching C-thread from Java VM...");
(*s_jvm)->DetachCurrentThread(s_jvm);
mrmailbox_log_info(mailbox, 0, "Detaching done.");
}
@@ -189,15 +193,22 @@ static uintptr_t s_mailbox_callback_(mrmailbox_t* mailbox, int event, uintptr_t
jlong l;
JNIEnv* env;
if( event==MR_EVENT_INFO || event==MR_EVENT_WARNING ) {
__android_log_print(event==MR_EVENT_INFO? ANDROID_LOG_INFO : ANDROID_LOG_WARN, "DeltaChat", "%s", (char*)data2); /* on problems, add `-llog` to `Android.mk` */
return 0; /* speed up things for info/warning */
}
else if( event == MR_EVENT_ERROR ) {
__android_log_print(ANDROID_LOG_ERROR, "DeltaChat", "%s", (char*)data2);
/* errors are also forwarded to Java to show them in a bubble or so */
}
if( s_jvm==NULL || s_MrMailbox_class==NULL || s_MrCallback_methodID==NULL ) {
s_log_callback_('e', "Callback called but JavaVM not ready.");
return 0;
return 0; /* may happen on startup */
}
(*s_jvm)->GetEnv(s_jvm, &env, JNI_VERSION_1_6); /* as this function may be called from _any_ thread, we cannot use a static pointer to JNIEnv */
if( env==NULL ) {
s_log_callback_('e', "Callback called but cannot get JNIEnv.");
return 0;
return 0; /* may happen on startup */
}
l = (*env)->CallStaticLongMethod(env, s_MrMailbox_class, s_MrCallback_methodID, (jint)event, (jlong)data1, (jlong)data2);
@@ -236,42 +247,33 @@ JNIEXPORT jstring Java_com_b44t_messenger_MrMailbox_getBlobdir(JNIEnv *env, jcla
}
JNIEXPORT jint Java_com_b44t_messenger_MrMailbox_MrMailboxConfigure(JNIEnv *env, jclass c, jlong hMailbox)
JNIEXPORT void Java_com_b44t_messenger_MrMailbox_configureAndConnect(JNIEnv *env, jclass cls)
{
return mrmailbox_configure((mrmailbox_t*)hMailbox);
mrmailbox_configure_and_connect(get_mrmailbox_t(env, cls));
}
JNIEXPORT jint Java_com_b44t_messenger_MrMailbox_MrMailboxIsConfigured(JNIEnv *env, jclass c, jlong hMailbox)
JNIEXPORT void Java_com_b44t_messenger_MrMailbox_configureCancel(JNIEnv *env, jclass cls)
{
return (jint)mrmailbox_is_configured((mrmailbox_t*)hMailbox);
mrmailbox_configure_cancel(get_mrmailbox_t(env, cls));
}
JNIEXPORT jint Java_com_b44t_messenger_MrMailbox_MrMailboxConnect(JNIEnv *env, jclass c, jlong hMailbox)
JNIEXPORT jint Java_com_b44t_messenger_MrMailbox_isConfigured(JNIEnv *env, jclass cls)
{
return mrmailbox_connect((mrmailbox_t*)hMailbox);
return (jint)mrmailbox_is_configured(get_mrmailbox_t(env, cls));
}
JNIEXPORT void Java_com_b44t_messenger_MrMailbox_MrMailboxDisconnect(JNIEnv *env, jclass c, jlong hMailbox)
JNIEXPORT void Java_com_b44t_messenger_MrMailbox_connect(JNIEnv *env, jclass cls)
{
mrmailbox_disconnect((mrmailbox_t*)hMailbox);
mrmailbox_connect(get_mrmailbox_t(env, cls));
}
JNIEXPORT jint Java_com_b44t_messenger_MrMailbox_MrMailboxFetch(JNIEnv *env, jclass c, jlong hMailbox)
JNIEXPORT void Java_com_b44t_messenger_MrMailbox_disconnect(JNIEnv *env, jclass cls)
{
return mrmailbox_fetch((mrmailbox_t*)hMailbox);
}
JNIEXPORT jstring Java_com_b44t_messenger_MrMailbox_getErrorDescr(JNIEnv *env, jclass cls)
{
char* c = mrmailbox_get_error_descr(get_mrmailbox_t(env, cls));
jstring ret = JSTRING_NEW(c);
free(c);
return ret;
mrmailbox_disconnect(get_mrmailbox_t(env, cls));
}
@@ -384,6 +386,12 @@ JNIEXPORT jint Java_com_b44t_messenger_MrMailbox_createGroupChat(JNIEnv *env, jc
}
JNIEXPORT jint Java_com_b44t_messenger_MrMailbox_isContactInChat(JNIEnv *env, jclass cls, jint chat_id, jint contact_id)
{
return (jint)mrmailbox_is_contact_in_chat(get_mrmailbox_t(env, cls), chat_id, contact_id);
}
JNIEXPORT jint Java_com_b44t_messenger_MrMailbox_addContactToChat(JNIEnv *env, jclass cls, jint chat_id, jint contact_id)
{
return (jint)mrmailbox_add_contact_to_chat(get_mrmailbox_t(env, cls), chat_id, contact_id);
@@ -448,22 +456,29 @@ JNIEXPORT void Java_com_b44t_messenger_MrMailbox_forwardMsgs(JNIEnv *env, jclass
/* MrMailbox - handle config */
JNIEXPORT jint Java_com_b44t_messenger_MrMailbox_MrMailboxSetConfig(JNIEnv *env, jclass c, jlong hMailbox, jstring key, jstring value)
JNIEXPORT void Java_com_b44t_messenger_MrMailbox_setConfig(JNIEnv *env, jclass cls, jstring key, jstring value)
{
CHAR_REF(key);
CHAR_REF(value);
jint ret = (jint)mrmailbox_set_config((mrmailbox_t*)hMailbox, keyPtr, valuePtr);
mrmailbox_set_config(get_mrmailbox_t(env, cls), keyPtr, valuePtr);
CHAR_UNREF(key);
CHAR_UNREF(value);
return ret;
}
JNIEXPORT jstring Java_com_b44t_messenger_MrMailbox_MrMailboxGetConfig(JNIEnv *env, jclass c, jlong hMailbox, jstring key, jstring def)
JNIEXPORT void Java_com_b44t_messenger_MrMailbox_setConfigInt(JNIEnv *env, jclass cls, jstring key, jint value)
{
CHAR_REF(key);
mrmailbox_set_config_int(get_mrmailbox_t(env, cls), keyPtr, value);
CHAR_UNREF(key);
}
JNIEXPORT jstring Java_com_b44t_messenger_MrMailbox_getConfig(JNIEnv *env, jclass cls, jstring key, jstring def)
{
CHAR_REF(key);
CHAR_REF(def);
char* temp = mrmailbox_get_config((mrmailbox_t*)hMailbox, keyPtr, defPtr);
char* temp = mrmailbox_get_config(get_mrmailbox_t(env, cls), keyPtr, defPtr);
jstring ret = JSTRING_NEW(temp);
free(temp);
CHAR_UNREF(key);
@@ -472,10 +487,10 @@ JNIEXPORT jstring Java_com_b44t_messenger_MrMailbox_MrMailboxGetConfig(JNIEnv *e
}
JNIEXPORT jint Java_com_b44t_messenger_MrMailbox_MrMailboxGetConfigInt(JNIEnv *env, jclass c, jlong hMailbox, jstring key, jint def)
JNIEXPORT jint Java_com_b44t_messenger_MrMailbox_getConfigInt(JNIEnv *env, jclass cls, jstring key, jint def)
{
CHAR_REF(key);
jint ret = mrmailbox_get_config_int((mrmailbox_t*)hMailbox, keyPtr, def);
jint ret = mrmailbox_get_config_int(get_mrmailbox_t(env, cls), keyPtr, def);
CHAR_UNREF(key);
return ret;
}
@@ -649,20 +664,20 @@ JNIEXPORT jint Java_com_b44t_messenger_MrChat_MrChatSetDraft(JNIEnv *env, jclass
}
JNIEXPORT jint Java_com_b44t_messenger_MrChat_MrChatSendText(JNIEnv *env, jclass c, jlong hChat, jstring text)
JNIEXPORT jint Java_com_b44t_messenger_MrChat_sendText(JNIEnv *env, jclass cls, jstring text)
{
mrmsg_t* msg = mrmsg_new();
msg->m_type = MR_MSG_TEXT;
CHAR_REF(text);
msg->m_text = textPtr? strdup(textPtr) : NULL;
CHAR_UNREF(text);
jint msg_id = mrchat_send_msg((mrchat_t*)hChat, msg);
jint msg_id = mrchat_send_msg(get_mrchat_t(env, cls), msg);
mrmsg_unref(msg);
return msg_id;
}
JNIEXPORT jint Java_com_b44t_messenger_MrChat_MrChatSendMedia(JNIEnv *env, jclass c, jlong hChat, jint type, jstring file, jstring mime, jint w, jint h, jint ms)
JNIEXPORT jint Java_com_b44t_messenger_MrChat_sendMedia(JNIEnv *env, jclass cls, jint type, jstring file, jstring mime, jint w, jint h, jint ms, jstring author, jstring trackname)
{
mrmsg_t* msg = mrmsg_new();
msg->m_type = type;
@@ -676,22 +691,36 @@ JNIEXPORT jint Java_com_b44t_messenger_MrChat_MrChatSendMedia(JNIEnv *env, jclas
mrparam_set_int(msg->m_param, 'w', w);
mrparam_set_int(msg->m_param, 'h', h);
}
if( type == MR_MSG_AUDIO || type == MR_MSG_VIDEO ) {
if( type == MR_MSG_AUDIO || type == MR_MSG_VOICE || type == MR_MSG_VIDEO ) {
mrparam_set_int(msg->m_param, 'd', ms);
}
jint msg_id = mrchat_send_msg((mrchat_t*)hChat, msg);
if( type == MR_MSG_AUDIO ) {
CHAR_REF(author);
mrparam_set(msg->m_param, 'N', authorPtr);
CHAR_UNREF(author);
CHAR_REF(trackname);
mrparam_set(msg->m_param, 'n', tracknamePtr);
CHAR_UNREF(trackname);
}
jint msg_id = mrchat_send_msg(get_mrchat_t(env, cls), msg);
mrmsg_unref(msg);
return msg_id;
}
JNIEXPORT jintArray Java_com_b44t_messenger_MrMailbox_MrMailboxGetChatMedia(JNIEnv *env, jclass c, jlong hMailbox, jint chat_id, jint msg_type, jint or_msg_type)
JNIEXPORT jintArray Java_com_b44t_messenger_MrMailbox_getChatMedia(JNIEnv *env, jclass cls, jint chat_id, jint msg_type, jint or_msg_type)
{
carray* ca = mrmailbox_get_chat_media((mrmailbox_t*)hMailbox, chat_id, msg_type, or_msg_type);
carray* ca = mrmailbox_get_chat_media(get_mrmailbox_t(env, cls), chat_id, msg_type, or_msg_type);
return carray2jintArray_n_carray_free(env, ca);
}
JNIEXPORT jint Java_com_b44t_messenger_MrMailbox_getNextMedia(JNIEnv *env, jclass cls, jint msg_id, jint dir)
{
return mrmailbox_get_next_media(get_mrmailbox_t(env, cls), msg_id, dir);
}
JNIEXPORT jintArray Java_com_b44t_messenger_MrMailbox_getChatMsgs(JNIEnv *env, jclass cls, jint chat_id, jint flags, jint marker1before)
{
carray* ca = mrmailbox_get_chat_msgs(get_mrmailbox_t(env, cls), chat_id, flags, marker1before);
@@ -803,9 +832,9 @@ JNIEXPORT jint Java_com_b44t_messenger_MrMsg_MrMsgGetToId(JNIEnv *env, jclass c,
}
JNIEXPORT jstring Java_com_b44t_messenger_MrMsg_MrMsgGetParam(JNIEnv *env, jclass c, jlong hMsg, jint key, jstring def)
JNIEXPORT jstring Java_com_b44t_messenger_MrMsg_getParam(JNIEnv *env, jobject obj, jint key, jstring def)
{
mrmsg_t* ths = (mrmsg_t*)hMsg;
mrmsg_t* ths = get_mrmsg_t(env, obj);
CHAR_REF(def);
char* temp = mrparam_get(ths? ths->m_param:NULL, key, defPtr);
jstring ret = JSTRING_NEW(temp);
@@ -815,17 +844,38 @@ JNIEXPORT jstring Java_com_b44t_messenger_MrMsg_MrMsgGetParam(JNIEnv *env, jclas
}
JNIEXPORT jint Java_com_b44t_messenger_MrMsg_MrMsgGetParamInt(JNIEnv *env, jclass c, jlong hMsg, jint key, jint def)
JNIEXPORT jint Java_com_b44t_messenger_MrMsg_getParamInt(JNIEnv *env, jobject obj, jint key, jint def)
{
mrmsg_t* ths = (mrmsg_t*)hMsg;
mrmsg_t* ths = get_mrmsg_t(env, obj);
return mrparam_get_int(ths? ths->m_param:NULL, key, def);
}
JNIEXPORT void Java_com_b44t_messenger_MrMsg_setParamInt(JNIEnv *env, jobject obj, jint key, jint value)
{
mrmsg_t* ths = get_mrmsg_t(env, obj);
mrparam_set_int(ths? ths->m_param:NULL, key, value);
}
JNIEXPORT void Java_com_b44t_messenger_MrMsg_saveParamToDisk(JNIEnv *env, jobject obj)
{
mrmsg_save_param_to_disk(get_mrmsg_t(env, obj));
}
JNIEXPORT jint Java_com_b44t_messenger_MrMsg_getBytes(JNIEnv *env, jobject obj)
{
jint ret = 0;
mrmsg_t* ths = get_mrmsg_t(env, obj);
return ths? ths->m_bytes : 0;
if( ths ) {
const char* file = mrparam_get(ths->m_param, 'f', NULL);
if( file ) {
ret = mr_get_filebytes(file);
free(file);
}
}
return ret;
}
@@ -841,6 +891,24 @@ JNIEXPORT jint Java_com_b44t_messenger_MrMsg_getSummarytext(JNIEnv *env, jobject
}
JNIEXPORT jint Java_com_b44t_messenger_MrMsg_getFilename(JNIEnv *env, jobject obj)
{
return JSTRING_NEW(mrmsg_get_filename(get_mrmsg_t(env, obj)));
}
JNIEXPORT jlong Java_com_b44t_messenger_MrMsg_getMediainfoCPtr(JNIEnv *env, jobject obj)
{
return (jlong)mrmsg_get_mediainfo(get_mrmsg_t(env, obj));
}
JNIEXPORT jint Java_com_b44t_messenger_MrMsg_isIncreation(JNIEnv *env, jobject obj)
{
return (jint)mrmsg_is_increation(get_mrmsg_t(env, obj));
}
/*******************************************************************************
* MrContact
******************************************************************************/
@@ -884,24 +952,24 @@ JNIEXPORT void Java_com_b44t_messenger_MrPoortext_MrPoortextUnref(JNIEnv *env, j
}
JNIEXPORT jstring Java_com_b44t_messenger_MrPoortext_MrPoortextGetTitle(JNIEnv *env, jclass c, jlong hPoortext)
JNIEXPORT jstring Java_com_b44t_messenger_MrPoortext_MrPoortextGetText1(JNIEnv *env, jclass c, jlong hPoortext)
{
mrpoortext_t* ths = (mrpoortext_t*)hPoortext; if( ths == NULL ) { return JSTRING_NEW(NULL); }
return JSTRING_NEW(ths->m_title);
return JSTRING_NEW(ths->m_text1);
}
JNIEXPORT jint Java_com_b44t_messenger_MrPoortext_MrPoortextGetTitleMeaning(JNIEnv *env, jclass c, jlong hPoortext)
JNIEXPORT jint Java_com_b44t_messenger_MrPoortext_MrPoortextGetText1Meaning(JNIEnv *env, jclass c, jlong hPoortext)
{
mrpoortext_t* ths = (mrpoortext_t*)hPoortext; if( ths == NULL ) { return 0; }
return ths->m_title_meaning;
return ths->m_text1_meaning;
}
JNIEXPORT jstring Java_com_b44t_messenger_MrPoortext_MrPoortextGetText(JNIEnv *env, jclass c, jlong hPoortext)
JNIEXPORT jstring Java_com_b44t_messenger_MrPoortext_MrPoortextGetText2(JNIEnv *env, jclass c, jlong hPoortext)
{
mrpoortext_t* ths = (mrpoortext_t*)hPoortext; if( ths == NULL ) { return JSTRING_NEW(NULL); }
return JSTRING_NEW(ths->m_text);
return JSTRING_NEW(ths->m_text2);
}
@@ -935,11 +1003,15 @@ JNIEXPORT jstring Java_com_b44t_messenger_MrMailbox_CPtr2String(JNIEnv *env, jcl
}
JNIEXPORT void Java_com_b44t_messenger_MrMailbox_MrStockAddStr(JNIEnv* env, jclass c, jint id, jstring str)
JNIEXPORT jlong Java_com_b44t_messenger_MrMailbox_String2CPtr(JNIEnv *env, jclass c, jstring str)
{
CHAR_REF(str);
mrstock_add_str(id, strPtr);
CHAR_UNREF(str)
char* hStr = NULL;
if( str ) {
CHAR_REF(str);
hStr = strdup(strPtr);
CHAR_UNREF(str);
}
return (jlong)hStr;
}
+28 -17
View File
@@ -20,28 +20,28 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- we need it eg. for getActiveNetworkInfo() -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<!-- <uses-permission android:name="android.permission.GET_ACCOUNTS" /> - required for AccountManager -->
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS"/>
<uses-permission android:name="android.permission.READ_PROFILE"/>
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS"/>
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS"/>
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"/>
<!-- <uses-permission android:name="android.permission.WRITE_CONTACTS" /> -->
<!-- <uses-permission android:name="android.permission.MANAGE_ACCOUNTS"/> - required for AccountManager in API level <= 22 -->
<!-- <uses-permission android:name="android.permission.READ_PROFILE"/> - required for ContactsContract.Profile -->
<!-- <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS"/> required for AbstractThreadedSyncAdapter-->
<!-- <uses-permission android:name="android.permission.READ_SYNC_SETTINGS"/> - required for AbstractThreadedSyncAdapter -->
<!-- <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"/> - seems to be unneeded and is no longer supported by Android, was needed for AbstractAccountAuthenticator, see http://stackoverflow.com/questions/32601456/marshmallow-permission-implementation#36907308 -->
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> - required for windows using the TYPE_SYSTEM_ALERT flag -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!-- we need the TelephonyManager to pause the audio player on calls -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
<uses-permission android:name="android.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"/>
<!--<uses-permission android:name="android.permission.CAMERA" />-->
<!-- <uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" /> - required for AndroidUtilities.uninstallShortcut() -->
<!-- <uses-permission android:name="android.permission.CAMERA" /> - also disabled in T'gram; we're using the camera via an intent only -->
<application
android:name=".ApplicationLoader"
@@ -114,7 +114,7 @@
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="tg" />
</intent-filter> -->
<meta-data android:name="android.service.chooser.chooser_target_service" android:value=".TgChooserTargetService" />
<!-- see note below, <meta-data android:name="android.service.chooser.chooser_target_service" android:value=".TgChooserTargetService" /> -->
</activity>
<activity
android:name="com.b44t.ui.ManageSpaceActivity"
@@ -157,6 +157,7 @@
</receiver>
-->
<!-- currently, we do not use the android account system
<service android:name=".AuthenticatorService" android:exported="true">
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator"/>
@@ -164,7 +165,9 @@
<meta-data android:name="android.accounts.AccountAuthenticator"
android:resource="@xml/auth"/>
</service>
-->
<!-- seems to be not needed, derived from AbstractThreadedSyncAdapter, would need the READ/WRITE_SYNC_SETTINGS
<service android:name=".ContactsSyncAdapterService" android:exported="true">
<intent-filter>
<action android:name="android.content.SyncAdapter" />
@@ -174,7 +177,11 @@
<meta-data android:name="android.provider.CONTACTS_STRUCTURE"
android:resource="@xml/contacts" />
</service>
-->
<!-- this would implement the "direct share" functionality (the system shows some direct links eg.
to the most recent chats when calling "share" from another app, see https://developer.android.com/reference/android/service/chooser/ChooserTargetService.html )
however, if we want this feature, we have to reimplement TgChooserTargetService or sth. like that.
<service
android:name="com.b44t.messenger.TgChooserTargetService"
android:label="@string/AppName"
@@ -182,18 +189,18 @@
<intent-filter>
<action android:name="android.service.chooser.ChooserTargetService" />
</intent-filter>
</service>
</service> -->
<service android:name=".NotificationsService" android:enabled="true"/>
<service android:name=".NotificationRepeat" android:exported="false"/>
<service android:name=".ClearCacheService" android:exported="false"/>
<service android:name=".VideoEncodingService" android:enabled="true"/>
<service android:name=".MusicPlayerService" android:exported="true" android:enabled="true"/>
<!-- Do not expose data through MediaBrowserService, this seems unexpected for an messenger.
Instead, the user can use 'save to music' or 'share' explicitly for items not privacy related.
<service android:name=".MusicBrowserService" android:exported="true">
<intent-filter>
<action android:name="android.media.browse.MediaBrowserService"/>
</intent-filter>
</service>
</service> -->
<receiver android:name=".MusicPlayerReceiver" >
<intent-filter>
@@ -217,10 +224,14 @@
<receiver android:name=".WearReplyReceiver" android:enabled="true"/>
<!-- <receiver android:name=".NetworkAlarm" android:enabled="true"/> -->
<!-- seems to be unneeded (bp)
<receiver android:name=".ShareBroadcastReceiver" android:enabled="true"/>
-->
<receiver android:name=".NotificationDismissReceiver" android:exported="false"/>
<provider android:name=".AttachmentsContentProvider" android:authorities="${applicationId}.attachments" android:exported="true" />
<uses-library android:name="com.sec.android.app.multiwindow" android:required="false" />
<meta-data android:name="com.sec.android.support.multiwindow" android:value="true" />
<meta-data android:name="com.sec.android.multiwindow.DEFAULT_SIZE_W" android:value="632dp" />
Binary file not shown.
@@ -22,33 +22,25 @@
package com.b44t.messenger;
import android.Manifest;
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.DownloadManager;
import android.content.ContentUris;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
@@ -70,10 +62,9 @@ import android.widget.AbsListView;
import android.widget.EdgeEffect;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.b44t.ui.ActionBar.BaseFragment;
import com.b44t.ui.Components.ForegroundDetector;
import com.b44t.ui.Components.TypefaceSpan;
@@ -86,6 +77,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.channels.FileChannel;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
@@ -95,7 +87,6 @@ import java.util.regex.Pattern;
public class AndroidUtilities {
private static final Hashtable<String, Typeface> typefaceCache = new Hashtable<>();
private static int prevOrientation = -10;
public static int statusBarHeight = 0;
@@ -108,7 +99,6 @@ public class AndroidUtilities {
private static Boolean isTablet = null;
private static int adjustOwnerClassGuid = 0;
public static Pattern WEB_URL = null;
static {
try {
final String GOOD_IRI_CHAR = "a-zA-Z0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF";
@@ -122,15 +112,6 @@ public class AndroidUtilities {
final String GTLD = "[" + GOOD_GTLD_CHAR + "]{2,63}";
final String HOST_NAME = "(" + IRI + "\\.)+" + GTLD;
final Pattern DOMAIN_NAME = Pattern.compile("(" + HOST_NAME + "|" + IP_ADDRESS + ")");
WEB_URL = Pattern.compile(
"((?:(http|https|Http|Https):\\/\\/(?:(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)"
+ "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_"
+ "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@)?)?"
+ "(?:" + DOMAIN_NAME + ")"
+ "(?:\\:\\d{1,5})?)" // plus option port number
+ "(\\/(?:(?:[" + GOOD_IRI_CHAR + "\\;\\/\\?\\:\\@\\&\\=\\#\\~" // plus option query params
+ "\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])|(?:\\%[a-fA-F0-9]{2}))*)?"
+ "(?:\\b|$)");
} catch (Exception e) {
FileLog.e("messenger", e);
}
@@ -142,101 +123,6 @@ public class AndroidUtilities {
checkDisplaySize();
}
public static int[] calcDrawableColor(Drawable drawable) {
int bitmapColor = 0xff000000;
int result[] = new int[2];
try {
if (drawable instanceof BitmapDrawable) {
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
if (bitmap != null) {
Bitmap b = Bitmaps.createScaledBitmap(bitmap, 1, 1, true);
if (b != null) {
bitmapColor = b.getPixel(0, 0);
b.recycle();
}
}
} else if (drawable instanceof ColorDrawable) {
bitmapColor = ((ColorDrawable) drawable).getColor();
}
} catch (Exception e) {
FileLog.e("messenger", e);
}
double[] hsv = rgbToHsv((bitmapColor >> 16) & 0xff, (bitmapColor >> 8) & 0xff, bitmapColor & 0xff);
hsv[1] = Math.min(1.0, hsv[1] + 0.05 + 0.1 * (1.0 - hsv[1]));
hsv[2] = Math.max(0, hsv[2] * 0.65);
int rgb[] = hsvToRgb(hsv[0], hsv[1], hsv[2]);
result[0] = Color.argb(0x66, rgb[0], rgb[1], rgb[2]);
result[1] = Color.argb(0x88, rgb[0], rgb[1], rgb[2]);
return result;
}
private static double[] rgbToHsv(int r, int g, int b) {
double rf = r / 255.0;
double gf = g / 255.0;
double bf = b / 255.0;
double max = (rf > gf && rf > bf) ? rf : (gf > bf) ? gf : bf;
double min = (rf < gf && rf < bf) ? rf : (gf < bf) ? gf : bf;
double h, s;
double d = max - min;
s = max == 0 ? 0 : d / max;
if (max == min) {
h = 0;
} else {
if (rf > gf && rf > bf) {
h = (gf - bf) / d + (gf < bf ? 6 : 0);
} else if (gf > bf) {
h = (bf - rf) / d + 2;
} else {
h = (rf - gf) / d + 4;
}
h /= 6;
}
return new double[]{h, s, max};
}
private static int[] hsvToRgb(double h, double s, double v) {
double r = 0, g = 0, b = 0;
double i = (int) Math.floor(h * 6);
double f = h * 6 - i;
double p = v * (1 - s);
double q = v * (1 - f * s);
double t = v * (1 - (1 - f) * s);
switch ((int) i % 6) {
case 0:
r = v;
g = t;
b = p;
break;
case 1:
r = q;
g = v;
b = p;
break;
case 2:
r = p;
g = v;
b = t;
break;
case 3:
r = p;
g = q;
b = v;
break;
case 4:
r = t;
g = p;
b = v;
break;
case 5:
r = v;
g = p;
b = q;
break;
}
return new int[]{(int) (r * 255), (int) (g * 255), (int) (b * 255)};
}
public static void requestAdjustResize(Activity activity, int classGuid) {
if (activity == null || isTablet()) {
return;
@@ -325,21 +211,6 @@ public class AndroidUtilities {
}
}
public static Typeface getTypeface(String assetPath) {
synchronized (typefaceCache) {
if (!typefaceCache.containsKey(assetPath)) {
try {
Typeface t = Typeface.createFromAsset(ApplicationLoader.applicationContext.getAssets(), assetPath);
typefaceCache.put(assetPath, t);
} catch (Exception e) {
FileLog.e("Typefaces", "Could not get typeface '" + assetPath + "' because " + e.getMessage());
return null;
}
}
return typefaceCache.get(assetPath);
}
}
public static void showKeyboard(View view) {
if (view == null) {
return;
@@ -352,19 +223,6 @@ public class AndroidUtilities {
}
}
public static boolean isKeyboardShowed(View view) {
if (view == null) {
return false;
}
try {
InputMethodManager inputManager = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
return inputManager.isActive(view);
} catch (Exception e) {
FileLog.e("messenger", e);
}
return false;
}
public static void hideKeyboard(View view) {
if (view == null) {
return;
@@ -526,19 +384,6 @@ public class AndroidUtilities {
}
}
public static void setProgressBarAnimationDuration(ProgressBar progressBar, int duration) {
if (progressBar == null) {
return;
}
try {
Field mCursorDrawableRes = ProgressBar.class.getDeclaredField("mDuration");
mCursorDrawableRes.setAccessible(true);
mCursorDrawableRes.setInt(progressBar, duration);
} catch (Exception e) {
FileLog.e("messenger", e);
}
}
private static Intent createShortcutIntent(int did, Bitmap bitmap) {
Intent shortcutIntent = new Intent(ApplicationLoader.applicationContext, OpenChatReceiver.class);
@@ -569,6 +414,9 @@ public class AndroidUtilities {
}
}
/* -- uninstalling shortcuts would be needed if a chat is deleted. However,
-- com.b44t.messenger.openchatNNN just opens the overview in this case, which is okay for the moment.
-- uninstalling shortcuts would required the permission com.android.launcher.permission.UNINSTALL_SHORTCUT
public static void uninstallShortcut(int did) {
try {
Intent addIntent = createShortcutIntent(did, null);
@@ -577,7 +425,7 @@ public class AndroidUtilities {
} catch (Exception e) {
FileLog.e("messenger", e);
}
}
}*/
public static int getViewInset(View view) {
if (view == null || Build.VERSION.SDK_INT < 21 || view.getHeight() == AndroidUtilities.displaySize.y || view.getHeight() == AndroidUtilities.displaySize.y - statusBarHeight) {
@@ -727,7 +575,7 @@ public class AndroidUtilities {
}
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(stringBuilder);
for (int a = 0; a < bolds.size() / 2; a++) {
spannableStringBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf")), bolds.get(a * 2), bolds.get(a * 2 + 1), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableStringBuilder.setSpan(new TypefaceSpan(Typeface.DEFAULT_BOLD), bolds.get(a * 2), bolds.get(a * 2 + 1), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
for (int a = 0; a < colors.size() / 3; a++) {
spannableStringBuilder.setSpan(new ForegroundColorSpan(colors.get(a * 3 + 2)), colors.get(a * 3), colors.get(a * 3 + 1), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
@@ -765,6 +613,26 @@ public class AndroidUtilities {
animatorSet.start();
}
public static void showDoneHint(Context context)
{
// this hint should be shown when an action is complete and not directly visible on the screen,
// eg. copy-to-clipboard or item deletion in a long list
Toast.makeText(context, ApplicationLoader.applicationContext.getString(R.string.DoneHint), Toast.LENGTH_SHORT).show();
}
public static void showErrorHint(Context context)
{
// this hint should be shown on errors that normally should not happen.
showHint(context, ApplicationLoader.applicationContext.getString(R.string.ErrorHint));
}
public static Toast showHint(Context context, String text)
{
Toast t = Toast.makeText(context, text, Toast.LENGTH_LONG);
t.show();
return t;
}
public static void addToClipboard(CharSequence str) {
try {
android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE);
@@ -920,49 +788,6 @@ public class AndroidUtilities {
return null;
}
public static CharSequence generateSearchName(String name, String name2, String q) {
if (name == null && name2 == null) {
return "";
}
SpannableStringBuilder builder = new SpannableStringBuilder();
String wholeString = name;
if (wholeString == null || wholeString.length() == 0) {
wholeString = name2;
} else if (name2 != null && name2.length() != 0) {
wholeString += " " + name2;
}
wholeString = wholeString.trim();
String lower = " " + wholeString.toLowerCase();
int index;
int lastIndex = 0;
while ((index = lower.indexOf(" " + q, lastIndex)) != -1) {
int idx = index - (index == 0 ? 0 : 1);
int end = q.length() + (index == 0 ? 0 : 1) + idx;
if (lastIndex != 0 && lastIndex != idx + 1) {
builder.append(wholeString.substring(lastIndex, idx));
} else if (lastIndex == 0 && idx != 0) {
builder.append(wholeString.substring(0, idx));
}
String query = wholeString.substring(idx, end);
if (query.startsWith(" ")) {
builder.append(" ");
}
query = query.trim();
builder.append(AndroidUtilities.replaceTags("<c#ff4d83b3>" + query + "</c>"));
lastIndex = end;
}
if (lastIndex != -1 && lastIndex != wholeString.length()) {
builder.append(wholeString.substring(lastIndex, wholeString.length()));
}
return builder;
}
public static File generateVideoPath() {
try {
File storageDir = getAlbumDir();
@@ -974,15 +799,15 @@ public class AndroidUtilities {
return null;
}
public static String formatFileSize(long size) {
if (size < 1024) {
return String.format("%d B", size);
} else if (size < 1024 * 1024) {
return String.format("%.1f KB", size / 1024.0f);
} else if (size < 1024 * 1024 * 1024) {
return String.format("%.1f MB", size / 1024.0f / 1024.0f);
public static String formatFileSize(long bytes) {
// We use the SI-prefix with the usual base as defined in the 1990's.
// The other option would be to show MiB and KiB, however, these abbreviations are not very usual.
if (bytes < 1000) {
return String.format("%d Byte", bytes);
} else if (bytes < (1000 * 1000)-500) { // 999499 Byte=999 KB, 999500 Byte=1,0 MB
return String.format("%.0f KB", bytes / 1000.0f);
} else {
return String.format("%.1f GB", size / 1024.0f / 1024.0f / 1024.0f);
return String.format("%.1f MB", bytes / 1000.0f / 1000.0f);
}
}
@@ -1051,56 +876,186 @@ public class AndroidUtilities {
return true;
}
public static byte[] calcAuthKeyHash(byte[] auth_key) {
byte[] sha1 = Utilities.computeSHA1(auth_key);
byte[] key_hash = new byte[16];
System.arraycopy(sha1, 0, key_hash, 0, 16);
return key_hash;
}
/* open, view, download files
**********************************************************************************************/
public static void openForView(MessageObject message, Activity activity) throws Exception {
File f = null;
String fileName = message.getFileName();
if (message.messageOwner.attachPath != null && message.messageOwner.attachPath.length() != 0) {
f = new File(message.messageOwner.attachPath);
}
if (f == null || !f.exists()) {
f = FileLoader.getPathToMessage(message.messageOwner);
}
if (f != null && f.exists()) {
String realMimeType = null;
Intent intent = new Intent(Intent.ACTION_VIEW);
MimeTypeMap myMime = MimeTypeMap.getSingleton();
public static String getMimetype(String fileName, String def)
{
String mimeType = "application/octet-stream";
try {
MimeTypeMap mimeMap = MimeTypeMap.getSingleton();
int idx = fileName.lastIndexOf('.');
if (idx != -1) {
String ext = fileName.substring(idx + 1);
realMimeType = myMime.getMimeTypeFromExtension(ext.toLowerCase());
if (realMimeType == null) {
if (message.type == 9 || message.type == 0) {
realMimeType = message.getDocument().mime_type;
}
if (realMimeType == null || realMimeType.length() == 0) {
realMimeType = null;
}
}
if (realMimeType != null) {
intent.setDataAndType(Uri.fromFile(f), realMimeType);
} else {
intent.setDataAndType(Uri.fromFile(f), "text/plain");
}
} else {
intent.setDataAndType(Uri.fromFile(f), "text/plain");
mimeType = mimeMap.getMimeTypeFromExtension(ext.toLowerCase());
}
if (realMimeType != null) {
try {
activity.startActivityForResult(intent, 500);
} catch (Exception e) {
intent.setDataAndType(Uri.fromFile(f), "text/plain");
activity.startActivityForResult(intent, 500);
}
} else {
activity.startActivityForResult(intent, 500);
if (mimeType == null) {
mimeType = def==null? "application/octet-stream" : def;
}
}
catch(Exception e) {
}
return mimeType;
}
public static void openForViewOrShare(Activity activity, int msg_id, String cmd)
{
MrMsg msg = MrMailbox.getMsg(msg_id);
String path = msg.getParam('f', "");
String mimeType = getMimetype(path, msg.getParam('m', "application/octet-stream"));
try {
File file = new File(path);
if( !file.exists() ) {
showHint(activity, LocaleController.formatString("FileNotFound", R.string.FileNotFound, path));
return;
}
Uri uri;
if (path.startsWith(MrMailbox.getBlobdir())) {
uri = Uri.parse("content://" + BuildConfig.APPLICATION_ID + ".attachments/" + file.getName());
} else {
uri = Uri.fromFile(file);
}
if( cmd == Intent.ACTION_VIEW ) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, mimeType);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
activity.startActivity(intent);
}
else {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType(mimeType);
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
activity.startActivity(Intent.createChooser(intent, ApplicationLoader.applicationContext.getString(R.string.Share)));
}
}
catch (Exception e) {
showHint(activity, LocaleController.formatString("NoHandleAppInstalled", R.string.NoHandleAppInstalled, mimeType));
}
}
public static File getFineFilename(File path, String desiredName)
{
// get a fine file name by adding a number to the basename and avoid overwrites
for( int i = 0; i < 1000; i++ ) {
String testName = desiredName;
if( i > 0 ) {
String baseName=desiredName, ext = "";
int idx = desiredName.lastIndexOf('.');
if( idx != -1 ) {
baseName = desiredName.substring(0, idx);
ext = desiredName.substring(idx);
}
testName = String.format("%s-%d%s", baseName, i, ext);
}
File pathNFile = new File(path, testName);
if (!pathNFile.exists()) {
return pathNFile;
}
}
return null;
}
public static void saveMessageFileToExt(final Activity context, int msg_id)
{
if (Build.VERSION.SDK_INT >= 23 && context.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
context.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 4);
return;
}
MrMsg msg = MrMailbox.getMsg(msg_id);
final int msg_type = msg.getType();
String msg_file_path = msg.getParam('f', "");
final String msg_mime = msg.getParam('m', "application/octet-stream");
final String msg_file_name = msg.getFilename();
final File sourceFile = new File(msg_file_path);
if( !sourceFile.exists() ) {
showHint(context, LocaleController.formatString("FileNotFound", R.string.FileNotFound, msg_file_path));
return;
}
final Toast waitingHint = showHint(context, ApplicationLoader.applicationContext.getString(R.string.OneMoment));
new Thread(new Runnable() {
@Override
public void run() {
boolean allOkay = false;
try {
// get destination path
File destPath = null;
boolean add_to_download_manager = false;
if (msg_type == MrMsg.MR_MSG_IMAGE || msg_type == MrMsg.MR_MSG_VIDEO) {
destPath = AndroidUtilities.getAlbumDir();
} else if (msg_type == MrMsg.MR_MSG_FILE) {
destPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
add_to_download_manager = true;
} else if (msg_type == MrMsg.MR_MSG_AUDIO || msg_type == MrMsg.MR_MSG_VOICE ) {
destPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);
}
// create destination path (must be done, see documentation for getExternalStoragePublicDirectory())
destPath.mkdirs();
File destPathNFile = getFineFilename(destPath, msg_file_name);
if( destPathNFile != null )
{
destPathNFile.createNewFile();
boolean copied = true;
FileChannel source = null;
FileChannel destination = null;
try {
source = new FileInputStream(sourceFile).getChannel();
destination = new FileOutputStream(destPathNFile).getChannel();
long size = source.size();
for (long a = 0; a < size; a += 4096) {
destination.transferFrom(source, a, Math.min(4096, size - a));
}
} catch (Exception e) {
copied = false;
} finally {
if (source != null) {
source.close();
}
if (destination != null) {
destination.close();
}
}
if (copied) {
if ( add_to_download_manager ) {
DownloadManager downloadManager = (DownloadManager) ApplicationLoader.applicationContext.getSystemService(Context.DOWNLOAD_SERVICE);
downloadManager.addCompletedDownload(destPathNFile.getName(), destPathNFile.getName(), false, getMimetype(msg_file_name, msg_mime), destPathNFile.getAbsolutePath(), destPathNFile.length(), true);
} else {
addMediaToGallery(Uri.fromFile(destPathNFile));
}
allOkay = true;
}
}
}
catch (Exception e) {
;
}
final boolean allOkayFinal = allOkay;
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
waitingHint.cancel();
if( allOkayFinal ) {
showDoneHint(context);
}
else {
showHint(context, ApplicationLoader.applicationContext.getString(R.string.AccessError));
}
}
});
}
}).start();
}
}
@@ -53,9 +53,6 @@ public class ApplicationLoader extends Application {
private static boolean isCustomTheme;
private static final Object sync = new Object();
private static int serviceMessageColor;
private static int serviceSelectedMessageColor;
public static volatile Context applicationContext;
public static volatile Handler applicationHandler;
private static volatile boolean applicationInited = false;
@@ -73,25 +70,11 @@ public class ApplicationLoader extends Application {
public static void reloadWallpaper() {
cachedWallpaper = null;
serviceMessageColor = 0;
ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE).edit().remove("serviceMessageColor").commit();
loadWallpaper();
}
private static void calcBackgroundColor() {
int result[] = AndroidUtilities.calcDrawableColor(cachedWallpaper);
serviceMessageColor = result[0];
serviceSelectedMessageColor = result[1];
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
preferences.edit().putInt("serviceMessageColor", serviceMessageColor).putInt("serviceSelectedMessageColor", serviceSelectedMessageColor).commit();
}
public static int getServiceMessageColor() {
return serviceMessageColor;
}
public static int getServiceSelectedMessageColor() {
return serviceSelectedMessageColor;
return 0x44000000; // this color is used as a background for date headlines, empty chat hints and in the drawer
}
public static void loadWallpaper() {
@@ -107,8 +90,6 @@ public class ApplicationLoader extends Application {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
int selectedBackground = preferences.getInt("selectedBackground", 1000001);
selectedColor = preferences.getInt("selectedColor", 0);
serviceMessageColor = preferences.getInt("serviceMessageColor", 0);
serviceSelectedMessageColor = preferences.getInt("serviceSelectedMessageColor", 0);
if (selectedColor == 0) {
if (selectedBackground == 1000001) {
cachedWallpaper = applicationContext.getResources().getDrawable(R.drawable.background_hd);
@@ -133,9 +114,6 @@ public class ApplicationLoader extends Application {
}
cachedWallpaper = new ColorDrawable(selectedColor);
}
if (serviceMessageColor == 0) {
calcBackgroundColor();
}
}
}
});
@@ -198,26 +176,20 @@ public class ApplicationLoader extends Application {
UserConfig.loadConfig();
String deviceModel;
String langCode;
String appVersion;
String systemVersion;
String configPath = getFilesDirFixed().toString();
try {
langCode = LocaleController.getLocaleStringIso639();
deviceModel = Build.MANUFACTURER + Build.MODEL;
PackageInfo pInfo = ApplicationLoader.applicationContext.getPackageManager().getPackageInfo(ApplicationLoader.applicationContext.getPackageName(), 0);
appVersion = pInfo.versionName + " (" + pInfo.versionCode + ")";
systemVersion = "SDK " + Build.VERSION.SDK_INT;
} catch (Exception e) {
langCode = "en";
deviceModel = "Android unknown";
appVersion = "App version unknown";
systemVersion = "SDK " + Build.VERSION.SDK_INT;
}
if (langCode.trim().length() == 0) {
langCode = "en";
}
if (deviceModel.trim().length() == 0) {
deviceModel = "Android unknown";
}
@@ -235,7 +207,7 @@ public class ApplicationLoader extends Application {
// make sure, the notifications for the "deaddrop" dialog are muted by default
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("notify2_"+MrChat.MR_CHAT_ID_DEADDROP, 2);
editor.commit();
editor.apply();
}
// open() sqlite file (you can inspect the file eg. with "Tools / Android Device Monitor / File Explorer")
@@ -246,7 +218,7 @@ public class ApplicationLoader extends Application {
// create other default objects
MessagesController.getInstance();
ConnectionsManager.getInstance().init(deviceModel, systemVersion, appVersion, langCode, configPath, FileLog.getNetworkLogPath(), UserConfig.getClientUserId(), enablePushConnection);
ConnectionsManager.getInstance().init();
if (UserConfig.getCurrentUser() != null) {
SendMessagesHelper.getInstance().checkUnsentMessages();
}
@@ -266,7 +238,6 @@ public class ApplicationLoader extends Application {
// however, we may want to to have a look at onPause() eg. of activities (eg. for flushing data, if needed)
MrMailbox.MrCallback(0, 0, 0); // do not remove this call; this makes sure, the function is not removed from build or warnings are printed!
MrMailbox.init();
MrMailbox.initStockStrings();
applicationHandler = new Handler(applicationContext.getMainLooper());
@@ -0,0 +1,85 @@
/*******************************************************************************
*
* Messenger Android Frontend
* (C) 2017 Björn Petersen
* Contact: r10s@b44t.com, http://b44t.com
*
* This program 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.
*
* This program 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
* this program. If not, see http://www.gnu.org/licenses/ .
*
******************************************************************************/
package com.b44t.messenger;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import java.io.File;
import java.io.FileNotFoundException;
public class AttachmentsContentProvider extends ContentProvider {
/* We save all attachments in our private files-directory
that cannot be read by other apps.
So starting, when starting an Intent for viewing (eg. openForView()), we cannot use the paths.
Instead, we give a content://-url that results in calls to this class.
(An alternative would be to copy files to view to a public directory, however, this would
lead to duplicate data.
Another alterntive would be to write all attachments to a public directory, however, this
may lead to security problems as files are system-wide-readable and would also cause problems
if the user or another app deletes these files) */
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
File privateFile = new File(MrMailbox.getBlobdir(), uri.getPath());
return ParcelFileDescriptor.open(privateFile, ParcelFileDescriptor.MODE_READ_ONLY);
}
@Override
public int delete(Uri arg0, String arg1, String[] arg2) {
return 0;
}
@Override
public String getType(Uri arg0) {
return null;
}
@Override
public Uri insert(Uri arg0, ContentValues arg1) {
return null;
}
@Override
public boolean onCreate() {
return false;
}
@Override
public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3,
String arg4) {
return null;
}
@Override
public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) {
return 0;
}
}
@@ -1,112 +0,0 @@
/*******************************************************************************
*
* Messenger Android Frontend
* (C) 2013-2016 Nikolai Kudashov
* (C) 2017 Björn Petersen
* Contact: r10s@b44t.com, http://b44t.com
*
* This program 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.
*
* This program 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
* this program. If not, see http://www.gnu.org/licenses/ .
*
******************************************************************************/
package com.b44t.messenger;
import android.accounts.AbstractAccountAuthenticator;
import android.accounts.Account;
import android.accounts.AccountAuthenticatorResponse;
import android.accounts.AccountManager;
import android.accounts.NetworkErrorException;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
public class AuthenticatorService extends Service {
private static class Authenticator extends AbstractAccountAuthenticator {
private final Context context;
public Authenticator(Context context) {
super(context);
this.context = context;
}
@Override
public Bundle addAccount(AccountAuthenticatorResponse response, String accountType, String authTokenType, String[] requiredFeatures, Bundle options)
throws NetworkErrorException {
return null;
}
@Override
public Bundle getAccountRemovalAllowed(AccountAuthenticatorResponse response, Account account) throws NetworkErrorException {
return super.getAccountRemovalAllowed(response, account);
}
@Override
public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account, Bundle options) throws NetworkErrorException {
return null;
}
@Override
public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) {
return null;
}
@Override
public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options)
throws NetworkErrorException {
return null;
}
@Override
public String getAuthTokenLabel(String authTokenType) {
return null;
}
@Override
public Bundle hasFeatures(AccountAuthenticatorResponse response,
Account account, String[] features)
throws NetworkErrorException {
return null;
}
@Override
public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options)
throws NetworkErrorException {
return null;
}
}
private static Authenticator authenticator = null;
protected Authenticator getAuthenticator() {
if (authenticator == null) {
authenticator = new Authenticator(this);
}
return authenticator;
}
@Override
public IBinder onBind(Intent intent) {
if (intent.getAction().equals(AccountManager.ACTION_AUTHENTICATOR_INTENT)) {
return getAuthenticator().getIBinder();
} else {
return null;
}
}
}
@@ -47,7 +47,7 @@ public class AutoMessageReplyReceiver extends BroadcastReceiver {
if (dialog_id == 0 || max_id == 0) {
return;
}
SendMessagesHelper.getInstance().sendMessageText(text.toString(), dialog_id, null, null);
SendMessagesHelper.getInstance().sendMessageText(text.toString(), dialog_id, null);
MrMailbox.markseenChat((int)dialog_id);
NotificationsController.getInstance().removeSeenMessages();
}
@@ -1,99 +0,0 @@
/*******************************************************************************
*
* Messenger Android Frontend
* (C) 2013-2016 Nikolai Kudashov
* (C) 2017 Björn Petersen
* Contact: r10s@b44t.com, http://b44t.com
*
* This program 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.
*
* This program 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
* this program. If not, see http://www.gnu.org/licenses/ .
*
******************************************************************************/
package com.b44t.messenger;
import android.app.Activity;
import android.app.IntentService;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;
import android.system.Os;
import android.system.StructStat;
import java.io.File;
import java.util.HashMap;
public class ClearCacheService extends IntentService {
public ClearCacheService() {
super("ClearCacheService");
}
@Override
protected void onHandleIntent(Intent intent) {
ApplicationLoader.postInitApplication();
/*
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
final int keepMedia = preferences.getInt("keep_media", 2);
if (keepMedia == 2) {
return;
}
Utilities.globalQueue.postRunnable(new Runnable() {
@Override
public void run() {
long currentTime = System.currentTimeMillis();
long diff = 60 * 60 * 1000 * 24 * (keepMedia == 0 ? 7 : 30);
final HashMap<Integer, File> paths = ImageLoader.getInstance().createMediaPaths();
for (HashMap.Entry<Integer, File> entry : paths.entrySet()) {
if (entry.getKey() == FileLoader.MEDIA_DIR_CACHE) {
continue;
}
try {
File[] array = entry.getValue().listFiles();
if (array != null) {
for (int b = 0; b < array.length; b++) {
File f = array[b];
if (f.isFile()) {
if (f.getName().equals(".nomedia")) {
continue;
}
if (Build.VERSION.SDK_INT >= 21) {
try {
StructStat stat = Os.stat(f.getPath());
if (stat.st_atime != 0) {
if (stat.st_atime + diff < currentTime) {
f.delete();
}
} else if (stat.st_mtime + diff < currentTime) {
f.delete();
}
} catch (Exception e) {
FileLog.e("messenger", e);
}
} else if (f.lastModified() + diff < currentTime) {
f.delete();
}
}
}
}
} catch (Throwable e) {
FileLog.e("messenger", e);
}
}
}
});
*/
}
}
@@ -73,7 +73,7 @@ public class ConnectionsManager {
//native_setPushConnectionEnabled(value);
}
public void init(String deviceModel, String systemVersion, String appVersion, String langCode, String configPath, String logPath, int userId, boolean enablePushConnection) {
public void init() {
//native_init(version, layer, apiId, deviceModel, systemVersion, appVersion, langCode, configPath, logPath, userId, enablePushConnection);
//checkConnection();
BroadcastReceiver networkStateReceiver = new BroadcastReceiver() {
@@ -117,6 +117,7 @@ public class ConnectionsManager {
return lastClassGuid++;
}
/* -- leave this for future use
public static boolean isRoaming() {
try {
ConnectivityManager cm = (ConnectivityManager) ApplicationLoader.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE);
@@ -128,8 +129,9 @@ public class ConnectionsManager {
FileLog.e("messenger", e);
}
return false;
}
} */
/* -- leave this for future use
public static boolean isConnectedToWiFi() {
try {
ConnectivityManager cm = (ConnectivityManager) ApplicationLoader.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE);
@@ -141,17 +143,16 @@ public class ConnectionsManager {
FileLog.e("messenger", e);
}
return false;
}
} */
public static boolean isNetworkOnline() {
try {
ConnectivityManager cm = (ConnectivityManager) ApplicationLoader.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && (netInfo.isConnectedOrConnecting() || netInfo.isAvailable())) {
if (netInfo != null && netInfo.isConnected()) {
return true;
}
netInfo = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
/* netInfo = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
return true;
@@ -160,10 +161,8 @@ public class ConnectionsManager {
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
return true;
}
}
} */
} catch (Exception e) {
FileLog.e("messenger", e);
return true;
}
return false;
}
@@ -1,78 +0,0 @@
/*******************************************************************************
*
* Messenger Android Frontend
* (C) 2013-2016 Nikolai Kudashov
* (C) 2017 Björn Petersen
* Contact: r10s@b44t.com, http://b44t.com
*
* This program 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.
*
* This program 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
* this program. If not, see http://www.gnu.org/licenses/ .
*
******************************************************************************/
package com.b44t.messenger;
import android.accounts.Account;
import android.accounts.OperationCanceledException;
import android.app.Service;
import android.content.AbstractThreadedSyncAdapter;
import android.content.ContentProviderClient;
import android.content.Context;
import android.content.Intent;
import android.content.SyncResult;
import android.os.Bundle;
import android.os.IBinder;
public class ContactsSyncAdapterService extends Service {
private static SyncAdapterImpl sSyncAdapter = null;
public ContactsSyncAdapterService() {
super();
}
private static class SyncAdapterImpl extends AbstractThreadedSyncAdapter {
private Context mContext;
public SyncAdapterImpl(Context context) {
super(context, true);
mContext = context;
}
@Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
try {
ContactsSyncAdapterService.performSync(mContext, account, extras, authority, provider, syncResult);
} catch (OperationCanceledException e) {
FileLog.e("messenger", e);
}
}
}
@Override
public IBinder onBind(Intent intent) {
return getSyncAdapter().getSyncAdapterBinder();
}
private SyncAdapterImpl getSyncAdapter() {
if (sSyncAdapter == null) {
sSyncAdapter = new SyncAdapterImpl(this);
}
return sSyncAdapter;
}
private static void performSync(Context context, Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult)
throws OperationCanceledException {
FileLog.d("messenger", "performSync: " + account.toString());
}
}
@@ -1,30 +0,0 @@
/*******************************************************************************
*
* Messenger Android Frontend
* (C) 2013-2016 Nikolai Kudashov
* (C) 2017 Björn Petersen
* Contact: r10s@b44t.com, http://b44t.com
*
* This program 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.
*
* This program 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
* this program. If not, see http://www.gnu.org/licenses/ .
*
******************************************************************************/
package com.b44t.messenger;
public class DownloadObject {
public TLObject object;
public int type;
public long id;
}
@@ -33,11 +33,6 @@ import java.util.concurrent.Semaphore;
public class FileLoader {
public interface FileLoaderDelegate {
void fileUploadProgressChanged(String location, float progress, boolean isEncrypted);
void fileDidUploaded(String location, TLRPC.InputFile inputFile, TLRPC.InputEncryptedFile inputEncryptedFile, byte[] key, byte[] iv, long totalFileSize);
void fileDidFailedUpload(String location, boolean isEncrypted);
void fileDidLoaded(String location, File finalFile, int type);
@@ -55,23 +50,16 @@ public class FileLoader {
private HashMap<Integer, File> mediaDirs = null;
private volatile DispatchQueue fileLoaderQueue = new DispatchQueue("fileUploadQueue");
private LinkedList<FileUploadOperation> uploadOperationQueue = new LinkedList<>();
private LinkedList<FileUploadOperation> uploadSmallOperationQueue = new LinkedList<>();
private LinkedList<FileLoadOperation> loadOperationQueue = new LinkedList<>();
private LinkedList<FileLoadOperation> audioLoadOperationQueue = new LinkedList<>();
private LinkedList<FileLoadOperation> photoLoadOperationQueue = new LinkedList<>();
private ConcurrentHashMap<String, FileUploadOperation> uploadOperationPaths = new ConcurrentHashMap<>();
private ConcurrentHashMap<String, FileUploadOperation> uploadOperationPathsEnc = new ConcurrentHashMap<>();
private ConcurrentHashMap<String, FileLoadOperation> loadOperationPaths = new ConcurrentHashMap<>();
private HashMap<String, Long> uploadSizes = new HashMap<>();
private FileLoaderDelegate delegate = null;
private int currentLoadOperationsCount = 0;
private int currentAudioLoadOperationsCount = 0;
private int currentPhotoLoadOperationsCount = 0;
private int currentUploadOperationsCount = 0;
private int currentUploadSmallOperationsCount = 0;
private static volatile FileLoader Instance = null;
@@ -92,12 +80,6 @@ public class FileLoader {
mediaDirs = dirs;
}
/*
public File checkDirectory(int type) {
return mediaDirs.get(type);
}
*/
public File getDirectory(int type) { // always returns the cache directory as this is the only one set in mediaDirs[] - we do not use the other directories at the moment
File dir = mediaDirs.get(type);
if (dir == null && type != MEDIA_DIR_CACHE) {
@@ -113,160 +95,6 @@ public class FileLoader {
return dir;
}
/*
public void checkUploadNewDataAvailable(final String location, final boolean encrypted, final long finalSize) {
fileLoaderQueue.postRunnable(new Runnable() {
@Override
public void run() {
FileUploadOperation operation;
if (encrypted) {
operation = uploadOperationPathsEnc.get(location);
} else {
operation = uploadOperationPaths.get(location);
}
if (operation != null) {
operation.checkNewDataAvailable(finalSize);
} else if (finalSize != 0) {
uploadSizes.put(location, finalSize);
}
}
});
}
*/
public void uploadFile(final String location, final boolean encrypted, final boolean small) {
uploadFile(location, encrypted, small, 0);
}
public void uploadFile(final String location, final boolean encrypted, final boolean small, final int estimatedSize) {
if (location == null) {
return;
}
fileLoaderQueue.postRunnable(new Runnable() {
@Override
public void run() {
if (encrypted) {
if (uploadOperationPathsEnc.containsKey(location)) {
return;
}
} else {
if (uploadOperationPaths.containsKey(location)) {
return;
}
}
int esimated = estimatedSize;
if (esimated != 0) {
Long finalSize = uploadSizes.get(location);
if (finalSize != null) {
esimated = 0;
uploadSizes.remove(location);
}
}
FileUploadOperation operation = new FileUploadOperation(location, encrypted, esimated);
if (encrypted) {
uploadOperationPathsEnc.put(location, operation);
} else {
uploadOperationPaths.put(location, operation);
}
operation.delegate = new FileUploadOperation.FileUploadOperationDelegate() {
@Override
public void didFinishUploadingFile(final FileUploadOperation operation, final TLRPC.InputFile inputFile, final TLRPC.InputEncryptedFile inputEncryptedFile, final byte[] key, final byte[] iv) {
fileLoaderQueue.postRunnable(new Runnable() {
@Override
public void run() {
if (encrypted) {
uploadOperationPathsEnc.remove(location);
} else {
uploadOperationPaths.remove(location);
}
if (small) {
currentUploadSmallOperationsCount--;
if (currentUploadSmallOperationsCount < 1) {
FileUploadOperation operation = uploadSmallOperationQueue.poll();
if (operation != null) {
currentUploadSmallOperationsCount++;
operation.start();
}
}
} else {
currentUploadOperationsCount--;
if (currentUploadOperationsCount < 1) {
FileUploadOperation operation = uploadOperationQueue.poll();
if (operation != null) {
currentUploadOperationsCount++;
operation.start();
}
}
}
if (delegate != null) {
delegate.fileDidUploaded(location, inputFile, inputEncryptedFile, key, iv, operation.getTotalFileSize());
}
}
});
}
@Override
public void didFailedUploadingFile(final FileUploadOperation operation) {
fileLoaderQueue.postRunnable(new Runnable() {
@Override
public void run() {
if (encrypted) {
uploadOperationPathsEnc.remove(location);
} else {
uploadOperationPaths.remove(location);
}
if (delegate != null) {
delegate.fileDidFailedUpload(location, encrypted);
}
if (small) {
currentUploadSmallOperationsCount--;
if (currentUploadSmallOperationsCount < 1) {
FileUploadOperation operation = uploadSmallOperationQueue.poll();
if (operation != null) {
currentUploadSmallOperationsCount++;
operation.start();
}
}
} else {
currentUploadOperationsCount--;
if (currentUploadOperationsCount < 1) {
FileUploadOperation operation = uploadOperationQueue.poll();
if (operation != null) {
currentUploadOperationsCount++;
operation.start();
}
}
}
}
});
}
@Override
public void didChangedUploadProgress(FileUploadOperation operation, final float progress) {
if (delegate != null) {
delegate.fileUploadProgressChanged(location, progress, encrypted);
}
}
};
if (small) {
if (currentUploadSmallOperationsCount < 1) {
currentUploadSmallOperationsCount++;
operation.start();
} else {
uploadSmallOperationQueue.add(operation);
}
} else {
if (currentUploadOperationsCount < 1) {
currentUploadOperationsCount++;
operation.start();
} else {
uploadOperationQueue.add(operation);
}
}
}
});
}
public void cancelLoadFile(TLRPC.Document document) {
cancelLoadFile(document, null, null);
}
@@ -1,94 +0,0 @@
/*******************************************************************************
*
* Messenger Android Frontend
* (C) 2013-2016 Nikolai Kudashov
* (C) 2017 Björn Petersen
* Contact: r10s@b44t.com, http://b44t.com
*
* This program 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.
*
* This program 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
* this program. If not, see http://www.gnu.org/licenses/ .
*
******************************************************************************/
package com.b44t.messenger;
import java.io.FileInputStream;
public class FileUploadOperation {
public int state = 0;
public FileUploadOperationDelegate delegate;
private int requestToken = 0;
private long totalFileSize = 0;
private boolean isEncrypted = false;
private int estimatedSize = 0;
private FileInputStream stream;
public interface FileUploadOperationDelegate {
void didFinishUploadingFile(FileUploadOperation operation, TLRPC.InputFile inputFile, TLRPC.InputEncryptedFile inputEncryptedFile, byte[] key, byte[] iv);
void didFailedUploadingFile(FileUploadOperation operation);
void didChangedUploadProgress(FileUploadOperation operation, float progress);
}
public FileUploadOperation(String location, boolean encrypted, int estimated) {
isEncrypted = encrypted;
estimatedSize = estimated;
}
public long getTotalFileSize() {
return totalFileSize;
}
public void start() {
}
public void cancel() {
if (state == 3) {
return;
}
state = 2;
if (requestToken != 0) {
ConnectionsManager.getInstance().cancelRequest(requestToken, true);
}
delegate.didFailedUploadingFile(this);
cleanup();
}
private void cleanup() {
}
/*
protected void checkNewDataAvailable(final long finalSize) {
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
if (estimatedSize != 0 && finalSize != 0) {
estimatedSize = 0;
totalFileSize = finalSize;
totalPartsCount = (int) (totalFileSize + uploadChunkSize - 1) / uploadChunkSize;
if (started) {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("uploadinfo", Activity.MODE_PRIVATE);
storeFileUploadInfo(preferences);
}
}
if (requestToken == 0) {
startUploadRequest();
}
}
});
}
*/
}
@@ -37,7 +37,6 @@ import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import com.b44t.ui.Components.AnimatedFileDrawable;
@@ -85,147 +84,18 @@ public class ImageLoader {
private static byte[] headerThumb = new byte[12];
private int currentHttpTasksCount = 0;
private LinkedList<HttpFileTask> httpFileLoadTasks = new LinkedList<>();
private HashMap<String, HttpFileTask> httpFileLoadTasksByKeys = new HashMap<>();
private HashMap<String, Runnable> retryHttpsTasks = new HashMap<>();
private int currentHttpFileLoadTasksCount = 0;
private String ignoreRemoval = null;
private volatile long lastCacheOutTime = 0;
private int lastImageNum = 0;
private long lastProgressUpdateTime = 0;
private File messengerPath = null;
private class ThumbGenerateInfo {
private int count;
private TLRPC.FileLocation fileLocation;
private String filter;
}
private class HttpFileTask extends AsyncTask<Void, Void, Boolean> {
private String url;
private File tempFile;
private String ext;
private RandomAccessFile fileOutputStream = null;
private boolean canRetry = true;
public HttpFileTask(String url, File tempFile, String ext) {
this.url = url;
this.tempFile = tempFile;
this.ext = ext;
}
protected Boolean doInBackground(Void... voids) {
InputStream httpConnectionStream = null;
boolean done = false;
URLConnection httpConnection = null;
try {
URL downloadUrl = new URL(url);
httpConnection = downloadUrl.openConnection();
httpConnection.addRequestProperty("User-Agent", "Mozilla/5.0 (Linux; Android 4.4; Nexus 5 Build/_BuildID_) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36");
httpConnection.addRequestProperty("Referer", "google.com");
httpConnection.setConnectTimeout(5000);
httpConnection.setReadTimeout(5000);
if (httpConnection instanceof HttpURLConnection) {
HttpURLConnection httpURLConnection = (HttpURLConnection) httpConnection;
httpURLConnection.setInstanceFollowRedirects(true);
int status = httpURLConnection.getResponseCode();
if (status == HttpURLConnection.HTTP_MOVED_TEMP || status == HttpURLConnection.HTTP_MOVED_PERM || status == HttpURLConnection.HTTP_SEE_OTHER) {
String newUrl = httpURLConnection.getHeaderField("Location");
String cookies = httpURLConnection.getHeaderField("Set-Cookie");
downloadUrl = new URL(newUrl);
httpConnection = downloadUrl.openConnection();
httpConnection.setRequestProperty("Cookie", cookies);
httpConnection.addRequestProperty("User-Agent", "Mozilla/5.0 (Linux; Android 4.4; Nexus 5 Build/_BuildID_) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36");
httpConnection.addRequestProperty("Referer", "google.com");
}
}
httpConnection.connect();
httpConnectionStream = httpConnection.getInputStream();
fileOutputStream = new RandomAccessFile(tempFile, "rws");
} catch (Throwable e) {
if (e instanceof UnknownHostException) {
canRetry = false;
}
FileLog.e("messenger", e);
}
if (canRetry) {
try {
if (httpConnection != null && httpConnection instanceof HttpURLConnection) {
int code = ((HttpURLConnection) httpConnection).getResponseCode();
if (code != HttpURLConnection.HTTP_OK && code != HttpURLConnection.HTTP_ACCEPTED && code != HttpURLConnection.HTTP_NOT_MODIFIED) {
canRetry = false;
}
}
} catch (Exception e) {
FileLog.e("messenger", e);
}
if (httpConnectionStream != null) {
try {
byte[] data = new byte[1024 * 4];
while (true) {
if (isCancelled()) {
break;
}
try {
int read = httpConnectionStream.read(data);
if (read > 0) {
fileOutputStream.write(data, 0, read);
} else if (read == -1) {
done = true;
break;
} else {
break;
}
} catch (Exception e) {
FileLog.e("messenger", e);
break;
}
}
} catch (Throwable e) {
FileLog.e("messenger", e);
}
}
try {
if (fileOutputStream != null) {
fileOutputStream.close();
fileOutputStream = null;
}
} catch (Throwable e) {
FileLog.e("messenger", e);
}
try {
if (httpConnectionStream != null) {
httpConnectionStream.close();
}
} catch (Throwable e) {
FileLog.e("messenger", e);
}
}
return done;
}
@Override
protected void onPostExecute(Boolean result) {
runHttpFileLoadTasks(this, result ? 2 : 1);
}
@Override
protected void onCancelled() {
runHttpFileLoadTasks(this, 2);
}
}
private class HttpImageTask extends AsyncTask<Void, Void, Boolean> {
private CacheImage cacheImage = null;
@@ -530,16 +400,6 @@ public class ImageLoader {
kf += "@" + filter;
}
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageThumbGenerated, bitmapDrawable, kf);
/*BitmapDrawable old = memCache.get(kf);
if (old != null) {
Bitmap image = old.getBitmap();
if (runtimeHack != null) {
runtimeHack.trackAlloc(image.getRowBytes() * image.getHeight());
}
if (!image.isRecycled()) {
image.recycle();
}
}*/
memCache.put(kf, bitmapDrawable);
}
});
@@ -1120,6 +980,7 @@ public class ImageLoader {
};
FileLoader.getInstance().setDelegate(new FileLoader.FileLoaderDelegate() {
/*
@Override
public void fileUploadProgressChanged(final String location, final float progress, final boolean isEncrypted) {
fileProgresses.put(location, progress);
@@ -1167,6 +1028,7 @@ public class ImageLoader {
}
});
}
*/
@Override
public void fileDidLoaded(final String location, final File finalFile, final int type) {
@@ -1256,149 +1118,6 @@ public class ImageLoader {
mediaDirs.put(FileLoader.MEDIA_DIR_CACHE, cachePath);
FileLoader.getInstance().setMediaDirs(mediaDirs);
/*
cacheOutQueue.postRunnable(new Runnable() {
@Override
public void run() {
final HashMap<Integer, File> paths = createMediaPaths();
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
FileLoader.getInstance().setMediaDirs(paths);
}
});
}
});
*/
}
/*
public HashMap<Integer, File> createMediaPaths() { // not sure, but it seems as if these paths are not needed
HashMap<Integer, File> mediaDirs = new HashMap<>();
File cachePath = AndroidUtilities.getCacheDir();
if (!cachePath.isDirectory()) {
try {
cachePath.mkdirs();
} catch (Exception e) {
FileLog.e("messenger", e);
}
}
try {
new File(cachePath, ".nomedia").createNewFile();
} catch (Exception e) {
FileLog.e("messenger", e);
}
mediaDirs.put(FileLoader.MEDIA_DIR_CACHE, cachePath);
FileLog.e("messenger", "cache path = " + cachePath);
try {
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
messengerPath = new File(Environment.getExternalStorageDirectory(), "Delta Chat");
messengerPath.mkdirs();
if (messengerPath.isDirectory()) {
try {
File imagePath = new File(messengerPath, "Delta Chat Images");
imagePath.mkdir();
if (imagePath.isDirectory() && canMoveFiles(cachePath, imagePath, FileLoader.MEDIA_DIR_IMAGE)) {
mediaDirs.put(FileLoader.MEDIA_DIR_IMAGE, imagePath);
FileLog.e("messenger", "image path = " + imagePath);
}
} catch (Exception e) {
FileLog.e("messenger", e);
}
try {
File videoPath = new File(messengerPath, "Delta Chat Video");
videoPath.mkdir();
if (videoPath.isDirectory() && canMoveFiles(cachePath, videoPath, FileLoader.MEDIA_DIR_VIDEO)) {
mediaDirs.put(FileLoader.MEDIA_DIR_VIDEO, videoPath);
FileLog.e("messenger", "video path = " + videoPath);
}
} catch (Exception e) {
FileLog.e("messenger", e);
}
try {
File audioPath = new File(messengerPath, "Delta Chat Audio");
audioPath.mkdir();
if (audioPath.isDirectory() && canMoveFiles(cachePath, audioPath, FileLoader.MEDIA_DIR_AUDIO)) {
new File(audioPath, ".nomedia").createNewFile();
mediaDirs.put(FileLoader.MEDIA_DIR_AUDIO, audioPath);
FileLog.e("messenger", "audio path = " + audioPath);
}
} catch (Exception e) {
FileLog.e("messenger", e);
}
try {
File documentPath = new File(messengerPath, "Delta Chat Documents");
documentPath.mkdir();
if (documentPath.isDirectory() && canMoveFiles(cachePath, documentPath, FileLoader.MEDIA_DIR_DOCUMENT)) {
new File(documentPath, ".nomedia").createNewFile();
mediaDirs.put(FileLoader.MEDIA_DIR_DOCUMENT, documentPath);
FileLog.e("messenger", "documents path = " + documentPath);
}
} catch (Exception e) {
FileLog.e("messenger", e);
}
}
} else {
FileLog.e("messenger", "this Android can't rename files");
}
MediaController.getInstance().checkSaveToGalleryFiles();
} catch (Exception e) {
FileLog.e("messenger", e);
}
return mediaDirs;
}
*/
private boolean canMoveFiles(File from, File to, int type) {
RandomAccessFile file = null;
try {
File srcFile = null;
File dstFile = null;
if (type == FileLoader.MEDIA_DIR_IMAGE) {
srcFile = new File(from, "000000000_999999_temp.jpg");
dstFile = new File(to, "000000000_999999.jpg");
} else if (type == FileLoader.MEDIA_DIR_DOCUMENT) {
srcFile = new File(from, "000000000_999999_temp.doc");
dstFile = new File(to, "000000000_999999.doc");
} else if (type == FileLoader.MEDIA_DIR_AUDIO) {
srcFile = new File(from, "000000000_999999_temp.ogg");
dstFile = new File(to, "000000000_999999.ogg");
} else if (type == FileLoader.MEDIA_DIR_VIDEO) {
srcFile = new File(from, "000000000_999999_temp.mp4");
dstFile = new File(to, "000000000_999999.mp4");
}
byte[] buffer = new byte[1024];
srcFile.createNewFile();
file = new RandomAccessFile(srcFile, "rws");
file.write(buffer);
file.close();
file = null;
boolean canRename = srcFile.renameTo(dstFile);
srcFile.delete();
dstFile.delete();
if (canRename) {
return true;
}
} catch (Exception e) {
FileLog.e("messenger", e);
} finally {
try {
if (file != null) {
file.close();
}
} catch (Exception e) {
FileLog.e("messenger", e);
}
}
return false;
}
public Float getFileProgress(String location) {
@@ -1408,21 +1127,6 @@ public class ImageLoader {
return fileProgresses.get(location);
}
private void performReplace(String oldKey, String newKey) {
BitmapDrawable b = memCache.get(oldKey);
if (b != null) {
ignoreRemoval = oldKey;
memCache.remove(oldKey);
memCache.put(newKey, b);
ignoreRemoval = null;
}
Integer val = bitmapUseCounts.get(oldKey);
if (val != null) {
bitmapUseCounts.put(newKey, val);
bitmapUseCounts.remove(oldKey);
}
}
public void incrementUseCount(String key) {
Integer count = bitmapUseCounts.get(key);
if (count == null) {
@@ -1503,65 +1207,6 @@ public class ImageLoader {
});
}
public BitmapDrawable getImageFromMemory(String key) {
return memCache.get(key);
}
public BitmapDrawable getImageFromMemory(TLObject fileLocation, String httpUrl, String filter) {
if (fileLocation == null && httpUrl == null) {
return null;
}
String key = null;
if (httpUrl != null) {
key = Utilities.MD5(httpUrl);
} else {
if (fileLocation instanceof TLRPC.FileLocation) {
TLRPC.FileLocation location = (TLRPC.FileLocation) fileLocation;
key = location.volume_id + "_" + location.local_id;
} else if (fileLocation instanceof TLRPC.Document) {
TLRPC.Document location = (TLRPC.Document) fileLocation;
key = location.dc_id + "_" + location.id;
}
}
if (filter != null) {
key += "@" + filter;
}
return memCache.get(key);
}
private void replaceImageInCacheInternal(final String oldKey, final String newKey, final TLRPC.FileLocation newLocation) {
ArrayList<String> arr = memCache.getFilterKeys(oldKey);
if (arr != null) {
for (int a = 0; a < arr.size(); a++) {
String filter = arr.get(a);
String oldK = oldKey + "@" + filter;
String newK = newKey + "@" + filter;
performReplace(oldK, newK);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.didReplacedPhotoInMemCache, oldK, newK, newLocation);
}
} else {
performReplace(oldKey, newKey);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.didReplacedPhotoInMemCache, oldKey, newKey, newLocation);
}
}
public void replaceImageInCache(final String oldKey, final String newKey, final TLRPC.FileLocation newLocation, boolean post) {
if (post) {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
replaceImageInCacheInternal(oldKey, newKey, newLocation);
}
});
} else {
replaceImageInCacheInternal(oldKey, newKey, newLocation);
}
}
public void putImageToCache(BitmapDrawable bitmap, String key) {
memCache.put(key, bitmap);
}
private void generateThumb(int mediaType, File originalPath, TLRPC.FileLocation thumbLocation, String filter) {
if (mediaType != FileLoader.MEDIA_DIR_IMAGE && mediaType != FileLoader.MEDIA_DIR_VIDEO && mediaType != FileLoader.MEDIA_DIR_DOCUMENT || originalPath == null || thumbLocation == null) {
return;
@@ -1619,7 +1264,6 @@ public class ImageLoader {
if (!added) {
boolean onlyCache = false;
boolean isQuality = false;
File cacheFile = null;
if (httpLocation != null) {
@@ -1932,80 +1576,12 @@ public class ImageLoader {
}
}
public void loadHttpFile(String url, String defaultExt) {
if (url == null || url.length() == 0 || httpFileLoadTasksByKeys.containsKey(url)) {
return;
}
String ext = getHttpUrlExtension(url, defaultExt);
File file = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), Utilities.MD5(url) + "_temp." + ext);
file.delete();
HttpFileTask task = new HttpFileTask(url, file, ext);
httpFileLoadTasks.add(task);
httpFileLoadTasksByKeys.put(url, task);
runHttpFileLoadTasks(null, 0);
}
public void cancelLoadHttpFile(String url) {
HttpFileTask task = httpFileLoadTasksByKeys.get(url);
if (task != null) {
task.cancel(true);
httpFileLoadTasksByKeys.remove(url);
httpFileLoadTasks.remove(task);
}
Runnable runnable = retryHttpsTasks.get(url);
if (runnable != null) {
AndroidUtilities.cancelRunOnUIThread(runnable);
}
runHttpFileLoadTasks(null, 0);
}
private void runHttpFileLoadTasks(final HttpFileTask oldTask, final int reason) {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
if (oldTask != null) {
currentHttpFileLoadTasksCount--;
}
if (oldTask != null) {
if (reason == 1) {
if (oldTask.canRetry) {
final HttpFileTask newTask = new HttpFileTask(oldTask.url, oldTask.tempFile, oldTask.ext);
Runnable runnable = new Runnable() {
@Override
public void run() {
httpFileLoadTasks.add(newTask);
runHttpFileLoadTasks(null, 0);
}
};
retryHttpsTasks.put(oldTask.url, runnable);
AndroidUtilities.runOnUIThread(runnable, 1000);
} else {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.httpFileDidFailedLoad, oldTask.url);
}
} else if (reason == 2) {
httpFileLoadTasksByKeys.remove(oldTask.url);
File file = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), Utilities.MD5(oldTask.url) + "." + oldTask.ext);
String result = oldTask.tempFile.renameTo(file) ? file.toString() : oldTask.tempFile.toString();
NotificationCenter.getInstance().postNotificationName(NotificationCenter.httpFileDidLoaded, oldTask.url, result);
}
}
while (currentHttpFileLoadTasksCount < 2 && !httpFileLoadTasks.isEmpty()) {
HttpFileTask task = httpFileLoadTasks.poll();
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null, null, null);
currentHttpFileLoadTasksCount++;
}
}
});
}
public static Bitmap loadBitmap(String path, Uri uri, float maxWidth, float maxHeight, boolean useMaxScale) {
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
InputStream inputStream = null;
if (path == null && uri != null && uri.getScheme() != null) {
String imageFilePath = null;
if (uri.getScheme().contains("file")) {
path = uri.getPath();
} else {
@@ -2020,7 +1596,6 @@ public class ImageLoader {
if (path != null) {
BitmapFactory.decodeFile(path, bmOptions);
} else if (uri != null) {
boolean error = false;
try {
inputStream = ApplicationLoader.applicationContext.getContentResolver().openInputStream(uri);
BitmapFactory.decodeStream(inputStream, null, bmOptions);
@@ -2134,7 +1709,7 @@ public class ImageLoader {
return b;
}
private static TLRPC.PhotoSize scaleAndSaveImageInternal(Bitmap bitmap, int w, int h, float photoW, float photoH, float scaleFactor, int quality, boolean cache, boolean scaleAnyway) throws Exception {
private static TLRPC.PhotoSize scaleAndSaveImageInternal(File cacheFile, Bitmap bitmap, int w, int h, float photoW, float photoH, float scaleFactor, int quality, boolean cache, boolean scaleAnyway) throws Exception {
Bitmap scaledBitmap;
if (scaleFactor > 1 || scaleAnyway) {
scaledBitmap = Bitmaps.createScaledBitmap(bitmap, w, h, true);
@@ -2163,8 +1738,11 @@ public class ImageLoader {
size.type = "w";
}
String fileName = location.volume_id + "_" + location.local_id + ".jpg";
final File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName);
if( cacheFile == null ) {
String fileName = location.volume_id + "_" + location.local_id + ".jpg";
cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName);
}
FileOutputStream stream = new FileOutputStream(cacheFile);
scaledBitmap.compress(Bitmap.CompressFormat.JPEG, quality, stream);
if (cache) {
@@ -2185,10 +1763,18 @@ public class ImageLoader {
}
public static TLRPC.PhotoSize scaleAndSaveImage(Bitmap bitmap, float maxWidth, float maxHeight, int quality, boolean cache) {
return scaleAndSaveImage(bitmap, maxWidth, maxHeight, quality, cache, 0, 0);
return scaleAndSaveImage(null, bitmap, maxWidth, maxHeight, quality, cache, 0, 0);
}
public static TLRPC.PhotoSize scaleAndSaveImage(Bitmap bitmap, float maxWidth, float maxHeight, int quality, boolean cache, int minWidth, int minHeight) {
return scaleAndSaveImage(null, bitmap, maxWidth, maxHeight, quality, cache, minWidth, minHeight);
}
public static TLRPC.PhotoSize scaleAndSaveImage(File cacheFile, Bitmap bitmap, float maxWidth, float maxHeight, int quality, boolean cache) {
return scaleAndSaveImage(cacheFile, bitmap, maxWidth, maxHeight, quality, cache, 0, 0);
}
private static TLRPC.PhotoSize scaleAndSaveImage(File cacheFile, Bitmap bitmap, float maxWidth, float maxHeight, int quality, boolean cache, int minWidth, int minHeight) {
if (bitmap == null) {
return null;
}
@@ -2216,13 +1802,13 @@ public class ImageLoader {
}
try {
return scaleAndSaveImageInternal(bitmap, w, h, photoW, photoH, scaleFactor, quality, cache, scaleAnyway);
return scaleAndSaveImageInternal(cacheFile, bitmap, w, h, photoW, photoH, scaleFactor, quality, cache, scaleAnyway);
} catch (Throwable e) {
FileLog.e("messenger", e);
ImageLoader.getInstance().clearMemory();
System.gc();
try {
return scaleAndSaveImageInternal(bitmap, w, h, photoW, photoH, scaleFactor, quality, cache, scaleAnyway);
return scaleAndSaveImageInternal(cacheFile, bitmap, w, h, photoW, photoH, scaleFactor, quality, cache, scaleAnyway);
} catch (Throwable e2) {
FileLog.e("messenger", e2);
return null;
@@ -371,12 +371,10 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
setImageBackup.ext = currentExt;
setImageBackup.cacheOnly = currentCacheOnly;
}
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.didReplacedPhotoInMemCache);
clearImage();
}
public boolean onAttachedToWindow() {
NotificationCenter.getInstance().addObserver(this, NotificationCenter.didReplacedPhotoInMemCache);
if (setImageBackup != null && (setImageBackup.fileLocation != null || setImageBackup.httpUrl != null || setImageBackup.thumbLocation != null || setImageBackup.thumb != null)) {
setImage(setImageBackup.fileLocation, setImageBackup.httpUrl, setImageBackup.filter, setImageBackup.thumb, setImageBackup.thumbLocation, setImageBackup.thumbFilter, setImageBackup.size, setImageBackup.ext, setImageBackup.cacheOnly);
return true;
@@ -1058,26 +1056,6 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
}
}
}
} else if (id == NotificationCenter.didReplacedPhotoInMemCache) {
String oldKey = (String) args[0];
if (currentKey != null && currentKey.equals(oldKey)) {
currentKey = (String) args[1];
currentImageLocation = (TLRPC.FileLocation) args[2];
}
if (currentThumbKey != null && currentThumbKey.equals(oldKey)) {
currentThumbKey = (String) args[1];
currentThumbLocation = (TLRPC.FileLocation) args[2];
}
if (setImageBackup != null) {
if (currentKey != null && currentKey.equals(oldKey)) {
currentKey = (String) args[1];
currentImageLocation = (TLRPC.FileLocation) args[2];
}
if (currentThumbKey != null && currentThumbKey.equals(oldKey)) {
currentThumbKey = (String) args[1];
currentThumbLocation = (TLRPC.FileLocation) args[2];
}
}
}
}
}
@@ -31,18 +31,10 @@ import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.text.format.DateFormat;
import android.util.Xml;
import com.b44t.messenger.time.FastDateFormat;
import org.xmlpull.v1.XmlPullParser;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
@@ -50,13 +42,6 @@ import java.util.TimeZone;
public class LocaleController {
static final int QUANTITY_OTHER = 0x0000;
static final int QUANTITY_ZERO = 0x0001;
static final int QUANTITY_ONE = 0x0002;
static final int QUANTITY_TWO = 0x0004;
static final int QUANTITY_FEW = 0x0008;
static final int QUANTITY_MANY = 0x0010;
public static boolean isRTL = false;
public static int nameDisplayOrder = 1;
private static boolean is24HourFormat = false;
@@ -68,13 +53,9 @@ public class LocaleController {
public FastDateFormat chatDate;
public FastDateFormat chatFullDate;
private HashMap<String, PluralRules> allRules = new HashMap<>();
private Locale currentLocale;
private PluralRules currentPluralRules;
private Locale systemDefaultLocale; // this is not Locale.getDefault(); Locale.getDefault() may be changed using Locale.setDefault()
private LocaleInfo currentLocaleInfo;
private LocaleInfo defaultLocalInfo;
private HashMap<String, String> localeValues = new HashMap<>();
private String languageOverride;
private boolean changingConfiguration = false;
@@ -96,34 +77,10 @@ public class LocaleController {
public String name;
public String nameEnglish;
public String shortName;
public String pathToFile;
public String getSaveString() {
return name + "|" + nameEnglish + "|" + shortName + "|" + pathToFile;
}
public static LocaleInfo createWithString(String string) {
if (string == null || string.length() == 0) {
return null;
}
String[] args = string.split("\\|");
if (args.length != 4) {
return null;
}
LocaleInfo localeInfo = new LocaleInfo();
localeInfo.name = args[0];
localeInfo.nameEnglish = args[1];
localeInfo.shortName = args[2];
localeInfo.pathToFile = args[3];
return localeInfo;
}
}
public ArrayList<LocaleInfo> sortedLanguages = new ArrayList<>();
public HashMap<String, LocaleInfo> languagesDict = new HashMap<>();
private ArrayList<LocaleInfo> otherLanguages = new ArrayList<>();
private static volatile LocaleController Instance = null;
public static LocaleController getInstance() {
LocaleController localInstance = Instance;
@@ -139,134 +96,67 @@ public class LocaleController {
}
public LocaleController() {
addRules(new String[]{"bem", "brx", "da", "de", "el", "en", "eo", "es", "et", "fi", "fo", "gl", "he", "iw", "it", "nb",
"nl", "nn", "no", "sv", "af", "bg", "bn", "ca", "eu", "fur", "fy", "gu", "ha", "is", "ku",
"lb", "ml", "mr", "nah", "ne", "om", "or", "pa", "pap", "ps", "so", "sq", "sw", "ta", "te",
"tk", "ur", "zu", "mn", "gsw", "chr", "rm", "pt", "an", "ast"}, new PluralRules_One());
addRules(new String[]{"cs", "sk"}, new PluralRules_Czech());
addRules(new String[]{"ff", "fr", "kab"}, new PluralRules_French());
addRules(new String[]{"hr", "ru", "sr", "uk", "be", "bs", "sh"}, new PluralRules_Balkan());
addRules(new String[]{"lv"}, new PluralRules_Latvian());
addRules(new String[]{"lt"}, new PluralRules_Lithuanian());
addRules(new String[]{"pl"}, new PluralRules_Polish());
addRules(new String[]{"ro", "mo"}, new PluralRules_Romanian());
addRules(new String[]{"sl"}, new PluralRules_Slovenian());
addRules(new String[]{"ar"}, new PluralRules_Arabic());
addRules(new String[]{"mk"}, new PluralRules_Macedonian());
addRules(new String[]{"cy"}, new PluralRules_Welsh());
addRules(new String[]{"br"}, new PluralRules_Breton());
addRules(new String[]{"lag"}, new PluralRules_Langi());
addRules(new String[]{"shi"}, new PluralRules_Tachelhit());
addRules(new String[]{"mt"}, new PluralRules_Maltese());
addRules(new String[]{"ga", "se", "sma", "smi", "smj", "smn", "sms"}, new PluralRules_Two());
addRules(new String[]{"ak", "am", "bh", "fil", "tl", "guw", "hi", "ln", "mg", "nso", "ti", "wa"}, new PluralRules_Zero());
addRules(new String[]{"az", "bm", "fa", "ig", "hu", "ja", "kde", "kea", "ko", "my", "ses", "sg", "to",
"tr", "vi", "wo", "yo", "zh", "bo", "dz", "id", "jv", "ka", "km", "kn", "ms", "th"}, new PluralRules_None());
LocaleInfo localeInfo = new LocaleInfo();
localeInfo.name = "English";
localeInfo.nameEnglish = "English";
localeInfo.shortName = "en";
localeInfo.pathToFile = null;
sortedLanguages.add(localeInfo);
languagesDict.put(localeInfo.shortName, localeInfo);
localeInfo = new LocaleInfo();
localeInfo.name = "Italiano";
localeInfo.nameEnglish = "Italian";
localeInfo.shortName = "it";
localeInfo.pathToFile = null;
sortedLanguages.add(localeInfo);
languagesDict.put(localeInfo.shortName, localeInfo);
localeInfo = new LocaleInfo();
localeInfo.name = "Español";
localeInfo.nameEnglish = "Spanish";
localeInfo.shortName = "es";
sortedLanguages.add(localeInfo);
languagesDict.put(localeInfo.shortName, localeInfo);
localeInfo = new LocaleInfo();
localeInfo.name = "Deutsch";
localeInfo.nameEnglish = "German";
localeInfo.shortName = "de";
localeInfo.pathToFile = null;
sortedLanguages.add(localeInfo);
languagesDict.put(localeInfo.shortName, localeInfo);
localeInfo = new LocaleInfo();
localeInfo.name = "Français";
localeInfo.nameEnglish = "French";
localeInfo.shortName = "fr";
localeInfo.pathToFile = null;
sortedLanguages.add(localeInfo);
languagesDict.put(localeInfo.shortName, localeInfo);
localeInfo = new LocaleInfo();
localeInfo.name = "Nederlands";
localeInfo.nameEnglish = "Dutch";
localeInfo.shortName = "nl";
localeInfo.pathToFile = null;
sortedLanguages.add(localeInfo);
languagesDict.put(localeInfo.shortName, localeInfo);
/* EDIT BY MR
localeInfo = new LocaleInfo();
localeInfo.name = "العربية";
localeInfo.nameEnglish = "Arabic";
localeInfo.shortName = "ar";
localeInfo.pathToFile = null;
sortedLanguages.add(localeInfo);
localeInfo.name = "Polski";
localeInfo.nameEnglish = "Polish";
localeInfo.shortName = "pl";
languagesDict.put(localeInfo.shortName, localeInfo);
*/
localeInfo = new LocaleInfo();
localeInfo.name = "Português";
localeInfo.nameEnglish = "Portuguese";
localeInfo.shortName = "pt";
localeInfo.pathToFile = null;
sortedLanguages.add(localeInfo);
languagesDict.put(localeInfo.shortName, localeInfo);
/* EDIT BY MR
localeInfo = new LocaleInfo();
localeInfo.name = "Português (Portugal)";
localeInfo.nameEnglish = "Portuguese (Portugal)";
localeInfo.shortName = "pt_PT";
localeInfo.pathToFile = null;
sortedLanguages.add(localeInfo);
languagesDict.put(localeInfo.shortName, localeInfo);
localeInfo = new LocaleInfo();
localeInfo.name = "한국어";
localeInfo.nameEnglish = "Korean";
localeInfo.shortName = "ko";
localeInfo.pathToFile = null;
sortedLanguages.add(localeInfo);
languagesDict.put(localeInfo.shortName, localeInfo);
*/
loadOtherLanguages();
for (LocaleInfo locale : otherLanguages) {
sortedLanguages.add(locale);
languagesDict.put(locale.shortName, locale);
}
Collections.sort(sortedLanguages, new Comparator<LocaleInfo>() {
@Override
public int compare(LocaleController.LocaleInfo o, LocaleController.LocaleInfo o2) {
return o.name.compareTo(o2.name);
}
});
defaultLocalInfo = localeInfo = new LocaleController.LocaleInfo();
localeInfo.name = "System default";
localeInfo.nameEnglish = "System default";
localeInfo.shortName = null;
localeInfo.pathToFile = null;
sortedLanguages.add(0, localeInfo);
localeInfo = new LocaleInfo();
localeInfo.name = "Magyar";
localeInfo.nameEnglish = "Hungarian";
localeInfo.shortName = "hu";
languagesDict.put(localeInfo.shortName, localeInfo);
systemDefaultLocale = Locale.getDefault(); // we have to remember this as we may switch back to default later
is24HourFormat = DateFormat.is24HourFormat(ApplicationLoader.applicationContext);
LocaleInfo currentInfo = null;
boolean override = false;
@@ -281,11 +171,11 @@ public class LocaleController {
}
}
if (currentInfo == null && Locale.getDefault().getLanguage() != null) {
currentInfo = languagesDict.get(Locale.getDefault().getLanguage());
if (currentInfo == null && systemDefaultLocale.getLanguage() != null) {
currentInfo = languagesDict.get(systemDefaultLocale.getLanguage());
}
if (currentInfo == null) {
currentInfo = languagesDict.get(getLocaleString(Locale.getDefault()));
currentInfo = languagesDict.get(getLocaleString(systemDefaultLocale));
}
if (currentInfo == null) {
currentInfo = languagesDict.get("en");
@@ -303,29 +193,6 @@ public class LocaleController {
}
}
private void addRules(String[] languages, PluralRules rules) {
for (String language : languages) {
allRules.put(language, rules);
}
}
private String stringForQuantity(int quantity) {
switch (quantity) {
case QUANTITY_ZERO:
return "zero";
case QUANTITY_ONE:
return "one";
case QUANTITY_TWO:
return "two";
case QUANTITY_FEW:
return "few";
case QUANTITY_MANY:
return "many";
default:
return "other";
}
}
private String getLocaleString(Locale locale) {
if (locale == null) {
return "en";
@@ -349,139 +216,7 @@ public class LocaleController {
return result.toString();
}
public static String getLocaleStringIso639() {
Locale locale = Locale.getDefault();
if (locale == null) {
return "en";
}
String languageCode = locale.getLanguage();
String countryCode = locale.getCountry();
String variantCode = locale.getVariant();
if (languageCode.length() == 0 && countryCode.length() == 0) {
return "en";
}
StringBuilder result = new StringBuilder(11);
result.append(languageCode);
if (countryCode.length() > 0 || variantCode.length() > 0) {
result.append('-');
}
result.append(countryCode);
if (variantCode.length() > 0) {
result.append('_');
}
result.append(variantCode);
return result.toString();
}
private void saveOtherLanguages() {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("langconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
String locales = "";
for (LocaleInfo localeInfo : otherLanguages) {
String loc = localeInfo.getSaveString();
if (loc != null) {
if (locales.length() != 0) {
locales += "&";
}
locales += loc;
}
}
editor.putString("locales", locales);
editor.commit();
}
public boolean deleteLanguage(LocaleInfo localeInfo) {
if (localeInfo.pathToFile == null) {
return false;
}
if (currentLocaleInfo == localeInfo) {
applyLanguage(defaultLocalInfo, true);
}
otherLanguages.remove(localeInfo);
sortedLanguages.remove(localeInfo);
languagesDict.remove(localeInfo.shortName);
File file = new File(localeInfo.pathToFile);
file.delete();
saveOtherLanguages();
return true;
}
private void loadOtherLanguages() {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("langconfig", Activity.MODE_PRIVATE);
String locales = preferences.getString("locales", null);
if (locales == null || locales.length() == 0) {
return;
}
String[] localesArr = locales.split("&");
for (String locale : localesArr) {
LocaleInfo localeInfo = LocaleInfo.createWithString(locale);
if (localeInfo != null) {
otherLanguages.add(localeInfo);
}
}
}
private HashMap<String, String> getLocaleFileStrings(File file) {
FileInputStream stream = null;
try {
HashMap<String, String> stringMap = new HashMap<>();
XmlPullParser parser = Xml.newPullParser();
stream = new FileInputStream(file);
parser.setInput(stream, "UTF-8");
int eventType = parser.getEventType();
String name = null;
String value = null;
String attrName = null;
while (eventType != XmlPullParser.END_DOCUMENT) {
if(eventType == XmlPullParser.START_TAG) {
name = parser.getName();
int c = parser.getAttributeCount();
if (c > 0) {
attrName = parser.getAttributeValue(0);
}
} else if(eventType == XmlPullParser.TEXT) {
if (attrName != null) {
value = parser.getText();
if (value != null) {
value = value.trim();
value = value.replace("\\n", "\n");
value = value.replace("\\", "");
}
}
} else if (eventType == XmlPullParser.END_TAG) {
value = null;
attrName = null;
name = null;
}
if (name != null && name.equals("string") && value != null && attrName != null && value.length() != 0 && attrName.length() != 0) {
stringMap.put(attrName, value);
name = null;
value = null;
attrName = null;
}
eventType = parser.next();
}
return stringMap;
} catch (Exception e) {
FileLog.e("messenger", e);
} finally {
try {
if (stream != null) {
stream.close();
}
} catch (Exception e) {
FileLog.e("messenger", e);
}
}
return new HashMap<>();
}
public void applyLanguage(LocaleInfo localeInfo, boolean override) {
applyLanguage(localeInfo, override, false);
}
public void applyLanguage(LocaleInfo localeInfo, boolean override, boolean fromFile) {
if (localeInfo == null) {
return;
}
@@ -501,16 +236,16 @@ public class LocaleController {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putString("language", localeInfo.shortName);
editor.commit();
editor.apply();
}
}
} else {
newLocale = Locale.getDefault();
newLocale = systemDefaultLocale; // this is not Locale.getDefault(); Locale.getDefault() may be changed using Locale.setDefault()
languageOverride = null;
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.remove("language");
editor.commit();
editor.apply();
if (newLocale != null) {
LocaleInfo info = null;
@@ -526,17 +261,8 @@ public class LocaleController {
}
}
if (newLocale != null) {
if (localeInfo.pathToFile == null) {
localeValues.clear();
} else if (!fromFile) {
localeValues = getLocaleFileStrings(new File(localeInfo.pathToFile));
}
currentLocale = newLocale;
currentLocaleInfo = localeInfo;
currentPluralRules = allRules.get(currentLocale.getLanguage());
if (currentPluralRules == null) {
currentPluralRules = allRules.get("en");
}
changingConfiguration = true;
Locale.setDefault(currentLocale);
android.content.res.Configuration config = new android.content.res.Configuration();
@@ -556,14 +282,10 @@ public class LocaleController {
}
private String getStringInternal(String key, int res) {
String value = localeValues.get(key);
if (value == null) {
try {
value = ApplicationLoader.applicationContext.getString(res);
} catch (Exception e) {
FileLog.e("messenger", e);
}
}
String value = null;
try {
value = ApplicationLoader.applicationContext.getString(res);
} catch (Exception e) { }
if (value == null) {
value = "LOC_ERR:" + key;
}
@@ -574,23 +296,9 @@ public class LocaleController {
return getInstance().getStringInternal(key, res);
}
public static String formatPluralString(String key, int plural) {
if (key == null || key.length() == 0 || getInstance().currentPluralRules == null) {
return "LOC_ERR:" + key;
}
String param = getInstance().stringForQuantity(getInstance().currentPluralRules.quantityForNumber(plural));
param = key + "_" + param;
int resourceId = ApplicationLoader.applicationContext.getResources().getIdentifier(param, "string", ApplicationLoader.applicationContext.getPackageName());
return formatString(param, resourceId, plural);
}
public static String formatString(String key, int res, Object... args) {
try {
String value = getInstance().localeValues.get(key);
if (value == null) {
value = ApplicationLoader.applicationContext.getString(res);
}
String value = ApplicationLoader.applicationContext.getString(res);
if (getInstance().currentLocale != null) {
return String.format(getInstance().currentLocale, value, args);
} else {
@@ -620,6 +328,7 @@ public class LocaleController {
return;
}
is24HourFormat = DateFormat.is24HourFormat(ApplicationLoader.applicationContext);
systemDefaultLocale = newConfig.locale;
if (languageOverride != null) {
LocaleInfo toSet = currentLocaleInfo;
currentLocaleInfo = null;
@@ -633,10 +342,6 @@ public class LocaleController {
recreateFormatters();
}
currentLocale = newLocale;
currentPluralRules = allRules.get(currentLocale.getLanguage());
if (currentPluralRules == null) {
currentPluralRules = allRules.get("en");
}
}
}
}
@@ -659,30 +364,6 @@ public class LocaleController {
return "LOC_ERR: formatDateChat";
}
public static String formatDateAudio(long date) {
try {
Calendar rightNow = Calendar.getInstance();
int day = rightNow.get(Calendar.DAY_OF_YEAR);
int year = rightNow.get(Calendar.YEAR);
rightNow.setTimeInMillis(date * 1000);
int dateDay = rightNow.get(Calendar.DAY_OF_YEAR);
int dateYear = rightNow.get(Calendar.YEAR);
if (dateDay == day && year == dateYear) {
return String.format("%s %s", LocaleController.getString("TodayAt", R.string.TodayAt), getInstance().formatterDay.format(new Date(date * 1000)));
} else if (dateDay + 1 == day && year == dateYear) {
return String.format("%s %s", LocaleController.getString("YesterdayAt", R.string.YesterdayAt), getInstance().formatterDay.format(new Date(date * 1000)));
} else if (year == dateYear) {
return LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, getInstance().formatterMonth.format(new Date(date * 1000)), getInstance().formatterDay.format(new Date(date * 1000)));
} else {
return LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, getInstance().formatterYear.format(new Date(date * 1000)), getInstance().formatterDay.format(new Date(date * 1000)));
}
} catch (Exception e) {
FileLog.e("messenger", e);
}
return "LOC_ERR";
}
private FastDateFormat createFormatter(Locale locale, String format, String defaultFormat) {
if (format == null || format.length() == 0) {
format = defaultFormat;
@@ -744,284 +425,4 @@ public class LocaleController {
}
return "LOC_ERR";
}
/*
public static String formatShortNumber(int number, int[] rounded) {
String K = "";
int lastDec = 0;
int KCount = 0;
while (number / 1000 > 0) {
K += "K";
lastDec = (number % 1000) / 100;
number /= 1000;
}
if (rounded != null) {
double value = number + lastDec / 10.0;
for (int a = 0; a < K.length(); a++) {
value *= 1000;
}
rounded[0] = (int) value;
}
if (lastDec != 0 && K.length() > 0) {
if (K.length() == 2) {
return String.format(Locale.US, "%d.%dM", number, lastDec);
} else {
return String.format(Locale.US, "%d.%d%s", number, lastDec, K);
}
}
if (K.length() == 2) {
return String.format(Locale.US, "%dM", number);
} else {
return String.format(Locale.US, "%d%s", number, K);
}
}
*/
abstract public static class PluralRules {
abstract int quantityForNumber(int n);
}
public static class PluralRules_Zero extends PluralRules {
public int quantityForNumber(int count) {
if (count == 0 || count == 1) {
return QUANTITY_ONE;
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_Welsh extends PluralRules {
public int quantityForNumber(int count) {
if (count == 0) {
return QUANTITY_ZERO;
} else if (count == 1) {
return QUANTITY_ONE;
} else if (count == 2) {
return QUANTITY_TWO;
} else if (count == 3) {
return QUANTITY_FEW;
} else if (count == 6) {
return QUANTITY_MANY;
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_Two extends PluralRules {
public int quantityForNumber(int count) {
if (count == 1) {
return QUANTITY_ONE;
} else if (count == 2) {
return QUANTITY_TWO;
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_Tachelhit extends PluralRules {
public int quantityForNumber(int count) {
if (count >= 0 && count <= 1) {
return QUANTITY_ONE;
} else if (count >= 2 && count <= 10) {
return QUANTITY_FEW;
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_Slovenian extends PluralRules {
public int quantityForNumber(int count) {
int rem100 = count % 100;
if (rem100 == 1) {
return QUANTITY_ONE;
} else if (rem100 == 2) {
return QUANTITY_TWO;
} else if (rem100 >= 3 && rem100 <= 4) {
return QUANTITY_FEW;
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_Romanian extends PluralRules {
public int quantityForNumber(int count) {
int rem100 = count % 100;
if (count == 1) {
return QUANTITY_ONE;
} else if ((count == 0 || (rem100 >= 1 && rem100 <= 19))) {
return QUANTITY_FEW;
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_Polish extends PluralRules {
public int quantityForNumber(int count) {
int rem100 = count % 100;
int rem10 = count % 10;
if (count == 1) {
return QUANTITY_ONE;
} else if (rem10 >= 2 && rem10 <= 4 && !(rem100 >= 12 && rem100 <= 14) && !(rem100 >= 22 && rem100 <= 24)) {
return QUANTITY_FEW;
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_One extends PluralRules {
public int quantityForNumber(int count) {
return count == 1 ? QUANTITY_ONE : QUANTITY_OTHER;
}
}
public static class PluralRules_None extends PluralRules {
public int quantityForNumber(int count) {
return QUANTITY_OTHER;
}
}
public static class PluralRules_Maltese extends PluralRules {
public int quantityForNumber(int count) {
int rem100 = count % 100;
if (count == 1) {
return QUANTITY_ONE;
} else if (count == 0 || (rem100 >= 2 && rem100 <= 10)) {
return QUANTITY_FEW;
} else if (rem100 >= 11 && rem100 <= 19) {
return QUANTITY_MANY;
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_Macedonian extends PluralRules {
public int quantityForNumber(int count) {
if (count % 10 == 1 && count != 11) {
return QUANTITY_ONE;
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_Lithuanian extends PluralRules {
public int quantityForNumber(int count) {
int rem100 = count % 100;
int rem10 = count % 10;
if (rem10 == 1 && !(rem100 >= 11 && rem100 <= 19)) {
return QUANTITY_ONE;
} else if (rem10 >= 2 && rem10 <= 9 && !(rem100 >= 11 && rem100 <= 19)) {
return QUANTITY_FEW;
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_Latvian extends PluralRules {
public int quantityForNumber(int count) {
if (count == 0) {
return QUANTITY_ZERO;
} else if (count % 10 == 1 && count % 100 != 11) {
return QUANTITY_ONE;
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_Langi extends PluralRules {
public int quantityForNumber(int count) {
if (count == 0) {
return QUANTITY_ZERO;
} else if (count > 0 && count < 2) {
return QUANTITY_ONE;
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_French extends PluralRules {
public int quantityForNumber(int count) {
if (count >= 0 && count < 2) {
return QUANTITY_ONE;
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_Czech extends PluralRules {
public int quantityForNumber(int count) {
if (count == 1) {
return QUANTITY_ONE;
} else if (count >= 2 && count <= 4) {
return QUANTITY_FEW;
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_Breton extends PluralRules {
public int quantityForNumber(int count) {
if (count == 0) {
return QUANTITY_ZERO;
} else if (count == 1) {
return QUANTITY_ONE;
} else if (count == 2) {
return QUANTITY_TWO;
} else if (count == 3) {
return QUANTITY_FEW;
} else if (count == 6) {
return QUANTITY_MANY;
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_Balkan extends PluralRules {
public int quantityForNumber(int count) {
int rem100 = count % 100;
int rem10 = count % 10;
if (rem10 == 1 && rem100 != 11) {
return QUANTITY_ONE;
} else if (rem10 >= 2 && rem10 <= 4 && !(rem100 >= 12 && rem100 <= 14)) {
return QUANTITY_FEW;
} else if ((rem10 == 0 || (rem10 >= 5 && rem10 <= 9) || (rem100 >= 11 && rem100 <= 14))) {
return QUANTITY_MANY;
} else {
return QUANTITY_OTHER;
}
}
}
public static class PluralRules_Arabic extends PluralRules {
public int quantityForNumber(int count) {
int rem100 = count % 100;
if (count == 0) {
return QUANTITY_ZERO;
} else if (count == 1) {
return QUANTITY_ONE;
} else if (count == 2) {
return QUANTITY_TWO;
} else if (rem100 >= 3 && rem100 <= 10) {
return QUANTITY_FEW;
} else if (rem100 >= 11 && rem100 <= 99) {
return QUANTITY_MANY;
} else {
return QUANTITY_OTHER;
}
}
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -26,29 +26,13 @@ package com.b44t.messenger;
import android.app.Activity;
import android.content.SharedPreferences;
import com.b44t.ui.ActionBar.BaseFragment;
import com.b44t.ui.SettingsActivity;
import com.b44t.ui.SettingsAdvActivity;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
public class MessagesController implements NotificationCenter.NotificationCenterDelegate {
public class MessagesController {
public ArrayList<TLRPC.TL_dialog> dialogs = new ArrayList<>();
public int nextDialogsCacheOffset;
public ConcurrentHashMap<Long, TLRPC.TL_dialog> dialogs_dict = new ConcurrentHashMap<>(100, 1.0f, 2);
public HashMap<Long, MessageObject> dialogMessage = new HashMap<>();
public HashMap<Long, MessageObject> dialogMessagesByRandomIds = new HashMap<>();
public HashMap<Integer, MessageObject> dialogMessagesByIds = new HashMap<>();
public HashMap<Long, CharSequence> printingStrings = new HashMap<>();
public int secretWebpagePreview = 2;
private String uploadingAvatar = null;
public int fontSize = AndroidUtilities.dp(16);
public int ratingDecay;
public int fontSize;
public static final int UPDATE_MASK_NAME = 1;
public static final int UPDATE_MASK_AVATAR = 2;
@@ -56,8 +40,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter
public static final int UPDATE_MASK_CHAT_AVATAR = 8;
public static final int UPDATE_MASK_CHAT_NAME = 16;
public static final int UPDATE_MASK_CHAT_MEMBERS = 32;
public static final int UPDATE_MASK_USER_PRINT = 64;
public static final int UPDATE_MASK_READ_DIALOG_MESSAGE = 256;
public static final int UPDATE_MASK_SELECT_DIALOG = 512;
public static final int UPDATE_MASK_NEW_MESSAGE = 2048;
public static final int UPDATE_MASK_SEND_STATE = 4096;
@@ -79,121 +61,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter
public MessagesController() {
ImageLoader.getInstance();
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileDidUpload);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileDidFailUpload);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileDidLoaded);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileDidFailedLoad);
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE);
preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
secretWebpagePreview = preferences.getInt("secretWebpage2", 2);
ratingDecay = preferences.getInt("ratingDecay", 2419200);
fontSize = preferences.getInt("msg_font_size", SettingsActivity.defMsgFontSize());
}
/*
public static TLRPC.InputUser getInputUser(TLRPC.User user) {
if (user == null) {
return new TLRPC.TL_inputUserEmpty();
}
TLRPC.InputUser inputUser;
if (user.id == UserConfig.getClientUserId()) {
inputUser = new TLRPC.TL_inputUserSelf();
} else {
inputUser = new TLRPC.TL_inputUser();
inputUser.user_id = user.id;
}
return inputUser;
}
public static TLRPC.InputUser getInputUser(int user_id) {
TLRPC.User user = getInstance().getUser(user_id);
return getInputUser(user);
}
*/
public static TLRPC.InputPeer getInputPeer(int id) {
TLRPC.InputPeer inputPeer;
{
inputPeer = new TLRPC.TL_inputPeerUser();
inputPeer.user_id = id;
}
return inputPeer;
}
public static TLRPC.Peer getPeer(int id) {
TLRPC.Peer inputPeer;
/*if (id < 0) {
inputPeer = new TLRPC.TL_peerChat();
inputPeer.chat_id = -id;
} else*/ {
inputPeer = new TLRPC.TL_peerUser();
inputPeer.user_id = id;
}
return inputPeer;
}
@Override
public void didReceivedNotification(int id, Object... args) {
if (id == NotificationCenter.FileDidUpload) {
final String location = (String) args[0];
final TLRPC.InputFile file = (TLRPC.InputFile) args[1];
if (uploadingAvatar != null && uploadingAvatar.equals(location)) {
/*TLRPC.TL_photos_uploadProfilePhoto req = new TLRPC.TL_photos_uploadProfilePhoto();
req.caption = "";
req.crop = new TLRPC.TL_inputPhotoCropAuto();
req.file = file;
req.geo_point = new TLRPC.TL_inputGeoPointEmpty();*/
/*ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
@Override
public void run(TLObject response, TLRPC.TL_error error) {
if (error == null) {
TLRPC.User user = getUser(UserConfig.getClientUserId());
if (user == null) {
user = UserConfig.getCurrentUser();
putUser(user, true);
} else {
UserConfig.setCurrentUser(user);
}
if (user == null) {
return;
}
TLRPC.TL_photos_photo photo = (TLRPC.TL_photos_photo) response;
ArrayList<TLRPC.PhotoSize> sizes = photo.photo.sizes;
TLRPC.PhotoSize smallSize = FileLoader.getClosestPhotoSizeWithSize(sizes, 100);
TLRPC.PhotoSize bigSize = FileLoader.getClosestPhotoSizeWithSize(sizes, 1000);
user.photo = new TLRPC.TL_userProfilePhoto();
user.photo.photo_id = photo.photo.id;
if (smallSize != null) {
user.photo.photo_small = smallSize.location;
}
if (bigSize != null) {
user.photo.photo_big = bigSize.location;
} else if (smallSize != null) {
user.photo.photo_small = smallSize.location;
}
//MessagesStorage.getInstance().clearUserPhotos(user.id);
ArrayList<TLRPC.User> users = new ArrayList<>();
users.add(user);
//MessagesStorage.getInstance().putUsersAndChats(users, null, false, true);
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.updateInterfaces, UPDATE_MASK_AVATAR);
UserConfig.saveConfig(true);
}
});
}
}
});*/
}
} else if (id == NotificationCenter.FileDidFailUpload) {
final String location = (String) args[0];
if (uploadingAvatar != null && uploadingAvatar.equals(location)) {
uploadingAvatar = null;
}
}
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
fontSize = preferences.getInt("msg_font_size", SettingsAdvActivity.defMsgFontSize());
}
public TLRPC.User getUser(Integer id) {
@@ -203,14 +73,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter
return u;
}
public TLRPC.Chat getChat(Integer id) {
return null;
}
public void deleteMessages(ArrayList<Integer> messages, ArrayList<Long> randoms, Object encryptedChat, final int channelId) {
}
public MediaController.SearchImage saveGif(TLRPC.Document document) {
MediaController.SearchImage searchImage = new MediaController.SearchImage();
searchImage.type = 2;
@@ -244,9 +106,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter
public void markMessageContentAsRead(final MessageObject messageObject) {
}
public void addUserToChat(final int chat_id, final TLRPC.User user, final TLRPC.ChatFull info, int count_fwd, String botHash, final BaseFragment fragment) {
}
public void changeChatAvatar(int chat_id, TLRPC.InputFile uploadedAvatar) {
/*TLObject request;
{
@@ -285,89 +144,4 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
return false;
}
protected void updateInterfaceWithMessages(long uid, ArrayList<MessageObject> messages) {
updateInterfaceWithMessages(uid, messages, false);
}
protected static void addNewGifToRecent(TLRPC.Document document, int date) {
ArrayList<MediaController.SearchImage> arrayList = new ArrayList<>();
MediaController.SearchImage searchImage = new MediaController.SearchImage();
searchImage.type = 2;
searchImage.document = document;
searchImage.date = date;
searchImage.id = "" + searchImage.document.id;
arrayList.add(searchImage);
}
protected void updateInterfaceWithMessages(final long uid, final ArrayList<MessageObject> messages, boolean isBroadcast) {
if (messages == null || messages.isEmpty()) {
return;
}
final boolean isEncryptedChat = false;
MessageObject lastMessage = null;
int channelId = 0;
for (int a = 0; a < messages.size(); a++) {
MessageObject message = messages.get(a);
if (lastMessage == null || (!isEncryptedChat && message.getId() > lastMessage.getId() || (isEncryptedChat || message.getId() < 0 && lastMessage.getId() < 0) && message.getId() < lastMessage.getId()) || message.messageOwner.date > lastMessage.messageOwner.date) {
lastMessage = message;
}
if (message.isOut() && message.isNewGif() && !message.isSending() && !message.isForwarded()) {
addNewGifToRecent(message.messageOwner.media.document, message.messageOwner.date);
}
}
//MessagesQuery.loadReplyMessagesForMessages(messages, uid);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.didReceivedNewMessages, uid, messages);
if (lastMessage == null) {
return;
}
TLRPC.TL_dialog dialog = dialogs_dict.get(uid);
if (dialog == null) {
if (!isBroadcast) {
TLRPC.Chat chat = getChat(channelId);
if (channelId != 0 && chat == null || chat != null && false/*chat.left*/) {
return;
}
dialog = new TLRPC.TL_dialog();
dialog.id = uid;
dialog.unread_count = 0;
dialog.top_message = lastMessage.getId();
dialog.last_message_date = lastMessage.messageOwner.date;
//dialog.flags = ChatObject.isChannel(chat) ? 1 : 0;
dialogs_dict.put(uid, dialog);
dialogs.add(dialog);
dialogMessage.put(uid, lastMessage);
if (lastMessage.messageOwner.to_id.channel_id == 0) {
dialogMessagesByIds.put(lastMessage.getId(), lastMessage);
if (lastMessage.messageOwner.random_id != 0) {
dialogMessagesByRandomIds.put(lastMessage.messageOwner.random_id, lastMessage);
}
}
nextDialogsCacheOffset++;
}
} else {
if ((dialog.top_message > 0 && lastMessage.getId() > 0 && lastMessage.getId() > dialog.top_message) ||
(dialog.top_message < 0 && lastMessage.getId() < 0 && lastMessage.getId() < dialog.top_message) ||
!dialogMessage.containsKey(uid) || dialog.top_message < 0 || dialog.last_message_date <= lastMessage.messageOwner.date) {
MessageObject object = dialogMessagesByIds.remove(dialog.top_message);
if (object != null && object.messageOwner.random_id != 0) {
dialogMessagesByRandomIds.remove(object.messageOwner.random_id);
}
dialog.top_message = lastMessage.getId();
if (!isBroadcast) {
dialog.last_message_date = lastMessage.messageOwner.date;
}
dialogMessage.put(uid, lastMessage);
if (lastMessage.messageOwner.to_id.channel_id == 0) {
dialogMessagesByIds.put(lastMessage.getId(), lastMessage);
if (lastMessage.messageOwner.random_id != 0) {
dialogMessagesByRandomIds.put(lastMessage.messageOwner.random_id, lastMessage);
}
}
}
}
}
}
@@ -76,13 +76,9 @@ public class MrChat {
return MrChatGetTotalMsgCount(m_hChat);
}
public int sendText(String text) {
return MrChatSendText(m_hChat, text);
}
public native int sendText(String text);
public int sendMedia(int type, String file, String mime, int w, int h, int time_ms) {
return MrChatSendMedia(m_hChat, type, file, mime, w, h, time_ms);
}
public native int sendMedia(int type, String file, String mime, int w, int h, int time_ms, String author, String trackname);
private long m_hChat; // must not be renamed as referenced by JNI under the name "m_hChat"
private native static void MrChatUnref (long hChat);
@@ -92,8 +88,6 @@ public class MrChat {
private native static int MrChatSetDraft (long hChat, String draft/*NULL=delete*/, long replyToMsgId);
private native static int MrChatGetUnseenCount (long hChat);
private native static int MrChatGetTotalMsgCount (long hChat);
private native static int MrChatSendText (long hChat, String text); // returns message id
private native static int MrChatSendMedia (long hChat, int type, String file, String mime, int w, int h, int time_ms);
/* additional functions that are not 1:1 available in the backend
@@ -28,6 +28,13 @@
package com.b44t.messenger;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class MrMailbox {
public static void init () {
@@ -38,53 +45,24 @@ public class MrMailbox {
public native static void close();
public native static String getBlobdir();
public static int configure() {
return MrMailboxConfigure(m_hMailbox);
}
public native static void configureAndConnect();
public native static void configureCancel();
public static int isConfigured() {
return MrMailboxIsConfigured(m_hMailbox);
}
public native static int isConfigured();
public static int connect() {
return MrMailboxConnect(m_hMailbox);
}
public native static void connect();
public native static void disconnect();
public static void disconnect() {
MrMailboxDisconnect(m_hMailbox);
}
public static int fetch() {
return MrMailboxFetch(m_hMailbox);
}
public native static String getErrorDescr();
public static int setConfig(String key, String value) {
return MrMailboxSetConfig(m_hMailbox, key, value);
}
public static String getConfig(String key, String def) {
return MrMailboxGetConfig(m_hMailbox, key, def);
}
public static int getConfigInt(String key, int def) {
return MrMailboxGetConfigInt(m_hMailbox, key, def);
}
public native static void setConfig(String key, String value);
public native static void setConfigInt(String key, int value);
public native static String getConfig(String key, String def);
public native static int getConfigInt(String key, int def);
public native static String getInfo();
public native static String cmdline(String cmd);
private static long m_hMailbox = 0; // do not rename this, is used in C-part
private native static long MrMailboxNew (); // returns hMailbox which must be unref'd after usage (Names as mrmailbox_new don't work due to the additional underscore)
private native static int MrMailboxConfigure (long hMailbox);
private native static int MrMailboxIsConfigured (long hMailbox);
private native static int MrMailboxConnect (long hMailbox);
private native static void MrMailboxDisconnect (long hMailbox);
private native static int MrMailboxFetch (long hMailbox);
private native static int MrMailboxSetConfig (long hMailbox, String key, String value); // value may be NULL
private native static String MrMailboxGetConfig (long hMailbox, String key, String def); // def may be NULL, returns empty string as NULL
private native static int MrMailboxGetConfigInt (long hMailbox, String key, int def); // def may be NULL, returns empty string as NULL
private native static long MrMailboxNew(); // returns hMailbox which must be unref'd after usage (Names as mrmailbox_new don't work due to the additional underscore)
// contacts
public native static int[] getKnownContacts(String query);
@@ -139,6 +117,7 @@ public class MrMailbox {
}
public native static int createGroupChat (String name);
public native static int isContactInChat (int chat_id, int contact_id);
public native static int addContactToChat (int chat_id, int contact_id);
public native static int removeContactFromChat (int chat_id, int contact_id);
public native static int setChatName (int chat_id, String name);
@@ -150,10 +129,8 @@ public class MrMailbox {
public native static int[] getUnseenMsgs();
public static int[] getChatMedia(int chat_id, int msg_type, int or_msg_type) {
return MrMailboxGetChatMedia(m_hMailbox, chat_id, msg_type, or_msg_type);
}
public native static int[] getChatMedia(int chat_id, int msg_type, int or_msg_type);
public native static int getNextMedia(int msg_id, int dir);
public native static int[] getChatContacts(int chat_id);
public native static int deleteChat(int chat_id);
@@ -161,7 +138,6 @@ public class MrMailbox {
private native static long MrMailboxGetChat (long hMailbox, int chat_id); // return hChat which must be unref'd after usage
private native static int MrMailboxGetChatIdByContactId (long hMailbox, int contact_id);
private native static int MrMailboxCreateChatByContactId(long hMailbox, int contact_id); // returns chat_id
private native static int[] MrMailboxGetChatMedia (long hMailbox, int chat_id, int msg_type, int or_msg_type);
// msgs
@@ -180,33 +156,55 @@ public class MrMailbox {
private native static String MrMailboxGetMsgInfo (long hMailbox, int id);
// static
private native static void MrStockAddStr (int id, String str);
public native static String MrGetVersionStr ();
public native static String CPtr2String (long hString); // get strings eg. from data1 from the callback
public native static long String2CPtr (String str);
/* receive events
**********************************************************************************************/
public final static int MR_EVENT_ERROR = 400; // INFO and WARNING are blocked in the mrwrapper.c
public final static int MR_EVENT_MSGS_CHANGED = 2000;
public final static int MR_EVENT_INCOMING_MSG = 2005;
public final static int MR_EVENT_MSG_DELIVERED = 2010;
public final static int MR_EVENT_MSG_READ = 2015;
public final static int MR_EVENT_CHAT_MODIFIED = 2020;
public final static int MR_EVENT_CONTACTS_CHANGED = 2030;
public final static int MR_EVENT_CONNECTION_STATE_CHANGED = 2040;
public final static int MR_EVENT_REPORT = 2050;
public final static int MR_REPORT_ERR_SELF_NOT_IN_GROUP = 1;
public final static int MR_EVENT_CHAT_MODIFIED = 2020;
public final static int MR_EVENT_CONTACTS_CHANGED = 2030;
public final static int MR_EVENT_CONFIGURE_ENDED = 2040;
public final static int MR_EVENT_CONFIGURE_PROGRESS = 2041;
public final static int MR_EVENT_IS_ONLINE = 2080;
public final static int MR_EVENT_GET_STRING = 2091;
public final static int MR_EVENT_GET_QUANTITIY_STRING = 2092;
public final static int MR_EVENT_HTTP_GET = 2100;
public static final Object m_lastErrorLock = new Object();
public static int m_lastErrorCode = 0;
public static String m_lastErrorString = "";
public static boolean m_showNextErrorAsToast = true;
public static long MrCallback(final int event, final long data1, final long data2) // this function is called from within the C-wrapper
{
switch(event) {
case MR_EVENT_CONNECTION_STATE_CHANGED:
case MR_EVENT_CONFIGURE_ENDED:
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.connectionStateChanged, (int)data1);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.configureEnded, (int)data1);
}
});
return 0;
case MR_EVENT_CONFIGURE_PROGRESS:
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.configureProgress, (int)data1);
}
});
return 0;
@@ -261,16 +259,83 @@ public class MrMailbox {
});
return 0;
case MR_EVENT_REPORT:
case MR_EVENT_ERROR:
synchronized (m_lastErrorLock) {
m_lastErrorCode = (int)data1;
m_lastErrorString = CPtr2String(data2);
}
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
if(data1==MR_REPORT_ERR_SELF_NOT_IN_GROUP) {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.errSelfNotInGroup);
synchronized (m_lastErrorLock) {
if( m_showNextErrorAsToast ) {
AndroidUtilities.showHint(ApplicationLoader.applicationContext, m_lastErrorString);
}
m_showNextErrorAsToast = true;
}
}
});
return 0;
case MR_EVENT_GET_STRING:
String s = "ErrStrBadId";
switch( (int)data1 ) {
// the string-IDs are defined in the backend; as this is the only place where they're used, there is no benefit in creating an enum or sth. like that.
case 1: s = ApplicationLoader.applicationContext.getString(R.string.NoMessages); break;
case 2: s = ApplicationLoader.applicationContext.getString(R.string.FromSelf); break;
case 3: s = ApplicationLoader.applicationContext.getString(R.string.Draft); break;
case 7: s = ApplicationLoader.applicationContext.getString(R.string.AttachVoiceMessage); break;
case 8: s = ApplicationLoader.applicationContext.getString(R.string.Deaddrop); break;
case 9: s = ApplicationLoader.applicationContext.getString(R.string.AttachPhoto); break;
case 10: s = ApplicationLoader.applicationContext.getString(R.string.AttachVideo); break;
case 11: s = ApplicationLoader.applicationContext.getString(R.string.AttachMusic); break;
case 12: s = ApplicationLoader.applicationContext.getString(R.string.AttachDocument); break;
case 13: s = ApplicationLoader.applicationContext.getString(R.string.DefaultStatusText); break;
case 14: s = ApplicationLoader.applicationContext.getString(R.string.MsgNewGroupDraft); break;
case 15: s = ApplicationLoader.applicationContext.getString(R.string.MsgGroupNameChanged); break;
case 16: s = ApplicationLoader.applicationContext.getString(R.string.MsgGroupImageChanged); break;
case 17: s = ApplicationLoader.applicationContext.getString(R.string.MsgMemberAddedToGroup); break;
case 18: s = ApplicationLoader.applicationContext.getString(R.string.MsgMemberRemovedFromToGroup); break;
case 19: s = ApplicationLoader.applicationContext.getString(R.string.MsgGroupLeft); break;
case 20: s = ApplicationLoader.applicationContext.getString(R.string.Error); break;
case 21: s = ApplicationLoader.applicationContext.getString(R.string.ErrSelfNotInGroup); break;
case 22: s = ApplicationLoader.applicationContext.getString(R.string.NoNetwork); break;
}
return String2CPtr(s);
case MR_EVENT_GET_QUANTITIY_STRING:
String sp = "ErrQtyStrBadId";
switch( (int)data1 ) {
// the string-IDs are defined in the backend; as this is the only place where they're used, there is no benefit in creating an enum or sth. like that.
case 4: sp = ApplicationLoader.applicationContext.getResources().getQuantityString(R.plurals.Members, (int)data2, (int)data2); break;
case 6: sp = ApplicationLoader.applicationContext.getResources().getQuantityString(R.plurals.Contacts, (int)data2, (int)data2); break;
}
return String2CPtr(sp);
case MR_EVENT_IS_ONLINE:
return ConnectionsManager.isNetworkOnline()? 1 : 0;
case MR_EVENT_HTTP_GET:
String httpContent = null;
try {
URL url = new URL(CPtr2String(data1));
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
InputStream inputStream = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader r = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder total = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
total.append(line).append('\n');
}
httpContent = total.toString();
} finally {
urlConnection.disconnect();
}
}
catch(Exception e) {}
return String2CPtr(httpContent);
}
return 0;
}
@@ -304,29 +369,6 @@ public class MrMailbox {
});
}
public static void initStockStrings()
{
MrStockAddStr(1, LocaleController.getString("NoMessages", R.string.NoMessages));
MrStockAddStr(2, LocaleController.getString("FromSelf", R.string.FromSelf));
MrStockAddStr(3, LocaleController.getString("Draft", R.string.Draft));
MrStockAddStr(4, LocaleController.getString("MemberSg", R.string.MemberSg));
MrStockAddStr(5, LocaleController.getString("MemberPl", R.string.MemberPl));
MrStockAddStr(6, LocaleController.getString("ContactSg", R.string.ContactSg));
MrStockAddStr(7, LocaleController.getString("ContactPl", R.string.ContactPl));
MrStockAddStr(8, LocaleController.getString("Deaddrop", R.string.Deaddrop));
MrStockAddStr(9, LocaleController.getString("AttachPhoto", R.string.AttachPhoto));
MrStockAddStr(10, LocaleController.getString("AttachVideo", R.string.AttachVideo));
MrStockAddStr(11, LocaleController.getString("AttachAudio", R.string.AttachAudio));
MrStockAddStr(12, LocaleController.getString("AttachDocument", R.string.AttachDocument));
MrStockAddStr(13, LocaleController.getString("DefaultStatusText", R.string.DefaultStatusText));
MrStockAddStr(14, LocaleController.getString("MsgNewGroupDraft", R.string.MsgNewGroupDraft));
MrStockAddStr(15, LocaleController.getString("MsgGroupNameChanged", R.string.MsgGroupNameChanged));
MrStockAddStr(16, LocaleController.getString("MsgGroupImageChanged", R.string.MsgGroupImageChanged));
MrStockAddStr(17, LocaleController.getString("MsgMemberAddedToGroup", R.string.MsgMemberAddedToGroup));
MrStockAddStr(18, LocaleController.getString("MsgMemberRemovedFromToGroup", R.string.MsgMemberRemovedFromToGroup));
MrStockAddStr(19, LocaleController.getString("MsgGroupLeft", R.string.MsgGroupLeft));
}
public static String getInviteText() {
String url = "https://getdelta.org";
String email = getConfig("addr", "");
@@ -27,8 +27,13 @@
package com.b44t.messenger;
import android.graphics.Bitmap;
import android.media.ThumbnailUtils;
import android.provider.MediaStore;
import android.util.Log;
import java.io.File;
public class MrMsg {
private static final String TAG = "MrMsg";
@@ -37,6 +42,7 @@ public class MrMsg {
public final static int MR_MSG_TEXT = 10;
public final static int MR_MSG_IMAGE = 20;
public final static int MR_MSG_AUDIO = 40;
public final static int MR_MSG_VOICE = 41;
public final static int MR_MSG_VIDEO = 50;
public final static int MR_MSG_FILE = 60;
@@ -90,17 +96,19 @@ public class MrMsg {
return MrMsgGetToId(m_hMsg);
}
public String getParam (int key, String def) {
return MrMsgGetParam(m_hMsg, key, def);
}
public int getParamInt(int key, int def) {
return MrMsgGetParamInt(m_hMsg, key, def);
}
public native String getParam(int key, String def);
public native int getParamInt(int key, int def);
public native void setParamInt(int key, int def);
public native void saveParamToDisk();
public native int getBytes();
public MrPoortext getSummary(MrChat chat) { return new MrPoortext(getSummaryCPtr(chat.getCPtr())); }
private native long getSummaryCPtr(long hChat);
public native String getSummarytext(int approx_characters);
public MrPoortext getMediainfo() { return new MrPoortext(getMediainfoCPtr()); }
private native long getMediainfoCPtr();
public native String getFilename();
public native int isIncreation();
private long m_hMsg; // must not be renamed as referenced by JNI under the name "m_hMsg"
private native static void MrMsgUnref (long hMsg);
@@ -112,8 +120,6 @@ public class MrMsg {
private native static int MrMsgGetChatId (long hMsg);
private native static int MrMsgGetFromId (long hMsg);
private native static int MrMsgGetToId (long hMsg);
private native static String MrMsgGetParam (long hMsg, int key, String def);
private native static int MrMsgGetParamInt (long hMsg, int key, int def);
/* additional functions that are not 1:1 available in the backend
@@ -143,7 +149,6 @@ public class MrMsg {
ret.unread = state!=MR_OUT_READ; // the state of outgoing messages
ret.media_unread = ret.unread;
ret.flags = 0; // posible flags: MESSAGE_FLAG_HAS_FROM_ID, however, this seems to be read only
ret.post = false; // ? true=avatar wird in gruppen nicht angezeigt, wird aber in isFromUser() auch überprüft...
ret.out = ret.from_id==MrContact.MR_CONTACT_ID_SELF; // true=outgoing message, read eg. in MessageObject.isOutOwner()
ret.created_by_mr = true;
@@ -190,31 +195,63 @@ public class MrMsg {
ret.message = "<cannot load image>";
}
}
else if( type == MR_MSG_AUDIO || type == MR_MSG_VIDEO ) {
else if( type == MR_MSG_AUDIO || type == MR_MSG_VOICE || type == MR_MSG_VIDEO || type == MR_MSG_FILE ) {
String path = getParam('f', "");
if( !path.isEmpty()) {
ret.message = "-1"; // may be misused for video editing information
ret.media = new TLRPC.TL_messageMediaDocument();
ret.media.caption = "";
ret.media.document = new TLRPC.TL_document();
ret.media.document.file_name = getFilename();
ret.media.document.mr_path = path;
if( type == MR_MSG_AUDIO ) {
ret.media.document.size = getBytes();
if( type == MR_MSG_AUDIO || type == MR_MSG_VOICE ) {
TLRPC.TL_documentAttributeAudio attr = new TLRPC.TL_documentAttributeAudio();
attr.voice = true; // !voice = music
attr.voice = type == MR_MSG_VOICE;
attr.duration = getParamInt('d', 0) / 1000;
ret.media.document.attributes.add(attr);
}
else if( type == MR_MSG_VIDEO) {
else if( type == MR_MSG_VIDEO ) {
File vfile = new File(path);
File tfile = new File(MrMailbox.getBlobdir(), vfile.getName()+"-preview.jpg");
if( !tfile.exists() ) {
try {
Bitmap thumb = ThumbnailUtils.createVideoThumbnail(path, MediaStore.Video.Thumbnails.MINI_KIND);
TLRPC.PhotoSize size = ImageLoader.scaleAndSaveImage(tfile, thumb, 90, 90, 55, false);
size.location.mr_path = tfile.getAbsolutePath();
size.type = "s";
ret.media.document.thumb = size;
setParamInt('w', size.w);
setParamInt('h', size.h);
saveParamToDisk();
}
catch (Exception e) {}
}
else {
TLRPC.PhotoSize size = new TLRPC.PhotoSize();
size.location = new TLRPC.TL_fileLocation();
size.location.mr_path = tfile.getAbsolutePath();
size.location.local_id = -ret.id;
size.w = getParamInt('w', 320);
size.h = getParamInt('h', 240);
size.type = "s";
ret.media.document.thumb = size;
}
TLRPC.TL_documentAttributeVideo attr = new TLRPC.TL_documentAttributeVideo();
attr.duration = getParamInt('d', 0) / 1000;
attr.w = getParamInt('w', 0);
attr.h = getParamInt('h', 0);
attr.w = getParamInt('w', 320);
attr.h = getParamInt('h', 240);
ret.media.document.attributes.add(attr);
}
else {
ret.media.document.mime_type = getParam('m', "application/octet-stream");
}
}
else {
ret.message = "<path missing>";
ret.message = "<file path missing>";
}
}
else {
@@ -30,10 +30,10 @@ package com.b44t.messenger;
public class MrPoortext {
public final static int MR_TITLE_NORMAL = 0;
public final static int MR_TITLE_DRAFT = 1;
public final static int MR_TITLE_USERNAME = 2;
public final static int MR_TITLE_SELF = 3;
public final static int MR_TEXT1_NORMAL = 0;
public final static int MR_TEXT1_DRAFT = 1;
public final static int MR_TEXT1_USERNAME = 2;
public final static int MR_TEXT1_SELF = 3;
public MrPoortext(long hPoortext) {
m_hPoortext = hPoortext;
@@ -44,16 +44,16 @@ public class MrPoortext {
MrPoortextUnref(m_hPoortext);
}
public String getTitle() {
return MrPoortextGetTitle(m_hPoortext);
public String getText1() {
return MrPoortextGetText1(m_hPoortext);
}
public int getTitleMeaning() {
return MrPoortextGetTitleMeaning(m_hPoortext);
public int getText1Meaning() {
return MrPoortextGetText1Meaning(m_hPoortext);
}
public String getText() {
return MrPoortextGetText(m_hPoortext);
public String getText2() {
return MrPoortextGetText2(m_hPoortext);
}
public long getTimestamp() {
@@ -66,9 +66,9 @@ public class MrPoortext {
private long m_hPoortext;
private native static void MrPoortextUnref (long hPoortext);
private native static String MrPoortextGetTitle (long hPoortext);
private native static int MrPoortextGetTitleMeaning (long hPoortext);
private native static String MrPoortextGetText (long hPoortext);
private native static String MrPoortextGetText1 (long hPoortext);
private native static int MrPoortextGetText1Meaning (long hPoortext);
private native static String MrPoortextGetText2 (long hPoortext);
private native static long MrPoortextGetTimestamp (long hPoortext);
private native static int MrPoortextGetState (long hPoortext);
}
@@ -1,604 +0,0 @@
/*******************************************************************************
*
* Messenger Android Frontend
* (C) 2013-2016 Nikolai Kudashov
* (C) 2017 Björn Petersen
* Contact: r10s@b44t.com, http://b44t.com
*
* This program 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.
*
* This program 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
* this program. If not, see http://www.gnu.org/licenses/ .
*
******************************************************************************/
package com.b44t.messenger;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.media.MediaDescription;
import android.media.MediaMetadata;
import android.media.browse.MediaBrowser;
import android.media.session.MediaSession;
import android.media.session.PlaybackState;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Process;
import android.os.SystemClock;
import android.service.media.MediaBrowserService;
import com.b44t.messenger.audioinfo.AudioInfo;
import com.b44t.ui.LaunchActivity;
import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class MusicBrowserService extends MediaBrowserService implements NotificationCenter.NotificationCenterDelegate {
private static final String AUTO_APP_PACKAGE_NAME = "com.google.android.projection.gearhead";
private static final String SLOT_RESERVATION_SKIP_TO_NEXT = "com.google.android.gms.car.media.ALWAYS_RESERVE_SPACE_FOR.ACTION_SKIP_TO_NEXT";
private static final String SLOT_RESERVATION_SKIP_TO_PREV = "com.google.android.gms.car.media.ALWAYS_RESERVE_SPACE_FOR.ACTION_SKIP_TO_PREVIOUS";
private static final String SLOT_RESERVATION_QUEUE = "com.google.android.gms.car.media.ALWAYS_RESERVE_SPACE_FOR.ACTION_QUEUE";
private MediaSession mediaSession;
private static final String MEDIA_ID_ROOT = "__ROOT__";
private boolean chatsLoaded;
private boolean loadingChats;
private ArrayList<Integer> dialogs = new ArrayList<>();
private HashMap<Integer, TLRPC.User> users = new HashMap<>();
private HashMap<Integer, TLRPC.Chat> chats = new HashMap<>();
private HashMap<Integer, ArrayList<MessageObject>> musicObjects = new HashMap<>();
private HashMap<Integer, ArrayList<MediaSession.QueueItem>> musicQueues = new HashMap<>();
public static final String ACTION_CMD = "com.example.android.mediabrowserservice.ACTION_CMD";
public static final String CMD_NAME = "CMD_NAME";
public static final String CMD_PAUSE = "CMD_PAUSE";
private Paint roundPaint;
private RectF bitmapRect;
private boolean serviceStarted;
private int lastSelectedDialog;
private static final int STOP_DELAY = 30000;
private DelayedStopHandler delayedStopHandler = new DelayedStopHandler(this);
@Override
public void onCreate() {
super.onCreate();
ApplicationLoader.postInitApplication();
lastSelectedDialog = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE).getInt("auto_lastSelectedDialog", 0);
mediaSession = new MediaSession(this, "MusicService");
setSessionToken(mediaSession.getSessionToken());
mediaSession.setCallback(new MediaSessionCallback());
mediaSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS | MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);
Context context = getApplicationContext();
Intent intent = new Intent(context, LaunchActivity.class);
PendingIntent pi = PendingIntent.getActivity(context, 99, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mediaSession.setSessionActivity(pi);
Bundle extras = new Bundle();
extras.putBoolean(SLOT_RESERVATION_QUEUE, true);
extras.putBoolean(SLOT_RESERVATION_SKIP_TO_PREV, true);
extras.putBoolean(SLOT_RESERVATION_SKIP_TO_NEXT, true);
mediaSession.setExtras(extras);
updatePlaybackState(null);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.audioPlayStateChanged);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.audioDidStarted);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.audioDidReset);
}
@Override
public int onStartCommand(Intent startIntent, int flags, int startId) {
/*if (startIntent != null) {
String action = startIntent.getAction();
String command = startIntent.getStringExtra(CMD_NAME);
if (ACTION_CMD.equals(action)) {
if (CMD_PAUSE.equals(command)) {
if (mPlayback != null && mPlayback.isPlaying()) {
handlePauseRequest();
}
}
}
}*/
return START_STICKY;
}
@Override
public void onDestroy() {
handleStopRequest(null);
delayedStopHandler.removeCallbacksAndMessages(null);
mediaSession.release();
}
@Override
public BrowserRoot onGetRoot(String clientPackageName, int clientUid, Bundle rootHints) {
if (clientPackageName == null || Process.SYSTEM_UID != clientUid && Process.myUid() != clientUid && !clientPackageName.equals("com.google.android.mediasimulator") && !clientPackageName.equals("com.google.android.projection.gearhead")) {
return null;
}
return new BrowserRoot(MEDIA_ID_ROOT, null);
}
@Override
public void onLoadChildren(final String parentMediaId, final Result<List<MediaBrowser.MediaItem>> result) {
if (!chatsLoaded) {
result.detach();
if (loadingChats) {
return;
}
loadingChats = true;
/*
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@Override
public void run() {
try {
ArrayList<Integer> usersToLoad = new ArrayList<>();
ArrayList<Integer> chatsToLoad = new ArrayList<>();
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT DISTINCT uid FROM media_v2 WHERE uid != 0 AND mid > 0 AND type = %d", SharedMediaQuery.MEDIA_MUSIC));
while (cursor.next()) {
int lower_part = (int) cursor.longValue(0);
if (lower_part == 0) {
continue;
}
dialogs.add(lower_part);
if (lower_part > 0) {
usersToLoad.add(lower_part);
} else {
chatsToLoad.add(-lower_part);
}
}
cursor.dispose();
if (!dialogs.isEmpty()) {
String ids = TextUtils.join(",", dialogs);
cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT uid, data, mid FROM media_v2 WHERE uid IN (%s) AND mid > 0 AND type = %d ORDER BY date DESC, mid DESC", ids, SharedMediaQuery.MEDIA_MUSIC));
while (cursor.next()) {
NativeByteBuffer data = cursor.byteBufferValue(1);
if (data != null) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
if (MessageObject.isMusicMessage(message)) {
int did = cursor.intValue(0);
message.id = cursor.intValue(2);
message.dialog_id = did;
ArrayList<MessageObject> arrayList = musicObjects.get(did);
ArrayList<MediaSession.QueueItem> arrayList1 = musicQueues.get(did);
if (arrayList == null) {
arrayList = new ArrayList<>();
musicObjects.put(did, arrayList);
arrayList1 = new ArrayList<>();
musicQueues.put(did, arrayList1);
}
MessageObject messageObject = new MessageObject(message, null, false);
arrayList.add(0, messageObject);
MediaDescription.Builder builder = new MediaDescription.Builder().setMediaId(did + "_" + arrayList.size());
builder.setTitle(messageObject.getMusicTitle());
builder.setSubtitle(messageObject.getMusicAuthor());
arrayList1.add(0, new MediaSession.QueueItem(builder.build(), arrayList1.size()));
}
}
}
cursor.dispose();
if (!usersToLoad.isEmpty()) {
ArrayList<TLRPC.User> usersArrayList = new ArrayList<>();
//MessagesStorage.getInstance().getUsersInternal(TextUtils.join(",", usersToLoad), usersArrayList);
for (int a = 0; a < usersArrayList.size(); a++) {
TLRPC.User user = usersArrayList.get(a);
users.put(user.id, user);
}
}
if (!chatsToLoad.isEmpty()) {
ArrayList<TLRPC.Chat> chatsArrayList = new ArrayList<>();
//MessagesStorage.getInstance().getChatsInternal(TextUtils.join(",", chatsToLoad), chatsArrayList);
for (int a = 0; a < chatsArrayList.size(); a++) {
TLRPC.Chat chat = chatsArrayList.get(a);
chats.put(chat.id, chat);
}
}
}
} catch (Exception e) {
FileLog.e("messenger", e);
}
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
chatsLoaded = true;
loadingChats = false;
loadChildrenImpl(parentMediaId, result);
if (lastSelectedDialog == 0 && !dialogs.isEmpty()) {
lastSelectedDialog = dialogs.get(0);
}
if (lastSelectedDialog != 0) {
ArrayList<MessageObject> arrayList = musicObjects.get(lastSelectedDialog);
ArrayList<MediaSession.QueueItem> arrayList1 = musicQueues.get(lastSelectedDialog);
if (arrayList != null && !arrayList.isEmpty()) {
mediaSession.setQueue(arrayList1);
if (lastSelectedDialog > 0) {
TLRPC.User user = users.get(lastSelectedDialog);
if (user != null) {
mediaSession.setQueueTitle(ContactsController.formatName(user.first_name, user.last_name));
} else {
mediaSession.setQueueTitle("DELETED USER");
}
} else {
TLRPC.Chat chat = chats.get(-lastSelectedDialog);
if (chat != null) {
mediaSession.setQueueTitle(chat.title);
} else {
mediaSession.setQueueTitle("DELETED CHAT");
}
}
MessageObject messageObject = arrayList.get(0);
MediaMetadata.Builder builder = new MediaMetadata.Builder();
builder.putLong(MediaMetadata.METADATA_KEY_DURATION, messageObject.getDuration() * 1000);
builder.putString(MediaMetadata.METADATA_KEY_ARTIST, messageObject.getMusicAuthor());
builder.putString(MediaMetadata.METADATA_KEY_TITLE, messageObject.getMusicTitle());
mediaSession.setMetadata(builder.build());
}
}
updatePlaybackState(null);
}
});
}
});
*/
} else {
loadChildrenImpl(parentMediaId, result);
}
}
private void loadChildrenImpl(final String parentMediaId, final Result<List<MediaBrowser.MediaItem>> result) {
List<MediaBrowser.MediaItem> mediaItems = new ArrayList<>();
if (MEDIA_ID_ROOT.equals(parentMediaId)) {
for (int a = 0; a < dialogs.size(); a++) {
int did = dialogs.get(a);
MediaDescription.Builder builder = new MediaDescription.Builder().setMediaId("__CHAT_" + did);
TLRPC.FileLocation avatar = null;
if (did > 0) {
TLRPC.User user = users.get(did);
if (user != null) {
builder.setTitle(ContactsController.formatName(user.first_name, user.last_name));
if (user.photo != null && user.photo.photo_small instanceof TLRPC.TL_fileLocation) {
avatar = user.photo.photo_small;
}
} else {
builder.setTitle("DELETED USER");
}
} else {
TLRPC.Chat chat = chats.get(-did);
if (chat != null) {
builder.setTitle(chat.title);
if (chat.photo != null && chat.photo.photo_small instanceof TLRPC.TL_fileLocation) {
avatar = chat.photo.photo_small;
}
} else {
builder.setTitle("DELETED CHAT");
}
}
Bitmap bitmap = null;
if (avatar != null) {
bitmap = createRoundBitmap(FileLoader.getPathToAttach(avatar, true));
if (bitmap != null) {
builder.setIconBitmap(bitmap);
}
}
if (avatar == null || bitmap == null) {
builder.setIconUri(Uri.parse("android.resource://" + getApplicationContext().getPackageName() + "/drawable/contact_blue"));
}
mediaItems.add(new MediaBrowser.MediaItem(builder.build(), MediaBrowser.MediaItem.FLAG_BROWSABLE));
}
} else if (parentMediaId != null && parentMediaId.startsWith("__CHAT_")) {
int did = 0;
try {
did = Integer.parseInt(parentMediaId.replace("__CHAT_", ""));
} catch (Exception e) {
FileLog.e("messenger", e);
}
ArrayList<MessageObject> arrayList = musicObjects.get(did);
if (arrayList != null) {
for (int a = 0; a < arrayList.size(); a++) {
MessageObject messageObject = arrayList.get(a);
MediaDescription.Builder builder = new MediaDescription.Builder().setMediaId(did + "_" + a);
builder.setTitle(messageObject.getMusicTitle());
builder.setSubtitle(messageObject.getMusicAuthor());
mediaItems.add(new MediaBrowser.MediaItem(builder.build(), MediaBrowser.MediaItem.FLAG_PLAYABLE));
}
}
}
result.sendResult(mediaItems);
}
private Bitmap createRoundBitmap(File path) {
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
Bitmap bitmap = BitmapFactory.decodeFile(path.toString(), options);
if (bitmap != null) {
Bitmap result = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
result.eraseColor(Color.TRANSPARENT);
Canvas canvas = new Canvas(result);
BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
if (roundPaint == null) {
roundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
bitmapRect = new RectF();
}
roundPaint.setShader(shader);
bitmapRect.set(0, 0, bitmap.getWidth(), bitmap.getHeight());
canvas.drawRoundRect(bitmapRect, bitmap.getWidth(), bitmap.getHeight(), roundPaint);
return result;
}
} catch (Throwable e) {
FileLog.e("messenger", e);
}
return null;
}
private final class MediaSessionCallback extends MediaSession.Callback {
@Override
public void onPlay() {
MessageObject messageObject = MediaController.getInstance().getPlayingMessageObject();
if (messageObject == null) {
onPlayFromMediaId(lastSelectedDialog + "_" + 0, null);
} else {
MediaController.getInstance().playAudio(messageObject);
}
}
@Override
public void onSkipToQueueItem(long queueId) {
MediaController.getInstance().playMessageAtIndex((int) queueId);
handlePlayRequest();
}
@Override
public void onSeekTo(long position) {
MessageObject messageObject = MediaController.getInstance().getPlayingMessageObject();
if (messageObject != null) {
MediaController.getInstance().seekToProgress(messageObject, position / 1000 / (float) messageObject.getDuration());
}
}
@Override
public void onPlayFromMediaId(String mediaId, Bundle extras) {
String args[] = mediaId.split("_");
if (args.length != 2) {
return;
}
try {
int did = Integer.parseInt(args[0]);
int id = Integer.parseInt(args[1]);
ArrayList<MessageObject> arrayList = musicObjects.get(did);
ArrayList<MediaSession.QueueItem> arrayList1 = musicQueues.get(did);
if (arrayList == null || id < 0 || id >= arrayList.size()) {
return;
}
lastSelectedDialog = did;
ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE).edit().putInt("auto_lastSelectedDialog", did).commit();
MediaController.getInstance().setPlaylist(arrayList, arrayList.get(id), false);
mediaSession.setQueue(arrayList1);
if (did > 0) {
TLRPC.User user = users.get(did);
if (user != null) {
mediaSession.setQueueTitle(ContactsController.formatName(user.first_name, user.last_name));
} else {
mediaSession.setQueueTitle("DELETED USER");
}
} else {
TLRPC.Chat chat = chats.get(-did);
if (chat != null) {
mediaSession.setQueueTitle(chat.title);
} else {
mediaSession.setQueueTitle("DELETED CHAT");
}
}
} catch (Exception e) {
FileLog.e("messenger", e);
}
handlePlayRequest();
}
@Override
public void onPause() {
handlePauseRequest();
}
@Override
public void onStop() {
handleStopRequest(null);
}
@Override
public void onSkipToNext() {
MediaController.getInstance().playNextMessage();
}
@Override
public void onSkipToPrevious() {
MediaController.getInstance().playPreviousMessage();
}
@Override
public void onPlayFromSearch(String query, Bundle extras) {
if (query == null || query.length() == 0) {
return;
}
query = query.toLowerCase();
for (int a = 0; a < dialogs.size(); a++) {
int did = dialogs.get(a);
if (did > 0) {
TLRPC.User user = users.get(did);
if (user == null) {
continue;
}
if (user.first_name != null && user.first_name.startsWith(query) || user.last_name != null && user.last_name.startsWith(query)) {
onPlayFromMediaId(did + "_" + 0, null);
break;
}
} else {
TLRPC.Chat chat = chats.get(-did);
if (chat == null) {
continue;
}
if (chat.title != null && chat.title.toLowerCase().contains(query)) {
onPlayFromMediaId(did + "_" + 0, null);
break;
}
}
}
}
}
private void updatePlaybackState(String error) {
long position = PlaybackState.PLAYBACK_POSITION_UNKNOWN;
MessageObject playingMessageObject = MediaController.getInstance().getPlayingMessageObject();
if (playingMessageObject != null) {
position = playingMessageObject.audioProgressSec * 1000;
}
PlaybackState.Builder stateBuilder = new PlaybackState.Builder().setActions(getAvailableActions());
int state;
if (playingMessageObject == null) {
state = PlaybackState.STATE_STOPPED;
} else {
if (MediaController.getInstance().isDownloadingCurrentMessage()) {
state = PlaybackState.STATE_BUFFERING;
} else {
state = MediaController.getInstance().isAudioPaused() ? PlaybackState.STATE_PAUSED : PlaybackState.STATE_PLAYING;
}
}
if (error != null) {
stateBuilder.setErrorMessage(error);
state = PlaybackState.STATE_ERROR;
}
stateBuilder.setState(state, position, 1.0f, SystemClock.elapsedRealtime());
if (playingMessageObject != null) {
stateBuilder.setActiveQueueItemId(MediaController.getInstance().getPlayingMessageObjectNum());
} else {
stateBuilder.setActiveQueueItemId(0);
}
mediaSession.setPlaybackState(stateBuilder.build());
}
private long getAvailableActions() {
long actions = PlaybackState.ACTION_PLAY | PlaybackState.ACTION_PLAY_FROM_MEDIA_ID | PlaybackState.ACTION_PLAY_FROM_SEARCH;
MessageObject playingMessageObject = MediaController.getInstance().getPlayingMessageObject();
if (playingMessageObject != null) {
if (!MediaController.getInstance().isAudioPaused()) {
actions |= PlaybackState.ACTION_PAUSE;
}
actions |= PlaybackState.ACTION_SKIP_TO_PREVIOUS;
actions |= PlaybackState.ACTION_SKIP_TO_NEXT;
}
return actions;
}
private void handleStopRequest(String withError) {
delayedStopHandler.removeCallbacksAndMessages(null);
delayedStopHandler.sendEmptyMessageDelayed(0, STOP_DELAY);
updatePlaybackState(withError);
stopSelf();
serviceStarted = false;
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.audioPlayStateChanged);
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.audioDidStarted);
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.audioDidReset);
}
private void handlePlayRequest() {
delayedStopHandler.removeCallbacksAndMessages(null);
if (!serviceStarted) {
startService(new Intent(getApplicationContext(), MusicBrowserService.class));
serviceStarted = true;
}
if (!mediaSession.isActive()) {
mediaSession.setActive(true);
}
MessageObject messageObject = MediaController.getInstance().getPlayingMessageObject();
if (messageObject == null) {
return;
}
MediaMetadata.Builder builder = new MediaMetadata.Builder();
builder.putLong(MediaMetadata.METADATA_KEY_DURATION, messageObject.getDuration() * 1000);
builder.putString(MediaMetadata.METADATA_KEY_ARTIST, messageObject.getMusicAuthor());
builder.putString(MediaMetadata.METADATA_KEY_TITLE, messageObject.getMusicTitle());
AudioInfo audioInfo = MediaController.getInstance().getAudioInfo();
if (audioInfo != null) {
Bitmap bitmap = audioInfo.getCover();
if (bitmap != null) {
builder.putBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART, bitmap);
}
}
mediaSession.setMetadata(builder.build());
}
private void handlePauseRequest() {
MediaController.getInstance().pauseAudio(MediaController.getInstance().getPlayingMessageObject());
delayedStopHandler.removeCallbacksAndMessages(null);
delayedStopHandler.sendEmptyMessageDelayed(0, STOP_DELAY);
}
@Override
public void didReceivedNotification(int id, Object... args) {
updatePlaybackState(null);
handlePlayRequest();
}
private static class DelayedStopHandler extends Handler {
private final WeakReference<MusicBrowserService> mWeakReference;
private DelayedStopHandler(MusicBrowserService service) {
mWeakReference = new WeakReference<>(service);
}
@Override
public void handleMessage(Message msg) {
MusicBrowserService service = mWeakReference.get();
if (service != null) {
MessageObject messageObject = MediaController.getInstance().getPlayingMessageObject();
if (messageObject != null && !MediaController.getInstance().isAudioPaused()) {
return;
}
service.stopSelf();
service.serviceStarted = false;
}
}
}
}
@@ -61,10 +61,10 @@ public class MusicPlayerReceiver extends BroadcastReceiver {
case KeyEvent.KEYCODE_MEDIA_STOP:
break;
case KeyEvent.KEYCODE_MEDIA_NEXT:
MediaController.getInstance().playNextMessage();
MediaController.getInstance().playNextMessage(+1, false);
break;
case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
MediaController.getInstance().playPreviousMessage();
MediaController.getInstance().playNextMessage(-1, false);
break;
}
} else {
@@ -73,11 +73,11 @@ public class MusicPlayerReceiver extends BroadcastReceiver {
} else if (intent.getAction().equals(MusicPlayerService.NOTIFY_PAUSE) || intent.getAction().equals(android.media.AudioManager.ACTION_AUDIO_BECOMING_NOISY)) {
MediaController.getInstance().pauseAudio(MediaController.getInstance().getPlayingMessageObject());
} else if (intent.getAction().equals(MusicPlayerService.NOTIFY_NEXT)) {
MediaController.getInstance().playNextMessage();
MediaController.getInstance().playNextMessage(+1, false);
} else if (intent.getAction().equals(MusicPlayerService.NOTIFY_CLOSE)) {
MediaController.getInstance().cleanupPlayer(true, true);
} else if (intent.getAction().equals(MusicPlayerService.NOTIFY_PREVIOUS)) {
MediaController.getInstance().playPreviousMessage();
MediaController.getInstance().playNextMessage(-1, false);
}
}
}
@@ -53,7 +53,6 @@ public class MusicPlayerService extends Service implements NotificationCenter.No
private RemoteControlClient remoteControlClient;
private AudioManager audioManager;
private static boolean supportBigNotifications = Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN;
private static boolean supportLockScreenControls = Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH;
@Override
@@ -108,95 +107,70 @@ public class MusicPlayerService extends Service implements NotificationCenter.No
}
@SuppressLint("NewApi")
private void createNotification(MessageObject messageObject) {
String songName = messageObject.getMusicTitle();
String authorName = messageObject.getMusicAuthor();
private void createNotification(MessageObject messageObject)
{
AudioInfo audioInfo = MediaController.getInstance().getAudioInfo();
RemoteViews simpleContentView = new RemoteViews(getApplicationContext().getPackageName(), R.layout.player_small_notification);
RemoteViews expandedView = null;
if (supportBigNotifications) {
expandedView = new RemoteViews(getApplicationContext().getPackageName(), R.layout.player_big_notification);
MrPoortext pt = MrMailbox.getMsg(messageObject.getId()).getMediainfo();
String authorName = pt.getText1();
String songName = pt.getText2();
if( songName == null || songName.length()==0 ) {
TLRPC.Document document = messageObject.messageOwner.media.document;
for (int i = 0; i < document.attributes.size(); i++) {
TLRPC.DocumentAttribute attr = document.attributes.get(i);
if (attr instanceof TLRPC.TL_documentAttributeAudio) {
authorName = attr.performer;
songName = attr.title;
break;
}
}
}
Intent intent = new Intent(ApplicationLoader.applicationContext, LaunchActivity.class);
intent.setAction("com.b44t.messenger.openplayer");
intent.setFlags(32768);
PendingIntent contentIntent = PendingIntent.getActivity(ApplicationLoader.applicationContext, 0, intent, 0);
if( songName == null || songName.length()==0 ) {
// preview of just recorded and not send voice messages
authorName = ApplicationLoader.applicationContext.getString(R.string.FromSelf);
songName = ApplicationLoader.applicationContext.getString(R.string.AttachVoiceMessage);
}
RemoteViews simpleContentView = new RemoteViews(getApplicationContext().getPackageName(), R.layout.player_small_notification);
//Intent intent = new Intent(ApplicationLoader.applicationContext, LaunchActivity.class);
//intent.setAction("com.b44t.messenger.openchat"+messageObject.getDialogId());
//intent.setFlags(32768);
//PendingIntent contentIntent = PendingIntent.getActivity(ApplicationLoader.applicationContext, 0, intent, 0);
Notification notification = new NotificationCompat.Builder(getApplicationContext())
.setSmallIcon(R.drawable.player)
.setContentIntent(contentIntent)
.setSmallIcon(R.drawable.notification_player)
//.setContentIntent(contentIntent)
.setContentTitle(songName).build();
notification.contentView = simpleContentView;
if (supportBigNotifications) {
notification.bigContentView = expandedView;
}
setListeners(simpleContentView);
if (supportBigNotifications) {
setListeners(expandedView);
}
Bitmap albumArt = audioInfo != null ? audioInfo.getSmallCover() : null;
if (albumArt != null) {
notification.contentView.setImageViewBitmap(R.id.player_album_art, albumArt);
if (supportBigNotifications) {
notification.bigContentView.setImageViewBitmap(R.id.player_album_art, albumArt);
}
notification.contentView.setViewVisibility(R.id.player_album_art, View.VISIBLE);
} else {
notification.contentView.setImageViewResource(R.id.player_album_art, R.drawable.nocover_small);
if (supportBigNotifications) {
notification.bigContentView.setImageViewResource(R.id.player_album_art, R.drawable.nocover_big);
}
notification.contentView.setViewVisibility(R.id.player_album_art, View.GONE);
}
if (MediaController.getInstance().isDownloadingCurrentMessage()) {
notification.contentView.setViewVisibility(R.id.player_pause, View.GONE);
notification.contentView.setViewVisibility(R.id.player_play, View.GONE);
notification.contentView.setViewVisibility(R.id.player_next, View.GONE);
notification.contentView.setViewVisibility(R.id.player_previous, View.GONE);
notification.contentView.setViewVisibility(R.id.player_progress_bar, View.VISIBLE);
if (supportBigNotifications) {
notification.bigContentView.setViewVisibility(R.id.player_pause, View.GONE);
notification.bigContentView.setViewVisibility(R.id.player_play, View.GONE);
notification.bigContentView.setViewVisibility(R.id.player_next, View.GONE);
notification.bigContentView.setViewVisibility(R.id.player_previous, View.GONE);
notification.bigContentView.setViewVisibility(R.id.player_progress_bar, View.VISIBLE);
}
} else {
notification.contentView.setViewVisibility(R.id.player_progress_bar, View.GONE);
{
notification.contentView.setViewVisibility(R.id.player_next, View.VISIBLE);
notification.contentView.setViewVisibility(R.id.player_previous, View.VISIBLE);
if (supportBigNotifications) {
notification.bigContentView.setViewVisibility(R.id.player_next, View.VISIBLE);
notification.bigContentView.setViewVisibility(R.id.player_previous, View.VISIBLE);
notification.bigContentView.setViewVisibility(R.id.player_progress_bar, View.GONE);
}
if (MediaController.getInstance().isAudioPaused()) {
notification.contentView.setViewVisibility(R.id.player_pause, View.GONE);
notification.contentView.setViewVisibility(R.id.player_play, View.VISIBLE);
if (supportBigNotifications) {
notification.bigContentView.setViewVisibility(R.id.player_pause, View.GONE);
notification.bigContentView.setViewVisibility(R.id.player_play, View.VISIBLE);
}
} else {
notification.contentView.setViewVisibility(R.id.player_pause, View.VISIBLE);
notification.contentView.setViewVisibility(R.id.player_play, View.GONE);
if (supportBigNotifications) {
notification.bigContentView.setViewVisibility(R.id.player_pause, View.VISIBLE);
notification.bigContentView.setViewVisibility(R.id.player_play, View.GONE);
}
}
}
notification.contentView.setTextViewText(R.id.player_song_name, songName);
notification.contentView.setTextViewText(R.id.player_author_name, authorName);
if (supportBigNotifications) {
notification.bigContentView.setTextViewText(R.id.player_song_name, songName);
notification.bigContentView.setTextViewText(R.id.player_author_name, authorName);
}
notification.flags |= Notification.FLAG_ONGOING_EVENT;
startForeground(5, notification);
@@ -218,12 +192,16 @@ public class MusicPlayerService extends Service implements NotificationCenter.No
public void setListeners(RemoteViews view) {
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, new Intent(NOTIFY_PREVIOUS), PendingIntent.FLAG_UPDATE_CURRENT);
view.setOnClickPendingIntent(R.id.player_previous, pendingIntent);
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, new Intent(NOTIFY_CLOSE), PendingIntent.FLAG_UPDATE_CURRENT);
view.setOnClickPendingIntent(R.id.player_close, pendingIntent);
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, new Intent(NOTIFY_PAUSE), PendingIntent.FLAG_UPDATE_CURRENT);
view.setOnClickPendingIntent(R.id.player_pause, pendingIntent);
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, new Intent(NOTIFY_NEXT), PendingIntent.FLAG_UPDATE_CURRENT);
view.setOnClickPendingIntent(R.id.player_next, pendingIntent);
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, new Intent(NOTIFY_PLAY), PendingIntent.FLAG_UPDATE_CURRENT);
view.setOnClickPendingIntent(R.id.player_play, pendingIntent);
}
@@ -31,7 +31,8 @@ public class NotificationCenter {
private static int totalEvents = 1;
public static final int connectionStateChanged = totalEvents++;
public static final int configureEnded = totalEvents++;
public static final int configureProgress = totalEvents++;
public static final int didReceivedNewMessages = totalEvents++;
public static final int updateInterfaces = totalEvents++;
public static final int dialogsNeedReload = totalEvents++;
@@ -43,37 +44,22 @@ public class NotificationCenter {
public static final int chatDidCreated = totalEvents++;
public static final int mediaDidLoaded = totalEvents++;
public static final int mediaCountDidLoaded = totalEvents++;
public static final int dialogPhotosLoaded = totalEvents++;
public static final int notificationsSettingsUpdated = totalEvents++;
//public static final int pushMessagesUpdated = totalEvents++;
public static final int blockedUsersDidLoaded = totalEvents++;
public static final int openedChatChanged = totalEvents++;
public static final int stopEncodingService = totalEvents++;
public static final int mainUserInfoChanged = totalEvents++;
public static final int recentImagesDidLoaded = totalEvents++;
public static final int replaceMessagesObjects = totalEvents++;
public static final int waveformCalculated = totalEvents++;
public static final int didSetPasscode = totalEvents++;
//public static final int screenStateChanged = totalEvents++; -- currently not used, but this may get handy
public static final int stickersDidLoaded = totalEvents++;
public static final int didReplacedPhotoInMemCache = totalEvents++;
public static final int musicDidLoaded = totalEvents++;
public static final int locationPermissionGranted = totalEvents++;
public static final int wasUnableToFindCurrentLocation = totalEvents++;
public static final int reloadHints = totalEvents++;
public static final int httpFileDidLoaded = totalEvents++;
public static final int httpFileDidFailedLoad = totalEvents++;
public static final int messageThumbGenerated = totalEvents++;
public static final int wallpapersDidLoaded = totalEvents++;
public static final int closeOtherAppActivities = totalEvents++;
public static final int didUpdatedConnectionState = totalEvents++;
public static final int emojiDidLoaded = totalEvents++;
public static final int FileDidUpload = totalEvents++;
public static final int FileDidFailUpload = totalEvents++;
public static final int FileUploadProgressChanged = totalEvents++;
public static final int FileLoadProgressChanged = totalEvents++;
public static final int FileDidLoaded = totalEvents++;
public static final int FileDidFailedLoad = totalEvents++;
@@ -88,14 +74,11 @@ public class NotificationCenter {
public static final int recordStarted = totalEvents++;
public static final int recordStartError = totalEvents++;
public static final int recordStopped = totalEvents++;
public static final int screenshotTook = totalEvents++;
public static final int albumsDidLoaded = totalEvents++;
public static final int audioDidSent = totalEvents++;
public static final int audioDidStarted = totalEvents++;
public static final int audioRouteChanged = totalEvents++;
public static final int errSelfNotInGroup = totalEvents++;
private SparseArray<ArrayList<Object>> observers = new SparseArray<>();
private SparseArray<ArrayList<Object>> removeAfterBroadcast = new SparseArray<>();
private SparseArray<ArrayList<Object>> addAfterBroadcast = new SparseArray<>();
@@ -33,6 +33,6 @@ public class NotificationDismissReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Context.MODE_PRIVATE);
preferences.edit().putInt("dismissDate", intent.getIntExtra("messageDate", 0)).commit();
preferences.edit().putInt("dismissDate", intent.getIntExtra("messageDate", 0)).apply();
}
}
@@ -70,7 +70,6 @@ public class NotificationsController {
private HashMap<Long, Integer> autoNotificationsIds = new HashMap<>();
private int wearNotificationId = 10000;
private int autoNotificationId = 20000;
public ArrayList<MessageObject> popupMessages = new ArrayList<>();
private long opened_dialog_id = 0;
private int total_unread_count = 0;
private int personal_count = 0;
@@ -408,7 +407,7 @@ public class NotificationsController {
return;
}
TLRPC.Message tmsg = mrMsg.get_TLRPC_Message();
MessageObject msgDrawObj = new MessageObject(tmsg, null, true);
MessageObject msgDrawObj = new MessageObject(tmsg, true);
delayedPushMessages.add(msgDrawObj);
pushMessages.add(0, msgDrawObj);
@@ -935,7 +934,7 @@ public class NotificationsController {
}
}
private void scheduleNotificationDelay(boolean onlineReason) {
/*private void scheduleNotificationDelay(boolean onlineReason) {
try {
FileLog.e("messenger", "delay notification start, onlineReason = " + onlineReason);
notificationDelayWakelock.acquire(10000);
@@ -945,7 +944,7 @@ public class NotificationsController {
FileLog.e("messenger", e);
showOrUpdateNotification(notifyCheck);
}
}
}*/
protected void repeatNotificationMaybe() {
notificationsQueue.postRunnable(new Runnable() {
@@ -1109,7 +1108,7 @@ public class NotificationsController {
String name;
if ( pushDialogs.size() > 1 || !showPreview ) {
name = LocaleController.getString("AppName", R.string.AppName);
name = mContext.getString(R.string.AppName);
} else {
if ( isGroupChat ) {
name = mrChat.getName();
@@ -1122,9 +1121,8 @@ public class NotificationsController {
if (pushDialogs.size() == 1) {
detailText = mContext.getResources().getQuantityString(R.plurals.NewMessages, total_unread_count, total_unread_count);
} else {
detailText = LocaleController.formatString("NotificationMessagesPeopleDisplayOrder", R.string.NotificationMessagesPeopleDisplayOrder,
mContext.getResources().getQuantityString(R.plurals.NewMessages, total_unread_count, total_unread_count),
LocaleController.formatPluralString("FromChats", pushDialogs.size()));
String newMessages = mContext.getResources().getQuantityString(R.plurals.NewMessages, total_unread_count, total_unread_count);
detailText = mContext.getResources().getQuantityString(R.plurals.NewMessagesInChats, pushDialogs.size(), newMessages, pushDialogs.size());
}
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(ApplicationLoader.applicationContext)
@@ -1328,14 +1326,14 @@ public class NotificationsController {
continue;
}
} else {
chat = MessagesController.getInstance().getChat(-(int)dialog_id);
if (chat == null) {
/*chat = MessagesController.getInstance().getChat(-(int)dialog_id);
if (chat == null) {*/
continue;
}
//}
}
TLRPC.FileLocation photoPath = null;
if (AndroidUtilities.needShowPasscode(false) || UserConfig.isWaitingForPasscodeEnter) {
name = LocaleController.getString("AppName", R.string.AppName);
name = mContext.getString(R.string.AppName);
} else {
if (chat != null) {
name = chat.title;
@@ -1386,19 +1384,19 @@ public class NotificationsController {
msgReplyIntent.putExtra("dialog_id", dialog_id);
msgReplyIntent.putExtra("max_id", max_id);
PendingIntent msgReplyPendingIntent = PendingIntent.getBroadcast(ApplicationLoader.applicationContext, notificationIdAuto, msgReplyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
RemoteInput remoteInputAuto = new RemoteInput.Builder(NotificationsController.EXTRA_VOICE_REPLY).setLabel(LocaleController.getString("Reply", R.string.Reply)).build();
RemoteInput remoteInputAuto = new RemoteInput.Builder(NotificationsController.EXTRA_VOICE_REPLY).setLabel(mContext.getString(R.string.Reply)).build();
unreadConvBuilder.setReplyAction(msgReplyPendingIntent, remoteInputAuto);
Intent replyIntent = new Intent(ApplicationLoader.applicationContext, WearReplyReceiver.class);
replyIntent.putExtra("dialog_id", dialog_id);
replyIntent.putExtra("max_id", max_id);
PendingIntent replyPendingIntent = PendingIntent.getBroadcast(ApplicationLoader.applicationContext, notificationIdWear, replyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
RemoteInput remoteInputWear = new RemoteInput.Builder(EXTRA_VOICE_REPLY).setLabel(LocaleController.getString("Reply", R.string.Reply)).build();
RemoteInput remoteInputWear = new RemoteInput.Builder(EXTRA_VOICE_REPLY).setLabel(mContext.getString(R.string.Reply)).build();
String replyToString;
if (chat != null) {
replyToString = LocaleController.formatString("ReplyToGroup", R.string.ReplyToGroup, name);
replyToString = String.format(mContext.getString(R.string.ReplyToGroup), name);
} else {
replyToString = LocaleController.formatString("ReplyToUser", R.string.ReplyToUser, name);
replyToString = String.format(mContext.getString(R.string.ReplyToContact), name);
}
wearReplyAction = new NotificationCompat.Action.Builder(R.drawable.ic_reply_icon, replyToString, replyPendingIntent).addRemoteInput(remoteInputWear).build();
}
File diff suppressed because it is too large Load Diff
@@ -1,44 +0,0 @@
/*******************************************************************************
*
* Messenger Android Frontend
* (C) 2013-2016 Nikolai Kudashov
* (C) 2017 Björn Petersen
* Contact: r10s@b44t.com, http://b44t.com
*
* This program 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.
*
* This program 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
* this program. If not, see http://www.gnu.org/licenses/ .
*
******************************************************************************/
package com.b44t.messenger;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class ShareBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String url = intent.getDataString();
if (url != null) {
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT, url);
Intent chooserIntent = Intent.createChooser(shareIntent, LocaleController.getString("ShareLink", R.string.ShareLink));
chooserIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(chooserIntent);
}
}
}
@@ -41,7 +41,6 @@ public class TLRPC {
}
public static class ChatPhoto extends TLObject {
public FileLocation photo_small;
public FileLocation photo_big;
}
@@ -51,7 +50,6 @@ public class TLRPC {
public int duration;
public String alt;
public InputStickerSet stickerset;
public int flags;
public boolean voice;
public String title;
public String performer;
@@ -77,20 +75,7 @@ public class TLRPC {
public static class TL_documentAttributeFilename extends DocumentAttribute {
}
public static class messages_Messages extends TLObject {
public ArrayList<Message> messages = new ArrayList<>();
public ArrayList<Chat> chats = new ArrayList<>();
public ArrayList<User> users = new ArrayList<>();
public int flags;
public int pts;
public int count;
}
public static class TL_messages_messages extends messages_Messages {
}
public static class Peer extends TLObject {
public final int channel_id = 0;
public int user_id;
public final int chat_id = 0;
}
@@ -98,85 +83,28 @@ public class TLRPC {
public static class TL_peerUser extends Peer {
}
public static class GeoPoint extends TLObject {
public double _long;
public double lat;
}
public static class TL_geoPoint extends GeoPoint {
}
public static class TL_messageMediaEmpty extends MessageMedia {
}
public static class TL_messageMediaVenue extends MessageMedia {
}
public static class TL_messageMediaDocument extends MessageMedia {
}
public static class TL_messageMediaContact extends MessageMedia {
}
public static class TL_messageMediaPhoto extends MessageMedia {
}
public static class TL_messageMediaGeo extends MessageMedia {
}
public static class PeerNotifySettings extends TLObject {
public int flags;
public boolean silent;
public int mute_until;
public String sound;
}
public static class TL_peerNotifySettings extends PeerNotifySettings {
}
public static class TL_messages_stickerSet extends TLObject {
public StickerSet set;
public ArrayList<Document> documents = new ArrayList<>();
}
public static class InputGeoPoint extends TLObject {
public double lat;
public double _long;
}
public static class TL_inputGeoPoint extends InputGeoPoint {
}
public static class Audio extends TLObject {
public long id;
public int date;
public int duration;
public String mime_type;
public int size;
public int dc_id;
public final int dc_id = 0;
public int user_id;
public byte[] key;
public byte[] iv;
}
public static class ChatFull extends TLObject {
public int flags;
public int id;
public String about;
}
public static class WebPage extends TLObject {
public int flags;
public long id;
public String url;
public String type;
public String title;
public String description;
public Photo photo;
public int duration;
public String author;
public int date;
public Document document;
}
public static class InputFileLocation extends TLObject {
@@ -184,7 +112,6 @@ public class TLRPC {
public long access_hash;
public long volume_id;
public int local_id;
public long secret;
}
public static class TL_inputDocumentFileLocation extends InputFileLocation {
@@ -198,17 +125,10 @@ public class TLRPC {
public String first_name;
public String last_name;
public String username;
public String phone;
public UserProfilePhoto photo;
public int flags;
public boolean self;
public boolean contact;
public boolean min;
}
public static class TL_userContact_old2 extends User {
}
public static class Video extends TLObject {
public long id;
public int user_id;
@@ -221,16 +141,6 @@ public class TLRPC {
public int h;
public String mime_type;
public String caption;
public byte[] key;
public byte[] iv;
}
public static class InputDocument extends TLObject {
public long id;
public long access_hash;
}
public static class TL_inputDocument extends InputDocument {
}
public static class Document extends TLObject {
@@ -253,53 +163,6 @@ public class TLRPC {
public static class TL_document extends Document {
}
public static class InputMedia extends TLObject {
public InputFile file;
public InputFile thumb;
public String mime_type;
public ArrayList<DocumentAttribute> attributes = new ArrayList<>();
public String caption;
public InputGeoPoint geo_point;
public String title;
public String address;
public String provider;
public String venue_id;
public String phone_number;
public String first_name;
public String last_name;
public String url;
public String q;
}
public static class TL_inputMediaContact extends InputMedia {
}
public static class TL_inputMediaUploadedThumbDocument extends InputMedia {
}
public static class TL_inputMediaDocument extends InputMedia {
public InputDocument id;
}
public static class TL_inputMediaGifExternal extends InputMedia {
}
public static class TL_inputMediaGeoPoint extends InputMedia {
}
public static class TL_inputMediaUploadedPhoto extends InputMedia {
}
public static class TL_inputMediaVenue extends InputMedia {
}
public static class TL_inputMediaUploadedDocument extends InputMedia {
}
public static class TL_inputMediaPhoto extends InputMedia {
public InputPhoto id;
}
public static class InputStickerSet extends TLObject {
public long id;
public String short_name;
@@ -308,11 +171,6 @@ public class TLRPC {
public static class TL_inputStickerSetEmpty extends InputStickerSet {
}
public static class InputEncryptedFile extends TLObject {
public long id;
public int parts;
}
public static class UserProfilePhoto extends TLObject {
public FileLocation photo_small;
public FileLocation photo_big;
@@ -320,7 +178,6 @@ public class TLRPC {
public static class Photo extends TLObject {
public long id;
public long access_hash;
public int user_id;
public int date;
public String caption;
@@ -340,12 +197,12 @@ public class TLRPC {
public String title;
public final ChatPhoto photo = null;
public int date;
public int version;
public boolean editor;
public final int version = 0;
public final boolean editor = false;
public String username;
public boolean signatures;
public boolean min;
public String address;
public final boolean signatures = false;
public final boolean min = false;
public final String address = null;
}
public static class StickerSet extends TLObject {
@@ -417,38 +274,15 @@ public class TLRPC {
public static class TL_wallPaperSolid extends WallPaper {
}
public static class InputPhoto extends TLObject {
public long id;
public long access_hash;
}
public static class TL_inputPhoto extends InputPhoto {
}
public static class InputPeer extends TLObject {
public int user_id;
public int chat_id;
public int channel_id;
}
public static class TL_inputPeerUser extends InputPeer {
}
public static class MessageMedia extends TLObject {
public byte[] bytes;
public Photo photo;
public GeoPoint geo;
public String title;
public String address;
public String provider;
public String venue_id;
public Document document;
public String caption;
public String phone_number;
public String first_name;
public String last_name;
public int user_id;
public WebPage webpage;
}
public static class Message extends TLObject {
@@ -456,47 +290,35 @@ public class TLRPC {
public int from_id;
public Peer to_id;
public int date;
public int reply_to_msg_id;
public long reply_to_random_id;
public final int reply_to_msg_id = 0;
public String message;
public MessageMedia media;
public int flags;
public boolean media_unread;
public boolean out;
public boolean unread;
public int views;
public boolean silent;
public boolean post;
public final int views = 0;
public final boolean silent = false;
public final boolean post = false;// ? true=avatar wird in gruppen nicht angezeigt, wird aber in isFromUser() auch überprüft...
public TL_messageFwdHeader fwd_from;
public int send_state = 0; //custom
public String attachPath = ""; //custom
public HashMap<String, String> params; //custom
public long random_id; //custom
public long dialog_id; //custom
public int layer; //custom
public TLRPC.Message replyMessage; //custom
public final int layer = 0; //custom
public boolean created_by_mr;
}
public static class TL_messageEmpty extends Message {
}
public static class TL_message extends Message {
}
public static class TL_dialog extends TLObject {
final public int flags = 0;
public Peer peer;
public int top_message;
public int unread_count;
public PeerNotifySettings notify_settings;
public int pts;
public final int top_message = 0;
public final int unread_count = 0;
public final int pts = 0;
public DraftMessage draft;
public int last_message_date; //custom
public long id; //custom
}
public static class Vector extends TLObject {
public ArrayList<Object> objects = new ArrayList<>();
}
}
@@ -1,187 +0,0 @@
/*******************************************************************************
*
* Messenger Android Frontend
* (C) 2013-2016 Nikolai Kudashov
* (C) 2017 Björn Petersen
* Contact: r10s@b44t.com, http://b44t.com
*
* This program 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.
*
* This program 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
* this program. If not, see http://www.gnu.org/licenses/ .
*
******************************************************************************/
package com.b44t.messenger;
// ChooserTargetService, see https://developer.android.com/reference/android/service/chooser/ChooserTargetService.html
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.ComponentName;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Build;
import android.service.chooser.ChooserTarget;
import android.service.chooser.ChooserTargetService;
import com.b44t.ui.LaunchActivity;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;
@TargetApi(Build.VERSION_CODES.M)
public class TgChooserTargetService extends ChooserTargetService {
@Override
public List<ChooserTarget> onGetChooserTargets(ComponentName targetActivityName, IntentFilter matchedFilter) {
final List<ChooserTarget> targets = new ArrayList<>();
if (!UserConfig.isClientActivated()) {
return targets;
}
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
if (!preferences.getBoolean("direct_share", true)) {
return targets;
}
ImageLoader imageLoader = ImageLoader.getInstance();
final Semaphore semaphore = new Semaphore(0);
final ComponentName componentName = new ComponentName(getPackageName(), LaunchActivity.class.getCanonicalName());
/*
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@Override
public void run() {
ArrayList<Integer> dialogs = new ArrayList<>();
ArrayList<TLRPC.Chat> chats = new ArrayList<>();
ArrayList<TLRPC.User> users = new ArrayList<>();
try {
ArrayList<Integer> usersToLoad = new ArrayList<>();
usersToLoad.add(UserConfig.getClientUserId());
ArrayList<Integer> chatsToLoad = new ArrayList<>();
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT did FROM dialogs ORDER BY date DESC LIMIT %d,%d", 0, 30));
while (cursor.next()) {
long id = cursor.longValue(0);
int lower_id = (int) id;
int high_id = (int) (id >> 32);
if (lower_id != 0) {
if (high_id == 1) {
continue;
} else {
if (lower_id > 0) {
if (!usersToLoad.contains(lower_id)) {
usersToLoad.add(lower_id);
}
} else {
if (!chatsToLoad.contains(-lower_id)) {
chatsToLoad.add(-lower_id);
}
}
}
} else {
continue;
}
dialogs.add(lower_id);
if (dialogs.size() == 8) {
break;
}
}
cursor.dispose();
if (!chatsToLoad.isEmpty()) {
//MessagesStorage.getInstance().getChatsInternal(TextUtils.join(",", chatsToLoad), chats);
}
if (!usersToLoad.isEmpty()) {
//MessagesStorage.getInstance().getUsersInternal(TextUtils.join(",", usersToLoad), users);
}
} catch (Exception e) {
FileLog.e("messenger", e);
}
for (int a = 0; a < dialogs.size(); a++) {
Bundle extras = new Bundle();
Icon icon = null;
String name = null;
int id = dialogs.get(a);
if (id > 0) {
for (int b = 0; b < users.size(); b++) {
TLRPC.User user = users.get(b);
if (user.id == id) {
if (!user.bot) {
extras.putLong("dialogId", (long) id);
if (user.photo != null && user.photo.photo_small != null) {
icon = createRoundBitmap(FileLoader.getPathToAttach(user.photo.photo_small, true));
}
name = ContactsController.formatName(user.first_name, user.last_name);
}
break;
}
}
} else {
for (int b = 0; b < chats.size(); b++) {
TLRPC.Chat chat = chats.get(b);
if (chat.id == -id) {
if (!ChatObject.isNotInChat(chat) && (!ChatObject.isChannel(chat) || chat.megagroup)) {
extras.putLong("dialogId", (long) id);
if (chat.photo != null && chat.photo.photo_small != null) {
icon = createRoundBitmap(FileLoader.getPathToAttach(chat.photo.photo_small, true));
}
name = chat.title;
}
break;
}
}
}
if (name != null) {
if (icon == null) {
icon = Icon.createWithResource(ApplicationLoader.applicationContext, R.drawable.logo_avatar);
}
targets.add(new ChooserTarget(name, icon, 1.0f, componentName, extras));
}
}
semaphore.release();
}
});
*/
try {
semaphore.acquire();
} catch (Exception e) {
FileLog.e("messenger", e);
}
return targets;
}
/*
private Icon createRoundBitmap(File path) {
try {
Bitmap bitmap = BitmapFactory.decodeFile(path.toString());
if (bitmap != null) {
Bitmap result = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
result.eraseColor(Color.TRANSPARENT);
Canvas canvas = new Canvas(result);
BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
if (roundPaint == null) {
roundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
bitmapRect = new RectF();
}
roundPaint.setShader(shader);
bitmapRect.set(0, 0, bitmap.getWidth(), bitmap.getHeight());
canvas.drawRoundRect(bitmapRect, bitmap.getWidth(), bitmap.getHeight(), roundPaint);
return Icon.createWithBitmap(result);
}
} catch (Throwable e) {
FileLog.e("messenger", e);
}
return null;
}
*/
}
@@ -32,15 +32,8 @@ import java.io.File;
public class UserConfig {
private static TLRPC.User currentUser;
public static boolean registeredForPush;
public static String pushString = "";
public static int lastSendMessageId = -210000;
public static int lastLocalId = -210000;
public static int lastBroadcastId = -1;
public static String contactsHash = "";
public static boolean blockedUsersLoaded;
private final static Object sync = new Object();
public static boolean saveIncomingPhotos;
public static String passcodeHash = "";
public static byte[] passcodeSalt = new byte[0];
public static boolean appLocked;
@@ -49,26 +42,6 @@ public class UserConfig {
public static int lastPauseTime;
public static boolean isWaitingForPasscodeEnter;
public static boolean useFingerprint = true;
public static String lastUpdateVersion;
public static int lastContactsSyncTime;
public static int lastHintsSyncTime;
public static boolean draftsLoaded;
public static int migrateOffsetId = -1;
public static int migrateOffsetDate = -1;
public static int migrateOffsetUserId = -1;
public static int migrateOffsetChatId = -1;
public static int migrateOffsetChannelId = -1;
public static long migrateOffsetAccess = -1;
public static int getNewMessageId() {
int id;
synchronized (sync) {
id = lastSendMessageId;
lastSendMessageId--;
}
return id;
}
public static void saveConfig(boolean withFile) {
saveConfig(withFile, null);
@@ -79,34 +52,14 @@ public class UserConfig {
try {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("userconfing", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("registeredForPush", registeredForPush);
editor.putString("pushString2", pushString);
editor.putInt("lastSendMessageId", lastSendMessageId);
editor.putInt("lastLocalId", lastLocalId);
editor.putString("contactsHash", contactsHash);
editor.putBoolean("saveIncomingPhotos", saveIncomingPhotos);
editor.putInt("lastBroadcastId", lastBroadcastId);
editor.putBoolean("blockedUsersLoaded", blockedUsersLoaded);
editor.putString("passcodeHash1", passcodeHash);
editor.putString("passcodeSalt", passcodeSalt.length > 0 ? Base64.encodeToString(passcodeSalt, Base64.DEFAULT) : "");
editor.putBoolean("appLocked", appLocked);
editor.putInt("passcodeType", passcodeType);
editor.putInt("autoLockIn", autoLockIn);
editor.putInt("lastPauseTime", lastPauseTime);
editor.putString("lastUpdateVersion2", lastUpdateVersion);
editor.putInt("lastContactsSyncTime", lastContactsSyncTime);
editor.putBoolean("useFingerprint", useFingerprint);
editor.putInt("lastHintsSyncTime", lastHintsSyncTime);
editor.putBoolean("draftsLoaded", draftsLoaded);
editor.putInt("migrateOffsetId", migrateOffsetId);
if (migrateOffsetId != -1) {
editor.putInt("migrateOffsetDate", migrateOffsetDate);
editor.putInt("migrateOffsetUserId", migrateOffsetUserId);
editor.putInt("migrateOffsetChatId", migrateOffsetChatId);
editor.putInt("migrateOffsetChannelId", migrateOffsetChannelId);
editor.putLong("migrateOffsetAccess", migrateOffsetAccess);
}
/*
if (currentUser != null) {
@@ -122,7 +75,7 @@ public class UserConfig {
}
*/
editor.commit();
editor.apply();
if (oldFile != null) {
oldFile.delete();
}
@@ -231,33 +184,13 @@ public class UserConfig {
*/
{
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("userconfing", Context.MODE_PRIVATE);
registeredForPush = preferences.getBoolean("registeredForPush", false);
pushString = preferences.getString("pushString2", "");
lastSendMessageId = preferences.getInt("lastSendMessageId", -210000);
lastLocalId = preferences.getInt("lastLocalId", -210000);
contactsHash = preferences.getString("contactsHash", "");
saveIncomingPhotos = preferences.getBoolean("saveIncomingPhotos", false);
lastBroadcastId = preferences.getInt("lastBroadcastId", -1);
blockedUsersLoaded = preferences.getBoolean("blockedUsersLoaded", false);
passcodeHash = preferences.getString("passcodeHash1", "");
appLocked = preferences.getBoolean("appLocked", false);
passcodeType = preferences.getInt("passcodeType", 0);
autoLockIn = preferences.getInt("autoLockIn", 60 * 60);
lastPauseTime = preferences.getInt("lastPauseTime", 0);
useFingerprint = preferences.getBoolean("useFingerprint", true);
lastUpdateVersion = preferences.getString("lastUpdateVersion2", "3.5");
lastContactsSyncTime = preferences.getInt("lastContactsSyncTime", (int) (System.currentTimeMillis() / 1000) - 23 * 60 * 60);
lastHintsSyncTime = preferences.getInt("lastHintsSyncTime", (int) (System.currentTimeMillis() / 1000) - 25 * 60 * 60);
draftsLoaded = preferences.getBoolean("draftsLoaded", false);
migrateOffsetId = preferences.getInt("migrateOffsetId", 0);
if (migrateOffsetId != -1) {
migrateOffsetDate = preferences.getInt("migrateOffsetDate", 0);
migrateOffsetUserId = preferences.getInt("migrateOffsetUserId", 0);
migrateOffsetChatId = preferences.getInt("migrateOffsetChatId", 0);
migrateOffsetChannelId = preferences.getInt("migrateOffsetChannelId", 0);
migrateOffsetAccess = preferences.getLong("migrateOffsetAccess", 0);
}
/*
String user = preferences.getString("user", null);
@@ -25,10 +25,6 @@ package com.b44t.messenger;
public class UserObject {
public static boolean isUserSelf(TLRPC.User user) {
return user.self;
}
public static String getUserName(TLRPC.User user) {
return "ErrName"; // use MrContact.getName() instead
}
@@ -23,50 +23,15 @@
package com.b44t.messenger;
import java.util.Locale;
public class VideoEditedInfo {
public long startTime;
public long endTime;
public int rotationValue;
public int originalWidth;
public int originalHeight;
public int originalBitrate;
public int resultWidth;
public int resultHeight;
public int bitrate;
public int resultBitrate;
public String originalPath;
public String getString() {
return String.format(Locale.US, "-1_%d_%d_%d_%d_%d_%d_%d_%d_%s", startTime, endTime, rotationValue, originalWidth, originalHeight, bitrate, resultWidth, resultHeight, originalPath);
}
public boolean parseString(String string) {
if (string.length() < 6) {
return false;
}
try {
String args[] = string.split("_");
if (args.length >= 10) {
startTime = Long.parseLong(args[1]);
endTime = Long.parseLong(args[2]);
rotationValue = Integer.parseInt(args[3]);
originalWidth = Integer.parseInt(args[4]);
originalHeight = Integer.parseInt(args[5]);
bitrate = Integer.parseInt(args[6]);
resultWidth = Integer.parseInt(args[7]);
resultHeight = Integer.parseInt(args[8]);
for (int a = 9; a < args.length; a++) {
if (originalPath == null) {
originalPath = args[a];
} else {
originalPath += "_" + args[a];
}
}
}
return true;
} catch (Exception e) {
FileLog.e("messenger", e);
}
return false;
}
}
@@ -1,95 +0,0 @@
/*******************************************************************************
*
* Messenger Android Frontend
* (C) 2013-2016 Nikolai Kudashov
* (C) 2017 Björn Petersen
* Contact: r10s@b44t.com, http://b44t.com
*
* This program 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.
*
* This program 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
* this program. If not, see http://www.gnu.org/licenses/ .
*
******************************************************************************/
package com.b44t.messenger;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
public class VideoEncodingService extends Service implements NotificationCenter.NotificationCenterDelegate {
private NotificationCompat.Builder builder = null;
private String path = null;
private int currentProgress = 0;
public VideoEncodingService() {
super();
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileUploadProgressChanged);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.stopEncodingService);
}
public IBinder onBind(Intent arg2) {
return null;
}
public void onDestroy() {
stopForeground(true);
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.FileUploadProgressChanged);
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.stopEncodingService);
FileLog.e("messenger", "destroy video service");
}
@Override
public void didReceivedNotification(int id, Object... args) {
if (id == NotificationCenter.FileUploadProgressChanged) {
String fileName = (String)args[0];
if (path != null && path.equals(fileName)) {
Float progress = (Float) args[1];
Boolean enc = (Boolean) args[2];
currentProgress = (int)(progress * 100);
builder.setProgress(100, currentProgress, currentProgress == 0);
NotificationManagerCompat.from(ApplicationLoader.applicationContext).notify(4, builder.build());
}
} else if (id == NotificationCenter.stopEncodingService) {
String filepath = (String)args[0];
if (filepath == null || filepath.equals(path)) {
stopSelf();
}
}
}
public int onStartCommand(Intent intent, int flags, int startId) {
path = intent.getStringExtra("path");
if (path == null) {
stopSelf();
return Service.START_NOT_STICKY;
}
FileLog.e("messenger", "start video service");
if (builder == null) {
builder = new NotificationCompat.Builder(ApplicationLoader.applicationContext);
builder.setSmallIcon(android.R.drawable.stat_sys_upload);
builder.setWhen(System.currentTimeMillis());
builder.setContentTitle(LocaleController.getString("AppName", R.string.AppName));
builder.setTicker(LocaleController.getString("SendingVideo", R.string.SendingVideo));
builder.setContentText(LocaleController.getString("SendingVideo", R.string.SendingVideo));
}
currentProgress = 0;
builder.setProgress(100, currentProgress, currentProgress == 0);
startForeground(4, builder.build());
NotificationManagerCompat.from(ApplicationLoader.applicationContext).notify(4, builder.build());
return Service.START_NOT_STICKY;
}
}
@@ -47,7 +47,7 @@ public class WearReplyReceiver extends BroadcastReceiver {
if (dialog_id == 0 || max_id == 0) {
return;
}
SendMessagesHelper.getInstance().sendMessageText(text.toString(), dialog_id, null, null);
SendMessagesHelper.getInstance().sendMessageText(text.toString(), dialog_id, null);
MrMailbox.markseenChat((int)dialog_id);
NotificationsController.getInstance().removeSeenMessages();
}
@@ -1,107 +0,0 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* 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 com.b44t.messenger.volley.toolbox;
import com.b44t.messenger.volley.AuthFailureError;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerFuture;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
/**
* An Authenticator that uses {@link AccountManager} to get auth
* tokens of a specified type for a specified account.
*/
public class AndroidAuthenticator implements Authenticator {
private final AccountManager mAccountManager;
private final Account mAccount;
private final String mAuthTokenType;
private final boolean mNotifyAuthFailure;
/**
* Creates a new authenticator.
* @param context Context for accessing AccountManager
* @param account Account to authenticate as
* @param authTokenType Auth token type passed to AccountManager
*/
public AndroidAuthenticator(Context context, Account account, String authTokenType) {
this(context, account, authTokenType, false);
}
/**
* Creates a new authenticator.
* @param context Context for accessing AccountManager
* @param account Account to authenticate as
* @param authTokenType Auth token type passed to AccountManager
* @param notifyAuthFailure Whether to raise a notification upon auth failure
*/
public AndroidAuthenticator(Context context, Account account, String authTokenType,
boolean notifyAuthFailure) {
this(AccountManager.get(context), account, authTokenType, notifyAuthFailure);
}
// Visible for testing. Allows injection of a mock AccountManager.
AndroidAuthenticator(AccountManager accountManager, Account account,
String authTokenType, boolean notifyAuthFailure) {
mAccountManager = accountManager;
mAccount = account;
mAuthTokenType = authTokenType;
mNotifyAuthFailure = notifyAuthFailure;
}
/**
* Returns the Account being used by this authenticator.
*/
public Account getAccount() {
return mAccount;
}
// TODO: Figure out what to do about notifyAuthFailure
@SuppressWarnings("deprecation")
@Override
public String getAuthToken() throws AuthFailureError {
AccountManagerFuture<Bundle> future = mAccountManager.getAuthToken(mAccount,
mAuthTokenType, mNotifyAuthFailure, null, null);
Bundle result;
try {
result = future.getResult();
} catch (Exception e) {
throw new AuthFailureError("Error while retrieving auth token", e);
}
String authToken = null;
if (future.isDone() && !future.isCancelled()) {
if (result.containsKey(AccountManager.KEY_INTENT)) {
Intent intent = result.getParcelable(AccountManager.KEY_INTENT);
throw new AuthFailureError(intent);
}
authToken = result.getString(AccountManager.KEY_AUTHTOKEN);
}
if (authToken == null) {
throw new AuthFailureError("Got null auth token for type: " + mAuthTokenType);
}
return authToken;
}
@Override
public void invalidateAuthToken(String authToken) {
mAccountManager.invalidateAuthToken(mAccount.type, authToken);
}
}
@@ -1,36 +0,0 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* 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 com.b44t.messenger.volley.toolbox;
import com.b44t.messenger.volley.AuthFailureError;
/**
* An interface for interacting with auth tokens.
*/
public interface Authenticator {
/**
* Synchronously retrieves an auth token.
*
* @throws AuthFailureError If authentication did not succeed
*/
public String getAuthToken() throws AuthFailureError;
/**
* Invalidates the provided auth token.
*/
public void invalidateAuthToken(String authToken);
}
@@ -37,14 +37,13 @@ import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.FrameLayout;
import android.widget.ListView;
import android.widget.Toast;
import com.b44t.messenger.AndroidUtilities;
import com.b44t.messenger.ApplicationLoader;
import com.b44t.messenger.LocaleController;
import com.b44t.messenger.MrMailbox;
import com.b44t.messenger.NotificationCenter;
import com.b44t.messenger.R;
import com.b44t.messenger.Utilities;
import com.b44t.ui.ActionBar.ActionBar;
import com.b44t.ui.ActionBar.ActionBarMenu;
import com.b44t.ui.ActionBar.BaseFragment;
@@ -52,54 +51,71 @@ import com.b44t.ui.Adapters.BaseFragmentAdapter;
import com.b44t.ui.Cells.HeaderCell;
import com.b44t.ui.Cells.EditTextCell;
import com.b44t.ui.Cells.ShadowSectionCell;
import com.b44t.ui.Cells.TextInfoPrivacyCell;
import com.b44t.ui.Cells.TextInfoCell;
import com.b44t.ui.Cells.TextSettingsCell;
import com.b44t.ui.Components.LayoutHelper;
import static android.app.ProgressDialog.STYLE_HORIZONTAL;
public class AccountSettingsActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate {
// the list
private ListView listView;
private ListAdapter listAdapter;
private int rowSectionBasic;
private int rowAddrHeadline;
private int rowAddr;
private int rowMailPwHeadline;
private int rowMailPw;
private int rowInfoBelowMailPw2;
private int rowOpenAdvOpions;
private int rowSectionMail;
private int rowMailHeadline;
private int rowMailServer;
private int rowMailPort;
private int rowMailUser;
private int rowBreak2;
private int rowMailSecurity;
private int rowBreak1;
private int rowSectionSend;
private int rowSendHeadline;
private int rowSendServer;
private int rowSendPort;
private int rowSendUser;
private int rowSendPw;
private int rowSendSecurity;
private int rowInfoBelowSendPw;
private int rowCount;
private final int typeInfo = 0; // no gaps here!
private final int typeTextEntry = 1;
private final int typeShadowSection = 2;
private final int typeSection = 3;
private final int ROWTYPE_INFO = 0; // no gaps here!
private final int ROWTYPE_TEXT_ENTRY = 1;
private final int ROWTYPE_SHADOW_BREAK = 2;
private final int ROWTYPE_HEADLINE = 3;
private final int ROWTYPE_TEXT_FLAGS = 4;
EditTextCell addrCell; // warning all these objects may be null!
EditTextCell mailPwCell;
EditTextCell mailServerCell;
EditTextCell mailPortCell;
EditTextCell mailUserCell;
EditTextCell sendPwCell;
EditTextCell sendServerCell;
EditTextCell sendPortCell;
EditTextCell sendUserCell;
private EditTextCell addrCell; // warning all these objects may be null!
private EditTextCell mailPwCell;
private EditTextCell mailServerCell;
private EditTextCell mailPortCell;
private EditTextCell mailUserCell;
private EditTextCell sendPwCell;
private EditTextCell sendServerCell;
private EditTextCell sendPortCell;
private EditTextCell sendUserCell;
private final int MR_IMAP_SOCKET_STARTTLS = 0x100;
private final int MR_IMAP_SOCKET_SSL = 0x200;
private final int MR_IMAP_SOCKET_PLAIN = 0x400;
private final int MR_SMTP_SOCKET_STARTTLS = 0x10000;
private final int MR_SMTP_SOCKET_SSL = 0x20000;
private final int MR_SMTP_SOCKET_PLAIN = 0x40000;
private int m_serverFlags;
// misc.
private View doneButton;
private final static int done_button = 1;
private final int ID_DONE_BUTTON = 1;
private ProgressDialog progressDialog = null;
boolean fromIntro;
private boolean fromIntro;
private boolean m_expanded = false;
public AccountSettingsActivity(Bundle args) {
super();
@@ -112,34 +128,77 @@ public class AccountSettingsActivity extends BaseFragment implements Notificatio
public boolean onFragmentCreate() {
super.onFragmentCreate();
NotificationCenter.getInstance().addObserver(this, NotificationCenter.connectionStateChanged);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.configureEnded);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.configureProgress);
rowCount = 0;
rowSectionBasic = rowCount++;
rowAddr = rowCount++;
rowMailPw = rowCount++;
rowInfoBelowMailPw2 = rowCount++;
m_serverFlags = MrMailbox.getConfigInt("server_flags", 0);
rowSectionMail = rowCount++;
rowMailServer = rowCount++;
rowMailUser = rowCount++;
rowMailPort = rowCount++;
rowBreak2 = rowCount++;
m_expanded = false;
if( !MrMailbox.getConfig("mail_user", "").isEmpty()
|| !MrMailbox.getConfig("mail_server", "").isEmpty()
|| !MrMailbox.getConfig("mail_port", "").isEmpty()
|| !MrMailbox.getConfig("send_user", "").isEmpty()
|| !MrMailbox.getConfig("send_pw", "").isEmpty()
|| !MrMailbox.getConfig("send_server", "").isEmpty()
|| !MrMailbox.getConfig("send_port", "").isEmpty()
|| (m_serverFlags!=0) ) {
m_expanded = true;
}
rowSectionSend = rowCount++;
rowSendServer = rowCount++;
rowSendUser = rowCount++;
rowSendPw = rowCount++;
rowSendPort = rowCount++;
rowInfoBelowSendPw = rowCount++;
calculateRows();
return true;
}
private void calculateRows()
{
rowCount = 0;
rowAddrHeadline = rowCount++;
rowAddr = rowCount++;
rowMailPwHeadline= rowCount++;
rowMailPw = rowCount++;
rowOpenAdvOpions = rowCount++;
if( m_expanded ) {
rowMailHeadline = rowCount++;
rowMailUser = rowCount++; // should be the first additional option, the loginname is the component, that cannot be configured automatically (if not derivable from the address)
rowMailServer = rowCount++;
rowMailPort = rowCount++;
rowMailSecurity = rowCount++;
rowBreak1 = rowCount++;
rowSendHeadline = rowCount++;
rowSendUser = rowCount++;
rowSendPw = rowCount++;
rowSendServer = rowCount++;
rowSendPort = rowCount++;
rowSendSecurity = rowCount++;
}
else {
rowMailHeadline = -1;
rowMailUser = -1;
rowMailServer = -1;
rowMailPort = -1;
rowMailSecurity = -1;
rowBreak1 = -1;
rowSendHeadline = -1;
rowSendUser = -1;
rowSendPw = -1;
rowSendServer = -1;
rowSendPort = -1;
rowSendSecurity = -1;
}
rowInfoBelowSendPw = rowCount++;
}
@Override
public void onFragmentDestroy() {
super.onFragmentDestroy();
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.connectionStateChanged);
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.configureEnded);
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.configureProgress);
}
@Override
@@ -147,7 +206,7 @@ public class AccountSettingsActivity extends BaseFragment implements Notificatio
// create action bar
if( !fromIntro ) {
actionBar.setBackButtonImage(R.drawable.ic_ab_back);
actionBar.setBackButtonImage(R.drawable.ic_close_white);
}
actionBar.setAllowOverlayTitle(true);
@@ -155,30 +214,16 @@ public class AccountSettingsActivity extends BaseFragment implements Notificatio
actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() {
@Override
public void onItemClick(int id) {
if (id == -1 && !fromIntro ) {
if( isModified() ) { // TODO: maybe we should also ask if the user presses the "back" button
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
builder.setMessage(LocaleController.getString("DiscardChanges", R.string.DiscardChanges));
builder.setPositiveButton(LocaleController.getString("Yes", R.string.Yes), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
finishFragment();
}
});
builder.setNegativeButton(LocaleController.getString("No", R.string.No), null);
showDialog(builder.create());
}
else {
finishFragment();
}
} else if (id == done_button) {
if (id == -1 && !fromIntro ) { // no "is modified" check: as we use "close/ok" buttons instead of a "back" button it is more clear what happens. moreover, the user may have done a failed "OK" in between, so a question "discard changes?" would be ambiguously
finishFragment();
} else if (id == ID_DONE_BUTTON) {
saveData();
}
}
});
ActionBarMenu menu = actionBar.createMenu();
doneButton = menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56));
menu.addItemWithWidth(ID_DONE_BUTTON, R.drawable.ic_done, AndroidUtilities.dp(56));
// create object to hold the whole view
fragmentView = new FrameLayout(context);
@@ -188,7 +233,7 @@ public class AccountSettingsActivity extends BaseFragment implements Notificatio
// create the main layout list
listAdapter = new ListAdapter(context);
ListView listView = new ListView(context);
listView = new ListView(context);
listView.setDivider(null);
listView.setDividerHeight(0);
listView.setVerticalScrollBarEnabled(false);
@@ -198,6 +243,47 @@ public class AccountSettingsActivity extends BaseFragment implements Notificatio
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(final AdapterView<?> adapterView, View view, final int i, long l) {
if( i==rowOpenAdvOpions )
{
m_expanded = !m_expanded;
calculateRows();
listAdapter.notifyDataSetChanged();
}
else if( i==rowMailSecurity || i==rowSendSecurity )
{
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
builder.setTitle(ApplicationLoader.applicationContext.getString(R.string.SecurityTitle));
builder.setItems(new CharSequence[]{
ApplicationLoader.applicationContext.getString(R.string.Automatic),
"SSL/TLS", /*1*/
"STARTTLS", /*2*/
ApplicationLoader.applicationContext.getString(R.string.Disabled) /*3*/
}, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if( i==rowMailSecurity ) {
m_serverFlags &= ~(MR_IMAP_SOCKET_SSL | MR_IMAP_SOCKET_STARTTLS | MR_IMAP_SOCKET_PLAIN);
switch( which ) {
case 1: m_serverFlags |= MR_IMAP_SOCKET_SSL; break;
case 2: m_serverFlags |= MR_IMAP_SOCKET_STARTTLS; break;
case 3: m_serverFlags |= MR_IMAP_SOCKET_PLAIN; break;
}
}
else if( i==rowSendSecurity ) {
m_serverFlags &= ~(MR_SMTP_SOCKET_SSL | MR_SMTP_SOCKET_STARTTLS | MR_SMTP_SOCKET_PLAIN);
switch( which ) {
case 1: m_serverFlags |= MR_SMTP_SOCKET_SSL; break;
case 2: m_serverFlags |= MR_SMTP_SOCKET_STARTTLS; break;
case 3: m_serverFlags |= MR_SMTP_SOCKET_PLAIN; break;
}
}
listView.invalidateViews();
}
});
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
showDialog(builder.create());
}
}
});
@@ -208,13 +294,6 @@ public class AccountSettingsActivity extends BaseFragment implements Notificatio
// Warning: the widgets are created as needed and may not be present!
String v;
/*
if( !isModified() && MrMailbox.MrMailboxIsConfigured(MrMailbox.hMailbox)!=0 ) {
finishFragment();
return; // nothing to do
}
*/
if( addrCell!=null) {
v = addrCell.getValue().trim();
MrMailbox.setConfig("addr", v.isEmpty() ? null : v);
@@ -260,6 +339,8 @@ public class AccountSettingsActivity extends BaseFragment implements Notificatio
MrMailbox.setConfig("send_pw", v.isEmpty() ? null : v);
}
MrMailbox.setConfigInt("server_flags", m_serverFlags);
// show dialog
if( progressDialog!=null ) {
progressDialog.dismiss();
@@ -267,74 +348,77 @@ public class AccountSettingsActivity extends BaseFragment implements Notificatio
}
progressDialog = new ProgressDialog(getParentActivity());
progressDialog.setMessage(LocaleController.getString("ConfiguringAccount", R.string.ConfiguringAccount));
progressDialog.setMessage(ApplicationLoader.applicationContext.getString(R.string.OneMoment));
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.setCancelable(false);
progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, LocaleController.getString("Cancel", R.string.Cancel), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
progressDialog = null;
}
});
@Override
public void onClick(DialogInterface dialog, int which) {
MrMailbox.configureCancel();
}
});
progressDialog.show();
// try to connect
// (for the future, we may put all this togehter in a single command, that is executed
// asynchronously by the backend; then we can skip creating a runnable here)
Utilities.searchQueue.postRunnable(new Runnable() {
@Override
public void run() {
MrMailbox.disconnect();
MrMailbox.configure();
MrMailbox.connect();
}
});
synchronized (MrMailbox.m_lastErrorLock) {
MrMailbox.m_showNextErrorAsToast = false;
MrMailbox.m_lastErrorString = "";
}
// try to connect, this results in an MR_EVENT_CONFIGURE_ENDED resp. NotificationCenter.configureEnded event
MrMailbox.configureAndConnect();
}
@Override
public void didReceivedNotification(int id, Object... args) {
if (id == NotificationCenter.connectionStateChanged ) {
if( id == NotificationCenter.configureProgress )
{
if( progressDialog!=null ) {
// we want the spinner together with a progress info
int percent = (Integer)args[0];
progressDialog.setMessage(ApplicationLoader.applicationContext.getString(R.string.OneMoment)+String.format(" %d%%", percent));
}
}
else if (id == NotificationCenter.configureEnded )
{
final String errorString;
synchronized (MrMailbox.m_lastErrorLock) {
MrMailbox.m_showNextErrorAsToast = true;
errorString = MrMailbox.m_lastErrorString;
}
if( progressDialog!=null ) {
progressDialog.dismiss();
progressDialog = null;
}
if( (int)args[0]==1 ) {
if( fromIntro ) {
if (fromIntro) {
presentFragment(new DialogsActivity(null), true);
((LaunchActivity)getParentActivity()).drawerLayoutContainer.setAllowOpenDrawer(true, false);
}
else {
LaunchActivity la = ((LaunchActivity) getParentActivity());
if (la != null) {
la.drawerLayoutContainer.setAllowOpenDrawer(true, false);
}
} else {
finishFragment();
}
AndroidUtilities.showDoneHint(ApplicationLoader.applicationContext);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.mainUserInfoChanged);
}
else {
String err = MrMailbox.getErrorDescr();
if( err.isEmpty() ) {
err = LocaleController.getString("CannotConnect", R.string.CannotConnect);
}
Toast.makeText(getParentActivity(), err, Toast.LENGTH_LONG).show();
else if( ! MrMailbox.m_lastErrorString.isEmpty() ){
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
builder.setMessage(errorString);
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
;
}
});
showDialog(builder.create());
}
}
}
private boolean isModified(){
// Warning: the widgets are created as needed and may not be present!
if( addrCell!=null && addrCell.isModified()) { return true; }
if( mailPwCell!=null && mailPwCell.isModified()) { return true; }
if( mailServerCell!=null && mailServerCell.isModified()) { return true; }
if( mailPortCell!=null && mailPortCell.isModified()) { return true; }
if( mailUserCell!=null && mailUserCell.isModified()) { return true; }
if( sendServerCell!=null && sendServerCell.isModified()) { return true; }
if( sendPortCell!=null && sendPortCell.isModified()) { return true; }
if( sendUserCell!=null && sendUserCell.isModified()) { return true; }
if( sendPwCell!=null && sendPwCell.isModified()) { return true; }
return false;
}
@Override
public void onTransitionAnimationEnd(boolean isOpen, boolean backward) {
if (isOpen && addrCell!=null) {
@@ -359,8 +443,7 @@ public class AccountSettingsActivity extends BaseFragment implements Notificatio
@Override
public boolean isEnabled(int i) {
return (i == rowAddr || i==rowMailPw || i==rowMailServer || i==rowMailPort|| i==rowMailUser
|| i==rowSendServer || i==rowSendPort || i==rowSendUser || i== rowSendPw);
return !(i==rowAddrHeadline || i==rowMailPwHeadline || i== rowMailHeadline || i== rowBreak1 || i== rowSendHeadline || i==rowInfoBelowSendPw);
}
@Override
@@ -386,21 +469,21 @@ public class AccountSettingsActivity extends BaseFragment implements Notificatio
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
int type = getItemViewType__(i);
if (type == typeTextEntry) {
if (type == ROWTYPE_TEXT_ENTRY) {
if (i == rowAddr) {
if( addrCell==null) {
addrCell = new EditTextCell(mContext);
addrCell = new EditTextCell(mContext, false);
addrCell.setValueHintAndLabel(MrMailbox.getConfig("addr", ""),
"", LocaleController.getString("MyEmailAddress", R.string.MyEmailAddress), false);
"", "", false);
addrCell.getEditTextView().setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
}
view = addrCell;
}
else if (i == rowMailPw) {
if( mailPwCell==null) {
mailPwCell = new EditTextCell(mContext);
mailPwCell = new EditTextCell(mContext, false);
mailPwCell.setValueHintAndLabel(MrMailbox.getConfig("mail_pw", ""),
"", LocaleController.getString("Password", R.string.Password), false);
"", "", false);
mailPwCell.getEditTextView().setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_TEXT_VARIATION_PASSWORD);
}
view = mailPwCell;
@@ -409,7 +492,8 @@ public class AccountSettingsActivity extends BaseFragment implements Notificatio
if( mailServerCell==null) {
mailServerCell = new EditTextCell(mContext);
mailServerCell.setValueHintAndLabel(MrMailbox.getConfig("mail_server", ""),
LocaleController.getString("Automatic", R.string.Automatic), LocaleController.getString("ImapServer", R.string.ImapServer), false);
ApplicationLoader.applicationContext.getString(R.string.Automatic), LocaleController.getString("ImapServer", R.string.ImapServer), false);
mailServerCell.getEditTextView().setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_URI);
}
view = mailServerCell;
}
@@ -417,7 +501,8 @@ public class AccountSettingsActivity extends BaseFragment implements Notificatio
if( mailPortCell==null) {
mailPortCell = new EditTextCell(mContext);
mailPortCell.setValueHintAndLabel(MrMailbox.getConfig("mail_port", ""),
LocaleController.getString("Default", R.string.Default), LocaleController.getString("ImapPort", R.string.ImapPort), false);
ApplicationLoader.applicationContext.getString(R.string.Automatic), LocaleController.getString("ImapPort", R.string.ImapPort), false);
mailPortCell.getEditTextView().setInputType(InputType.TYPE_CLASS_NUMBER);
}
view = mailPortCell;
}
@@ -425,7 +510,7 @@ public class AccountSettingsActivity extends BaseFragment implements Notificatio
if( mailUserCell==null) {
mailUserCell = new EditTextCell(mContext);
mailUserCell.setValueHintAndLabel(MrMailbox.getConfig("mail_user", ""),
LocaleController.getString("FromAbove", R.string.FromAbove), LocaleController.getString("ImapLoginname", R.string.ImapLoginname), false);
ApplicationLoader.applicationContext.getString(R.string.Automatic), LocaleController.getString("ImapLoginname", R.string.ImapLoginname), false);
}
view = mailUserCell;
}
@@ -433,7 +518,8 @@ public class AccountSettingsActivity extends BaseFragment implements Notificatio
if( sendServerCell==null) {
sendServerCell = new EditTextCell(mContext);
sendServerCell.setValueHintAndLabel(MrMailbox.getConfig("send_server", ""),
LocaleController.getString("Automatic", R.string.Automatic), LocaleController.getString("SmtpServer", R.string.SmtpServer), false);
ApplicationLoader.applicationContext.getString(R.string.Automatic), LocaleController.getString("SmtpServer", R.string.SmtpServer), false);
sendServerCell.getEditTextView().setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_URI);
}
view = sendServerCell;
}
@@ -441,7 +527,8 @@ public class AccountSettingsActivity extends BaseFragment implements Notificatio
if( sendPortCell==null) {
sendPortCell = new EditTextCell(mContext);
sendPortCell.setValueHintAndLabel(MrMailbox.getConfig("send_port", ""),
LocaleController.getString("Default", R.string.Default), LocaleController.getString("SmtpPort", R.string.SmtpPort), false);
ApplicationLoader.applicationContext.getString(R.string.Automatic), LocaleController.getString("SmtpPort", R.string.SmtpPort), false);
sendPortCell.getEditTextView().setInputType(InputType.TYPE_CLASS_NUMBER);
}
view = sendPortCell;
}
@@ -449,7 +536,7 @@ public class AccountSettingsActivity extends BaseFragment implements Notificatio
if( sendUserCell==null) {
sendUserCell = new EditTextCell(mContext);
sendUserCell.setValueHintAndLabel(MrMailbox.getConfig("send_user", ""),
LocaleController.getString("FromAbove", R.string.FromAbove), LocaleController.getString("SmtpLoginname", R.string.SmtpLoginname), false);
ApplicationLoader.applicationContext.getString(R.string.Automatic), LocaleController.getString("SmtpLoginname", R.string.SmtpLoginname), false);
}
view = sendUserCell;
}
@@ -463,35 +550,59 @@ public class AccountSettingsActivity extends BaseFragment implements Notificatio
view = sendPwCell;
}
}
else if (type == typeSection) {
else if (type ==ROWTYPE_TEXT_FLAGS) {
if (view == null) {
view = new TextSettingsCell(mContext);
view.setBackgroundColor(0xffffffff);
}
TextSettingsCell textCell = (TextSettingsCell) view;
String value = ApplicationLoader.applicationContext.getString(R.string.Automatic);
if( i == rowMailSecurity ) {
if( (m_serverFlags&MR_IMAP_SOCKET_SSL)!=0 ) { value = "SSL/TLS"; }
if( (m_serverFlags&MR_IMAP_SOCKET_STARTTLS)!=0 ) { value = "STARTTLS"; }
if( (m_serverFlags&MR_IMAP_SOCKET_PLAIN)!=0 ) { value = ApplicationLoader.applicationContext.getString(R.string.Disabled); }
}
else if( i == rowSendSecurity ) {
if( (m_serverFlags&MR_SMTP_SOCKET_SSL)!=0 ) { value = "SSL/TLS"; }
if( (m_serverFlags&MR_SMTP_SOCKET_STARTTLS)!=0 ) { value = "STARTTLS"; }
if( (m_serverFlags&MR_SMTP_SOCKET_PLAIN)!=0 ) { value = ApplicationLoader.applicationContext.getString(R.string.Disabled); }
}
textCell.setTextAndValue(ApplicationLoader.applicationContext.getString(R.string.SecurityTitle), value, false);
}
else if (type == ROWTYPE_HEADLINE) {
if (view == null) {
view = new HeaderCell(mContext);
view.setBackgroundColor(0xffffffff);
}
if (i == rowSectionBasic) {
((HeaderCell) view).setText(LocaleController.getString("BasicSettings", R.string.BasicSettings));
} else if (i == rowSectionMail) {
if (i == rowAddrHeadline) {
((HeaderCell) view).setText(ApplicationLoader.applicationContext.getString(R.string.EmailAddress));
} else if (i == rowMailPwHeadline) {
((HeaderCell) view).setText(ApplicationLoader.applicationContext.getString(R.string.Password));
} else if (i == rowMailHeadline) {
((HeaderCell) view).setText(LocaleController.getString("InboxHeadline", R.string.InboxHeadline));
} else if (i == rowSectionSend) {
} else if (i == rowSendHeadline) {
((HeaderCell) view).setText(LocaleController.getString("OutboxHeadline", R.string.OutboxHeadline));
}
}
else if (type == typeShadowSection) {
else if (type == ROWTYPE_SHADOW_BREAK) {
if (view == null) {
view = new ShadowSectionCell(mContext);
}
}
else if (type == typeInfo) {
else if (type == ROWTYPE_INFO) {
if (view == null) {
view = new TextInfoPrivacyCell(mContext);
view = new TextInfoCell(mContext);
}
if( i==rowInfoBelowMailPw2) {
((TextInfoPrivacyCell) view).setText(LocaleController.getString("MyAccoutExplain", R.string.MyAccountExplain)+"\n");
view.setBackgroundResource(R.drawable.greydivider); // has shadow top+bottom
if( i== rowOpenAdvOpions) {
((TextInfoCell) view).setText(LocaleController.getString("MyAccoutExplain", R.string.MyAccountExplain),
m_expanded? " \u2212" /*minus-sign*/ : "+", m_expanded /*draw bottom border?*/);
view.setBackgroundResource(m_expanded? R.drawable.greydivider : R.drawable.greydivider_bottom); // has shadow top+bottom
}
else if( i==rowInfoBelowSendPw) {
((TextInfoPrivacyCell) view).setText(LocaleController.getString("MyAccountExplain2", R.string.MyAccountExplain2));
view.setBackgroundResource(R.drawable.greydivider_bottom);
((TextInfoCell) view).setText(AndroidUtilities.replaceTags(LocaleController.getString("MyAccountExplain2", R.string.MyAccountExplain2)));
if( m_expanded ) {
view.setBackgroundResource(R.drawable.greydivider_bottom);
}
}
}
return view;
@@ -505,15 +616,18 @@ public class AccountSettingsActivity extends BaseFragment implements Notificatio
private int getItemViewType__(int i) {
if (i == rowAddr || i==rowMailPw || i==rowMailServer || i==rowMailPort|| i==rowMailUser
|| i==rowSendServer || i==rowSendPort || i==rowSendUser || i== rowSendPw ) {
return typeTextEntry;
return ROWTYPE_TEXT_ENTRY;
}
else if( i==rowSectionBasic || i==rowSectionMail || i==rowSectionSend ) {
return typeSection;
else if( i==rowAddrHeadline || i==rowMailPwHeadline || i== rowMailHeadline || i== rowSendHeadline ) {
return ROWTYPE_HEADLINE;
}
else if( i== rowBreak2) {
return typeShadowSection;
else if( i== rowBreak1 ) {
return ROWTYPE_SHADOW_BREAK;
}
return typeInfo;
else if( i==rowMailSecurity || i==rowSendSecurity) {
return ROWTYPE_TEXT_FLAGS;
}
return ROWTYPE_INFO;
}
@Override
@@ -28,6 +28,7 @@ import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.view.Gravity;
@@ -160,7 +161,6 @@ public class ActionBar extends FrameLayout {
titleTextView = new SimpleTextView(getContext());
titleTextView.setGravity(Gravity.LEFT);
titleTextView.setTextColor(0xffffffff);
titleTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
addView(titleTextView, 0, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP));
}
@@ -655,7 +655,7 @@ public class ActionBarLayout extends FrameLayout {
if (parentActivity.getCurrentFocus() != null) {
AndroidUtilities.hideKeyboard(parentActivity.getCurrentFocus());
}
boolean needAnimation = !forceWithoutAnimation && parentActivity.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE).getBoolean("view_animations", true);
boolean needAnimation = !forceWithoutAnimation && parentActivity.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE).getBoolean("view_animations2", true);
final BaseFragment currentFragment = !fragmentsStack.isEmpty() ? fragmentsStack.get(fragmentsStack.size() - 1) : null;
@@ -863,7 +863,7 @@ public class ActionBarLayout extends FrameLayout {
AndroidUtilities.hideKeyboard(parentActivity.getCurrentFocus());
}
setInnerTranslationX(0);
boolean needAnimation = animated && parentActivity.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE).getBoolean("view_animations", true);
boolean needAnimation = animated && parentActivity.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE).getBoolean("view_animations2", true);
final BaseFragment currentFragment = fragmentsStack.get(fragmentsStack.size() - 1);
BaseFragment previousFragment = null;
if (fragmentsStack.size() > 1) {
@@ -49,6 +49,19 @@ public class BaseFragment {
protected boolean swipeBackEnabled = true;
protected boolean hasOwnBackground = false;
// IDs forwarded from startActivityForResult() to onActivityResultFragment()
public final static int
RC0_CHAT_IMAGE_CAPTURE = 0,
RC1_CHAT_PICK = 1,
RC2_CHAT_VIDEO_CAPTURE = 2,
RC10_WALLPAPER_IMAGE_CAPTURE = 10,
RC11_WALLPAPER_PICK = 11,
RC12_PROFILE_RINGTONE_PICKER = 12,
RC13_AVATAR_IMAGE_CAPTURE = 13,
RC14_AVATAR_GET_CONTENT = 14,
RC21_CHAT_PICK_WO_COMPR = 21,
RC500_PHOTO_VIEW = 500;
public BaseFragment() {
classGuid = ConnectionsManager.getInstance().generateClassGuid();
}
@@ -464,7 +464,6 @@ public class BottomSheet extends Dialog {
textView.setGravity(Gravity.CENTER);
textView.setTextColor(0xff212121);
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
}
}
@@ -43,10 +43,9 @@ import com.b44t.ui.Components.ChatAttachAlert;
public class Theme {
public static final int ACTION_BAR_COLOR = 0xff415e6b; // also used for the notification icon background
public static final int ACTION_BAR_COLOR = 0xff415e6b; // also used for the notification icon background and as pincode-default-background color, TODO: let player_big_notification/player_small_notification use this color automatically
public static final int ACTION_BAR_PHOTO_VIEWER_COLOR = 0x7f000000;
public static final int ACTION_BAR_MEDIA_PICKER_COLOR = 0xff333333;
public static final int ACTION_BAR_PLAYER_COLOR = 0xffffffff;
public static final int ACTION_BAR_TITLE_COLOR = 0xffffffff;
public static final int ACTION_BAR_SUBTITLE_COLOR = 0xffd5e8f7;
public static final int ACTION_BAR_ACTION_MODE_TEXT_COLOR = 0xff737373;
@@ -61,7 +60,7 @@ public class Theme {
public static final int ATTACH_SHEET_TEXT_COLOR = 0xff757575;
public static final int DIALOGS_TITLE_TEXT_COLOR = 0xff212121;
public static final int DIALOGS_TITLE_TEXT_COLOR = 0xff000000;
public static final int DIALOGS_MESSAGE_TEXT_COLOR = 0xff8f8f8f;
public static final int DIALOGS_NAME_TEXT_COLOR = 0xff555555;
public static final int DIALOGS_SELF_TEXT_COLOR = 0xff00a60e; // from encrypted chat title: 0xff00a60e, alternative: 0xff3c912e
@@ -69,18 +68,8 @@ public class Theme {
public static final int DIALOGS_DRAFT_TEXT_COLOR = 0xffdd4b39;
public static final int CHAT_BOTTOM_OVERLAY_TEXT_COLOR = 0xff7f7f7f;
public static final int CHAT_GIF_HINT_TEXT_COLOR = 0xffffffff;
public static final int CHAT_EMPTY_VIEW_TEXT_COLOR = 0xffffffff;
public static final int INAPP_PLAYER_PERFORMER_TEXT_COLOR = 0xff2f3438;
public static final int INAPP_PLAYER_TITLE_TEXT_COLOR = 0xff2f3438;
public static final int INAPP_PLAYER_BACKGROUND_COLOR = 0xffffffff;
public static final int ALERT_PANEL_NAME_TEXT_COLOR = 0xff3a8ccf;
public static final int ALERT_PANEL_MESSAGE_TEXT_COLOR = 0xff999999;
public static final int AUTODOWNLOAD_SHEET_SAVE_TEXT_COLOR = 0xff3a8ccf;
public static final int STICKERS_SHEET_TITLE_TEXT_COLOR = 0xff212121;
public static final int STICKERS_SHEET_SEND_TEXT_COLOR = 0xff3a8ccf;
public static final int STICKERS_SHEET_ADD_TEXT_COLOR = 0xff3a8ccf;
@@ -88,87 +77,24 @@ public class Theme {
public static final int STICKERS_SHEET_REMOVE_TEXT_COLOR = 0xffcd5a5a;
public static final int MSG_SELECTED_BACKGROUND_COLOR = 0x6633b5e5;
public static final int MSG_WEB_PREVIEW_DURATION_TEXT_COLOR = 0xffffffff;
public static final int MSG_STICKER_NAME_TEXT_COLOR = 0xffffffff;
public static final int MSG_IN_FORDWARDED_NAME_TEXT_COLOR = 0xff3886c7;
public static final int MSG_OUT_FORDWARDED_NAME_TEXT_COLOR = 0xff55ab4f;
public static final int MSG_IN_REPLY_LINE_COLOR = 0xff70b4e8;
public static final int MSG_OUT_REPLY_LINE_COLOR = 0xff88c97b;
public static final int MSG_STICKER_REPLY_LINE_COLOR = 0xffffffff;
public static final int MSG_IN_REPLY_NAME_TEXT_COLOR = 0xff3a8ccf;
public static final int MSG_OUT_REPLY_NAME_TEXT_COLOR = 0xff55ab4f;
public static final int MSG_STICKER_REPLY_NAME_TEXT_COLOR = 0xffffffff;
public static final int MSG_IN_REPLY_MESSAGE_TEXT_COLOR = 0xff000000;
public static final int MSG_OUT_REPLY_MESSAGE_TEXT_COLOR = 0xff000000;
public static final int MSG_IN_REPLY_MEDIA_MESSAGE_TEXT_COLOR = 0xffa1aab3;
public static final int MSG_OUT_REPLY_MEDIA_MESSAGE_TEXT_COLOR = 0xff65b05b;
public static final int MSG_IN_REPLY_MEDIA_MESSAGE_SELETED_TEXT_COLOR = 0xff89b4c1;
public static final int MSG_OUT_REPLY_MEDIA_MESSAGE_SELETED_TEXT_COLOR = 0xff65b05b;
public static final int MSG_STICKER_REPLY_MESSAGE_TEXT_COLOR = 0xffffffff;
public static final int MSG_IN_WEB_PREVIEW_LINE_COLOR = 0xff70b4e8;
public static final int MSG_OUT_WEB_PREVIEW_LINE_COLOR = 0xff88c97b;
public static final int MSG_IN_SITE_NAME_TEXT_COLOR = 0xff3a8ccf;
public static final int MSG_OUT_SITE_NAME_TEXT_COLOR = 0xff55ab4f;
public static final int MSG_IN_CONTACT_NAME_TEXT_COLOR = 0xff4e9ad4;
public static final int MSG_OUT_CONTACT_NAME_TEXT_COLOR = 0xff55ab4f;
public static final int MSG_IN_CONTACT_PHONE_TEXT_COLOR = 0xff2f3438;
public static final int MSG_OUT_CONTACT_PHONE_TEXT_COLOR = 0xff354234;
public static final int MSG_MEDIA_PROGRESS_COLOR = 0xffffffff;
public static final int MSG_IN_AUDIO_PROGRESS_COLOR = 0xffffffff;
public static final int MSG_OUT_AUDIO_PROGRESS_COLOR = 0xffefffde;
public static final int MSG_IN_AUDIO_SELECTED_PROGRESS_COLOR = 0xffe2f8ff;
public static final int MSG_OUT_AUDIO_SELECTED_PROGRESS_COLOR = 0xffd4f5bc;
public static final int MSG_MEDIA_TIME_TEXT_COLOR = 0xffffffff;
public static final int MSG_IN_TIME_TEXT_COLOR = 0xffa1aab3;
public static final int MSG_IN_TIME_N_FWD_TEXT_COLOR = 0xff9ea7b0;
public static final int MSG_OUT_TIME_TEXT_COLOR = 0xff70b15c;
public static final int MSG_IN_TIME_SELECTED_TEXT_COLOR = 0xff89b4c1;
public static final int MSG_OUT_TIME_SELECTED_TEXT_COLOR = 0xff70b15c;
public static final int MSG_IN_AUDIO_PERFORMER_TEXT_COLOR = 0xff2f3438;
public static final int MSG_OUT_AUDIO_PERFORMER_TEXT_COLOR = 0xff354234;
public static final int MSG_IN_AUDIO_TITLE_TEXT_COLOR = 0xff4e9ad4;
public static final int MSG_OUT_AUDIO_TITLE_TEXT_COLOR = 0xff55ab4f;
public static final int MSG_IN_AUDIO_DURATION_TEXT_COLOR = 0xffa1aab3;
public static final int MSG_OUT_AUDIO_DURATION_TEXT_COLOR = 0xff65b05b;
public static final int MSG_IN_AUDIO_DURATION_SELECTED_TEXT_COLOR = 0xff89b4c1;
public static final int MSG_OUT_AUDIO_DURATION_SELECTED_TEXT_COLOR = 0xff65b05b;
public static final int MSG_IN_AUDIO_SEEKBAR_COLOR = 0xffe4eaf0;
public static final int MSG_OUT_AUDIO_SEEKBAR_COLOR = 0xffbbe3ac;
public static final int MSG_IN_AUDIO_SEEKBAR_SELECTED_COLOR = 0xffbcdee8;
public static final int MSG_OUT_AUDIO_SEEKBAR_SELECTED_COLOR = 0xffa9dd96;
public static final int MSG_IN_AUDIO_SEEKBAR_FILL_COLOR = 0xff72b5e8;
public static final int MSG_OUT_AUDIO_SEEKBAR_FILL_COLOR = 0xff78c272;
public static final int MSG_IN_VOICE_SEEKBAR_COLOR = 0xffdee5eb;
public static final int MSG_OUT_VOICE_SEEKBAR_COLOR = 0xffbbe3ac;
public static final int MSG_IN_VOICE_SEEKBAR_SELECTED_COLOR = 0xffbcdee8;
public static final int MSG_OUT_VOICE_SEEKBAR_SELECTED_COLOR = 0xffa9dd96;
public static final int MSG_IN_VOICE_SEEKBAR_FILL_COLOR = 0xff72b5e8;
public static final int MSG_OUT_VOICE_SEEKBAR_FILL_COLOR = 0xff78c272;
public static final int MSG_IN_FILE_PROGRESS_COLOR = 0xffebf0f5;
public static final int MSG_OUT_FILE_PROGRESS_COLOR = 0xffdaf5c3;
public static final int MSG_IN_FILE_PROGRESS_SELECTED_COLOR = 0xffcbeaf6;
public static final int MSG_OUT_FILE_PROGRESS_SELECTED_COLOR = 0xffc5eca7;
public static final int MSG_IN_FILE_NAME_TEXT_COLOR = 0xff4e9ad4;
public static final int MSG_OUT_FILE_NAME_TEXT_COLOR = 0xff55ab4f;
public static final int MSG_IN_FILE_INFO_TEXT_COLOR = 0xffa1aab3;
public static final int MSG_OUT_FILE_INFO_TEXT_COLOR = 0xff65b05b;
public static final int MSG_IN_FILE_INFO_SELECTED_TEXT_COLOR = 0xff89b4c1;
public static final int MSG_OUT_FILE_INFO_SELECTED_TEXT_COLOR = 0xff65b05b;
public static final int MSG_MEDIA_TIME_TEXT_COLOR = 0xffffffff;
public static final int MSG_IN_FILE_BACKGROUND_COLOR = 0xffebf0f5;
public static final int MSG_OUT_FILE_BACKGROUND_COLOR = 0xffdaf5c3;
public static final int MSG_IN_FILE_BACKGROUND_SELECTED_COLOR = 0xffcbeaf6;
public static final int MSG_OUT_FILE_BACKGROUND_SELECTED_COLOR = 0xffc5eca7;
public static final int MSG_IN_VENUE_NAME_TEXT_COLOR = 0xff4e9ad4;
public static final int MSG_OUT_VENUE_NAME_TEXT_COLOR = 0xff55ab4f;
public static final int MSG_IN_VENUE_INFO_TEXT_COLOR = 0xffa1aab3;
public static final int MSG_OUT_VENUE_INFO_TEXT_COLOR = 0xff65b05b;
public static final int MSG_IN_VENUE_INFO_SELECTED_TEXT_COLOR = 0xff89b4c1;
public static final int MSG_OUT_VENUE_INFO_SELECTED_TEXT_COLOR = 0xff65b05b;
public static final int MSG_MEDIA_INFO_TEXT_COLOR = 0xffffffff;
public static final int MSG_TEXT_COLOR = 0xff000000;
public static final int MSG_LINK_TEXT_COLOR = 0xff2678b6;
public static final int MSG_LINK_SELECT_BACKGROUND_COLOR = 0x3362a9e3;
public static final int MSG_TEXT_SELECT_BACKGROUND_COLOR = 0x6662a9e3;
public static final int MSG_DOC_NAME_COLOR = 0xFF3093e0; // similar color as the file-icon
public static final int MSG_AUDIO_NAME_COLOR = 0xFFed824e; // similar color as the audio-icon
public static final int MSG_AUDIO_SEEKBAR_DARK_COLOR = 0xFFf68751; // same color as in audio-icon, also used for the record-button
public static final int MSG_AUDIO_SEEKBAR_LITE_COLOR = 0xFFfbc8af;
public static Drawable backgroundDrawableIn;
public static Drawable backgroundDrawableInSelected;
@@ -188,18 +114,16 @@ public class Theme {
public static Drawable[] cornerOuter = new Drawable[4];
public static Drawable[] cornerInner = new Drawable[4];
public static Drawable shareIconDrawable;
public static Drawable newchatIconDrawable;
public static Drawable geoInDrawable;
public static Drawable geoOutDrawable;
public static Drawable[] contactDrawable = new Drawable[2];
public static Drawable[][] fileStatesDrawable = new Drawable[10][2];
public static Drawable[][] photoStatesDrawables = new Drawable[13][2];
public static Drawable[] docMenuDrawable = new Drawable[4];
public static final int INLIST_FILE = 0;
public static final int INLIST_PLAY = 1;
public static final int INLIST_PAUSE = 2;
public static final int INLIST_TRANSP_PLAY = 3;
public static final int INLIST_COUNT = 4;
public static Drawable[] inlistDrawable = new Drawable[INLIST_COUNT];
public static PorterDuffColorFilter colorFilter;
public static PorterDuffColorFilter colorPressedFilter;
private static int currentColor;
public static Drawable attachButtonDrawables[] = new Drawable[8];
@@ -223,63 +147,12 @@ public class Theme {
timeStickerBackgroundDrawable = context.getResources().getDrawable(R.drawable.phototime2);
systemDrawable = context.getResources().getDrawable(R.drawable.system);
fileStatesDrawable[0][0] = context.getResources().getDrawable(R.drawable.play_g); // self
fileStatesDrawable[0][1] = context.getResources().getDrawable(R.drawable.play_g_s);
fileStatesDrawable[1][0] = context.getResources().getDrawable(R.drawable.pause_g);
fileStatesDrawable[1][1] = context.getResources().getDrawable(R.drawable.pause_g_s);
fileStatesDrawable[2][0] = context.getResources().getDrawable(R.drawable.file_g_load);
fileStatesDrawable[2][1] = context.getResources().getDrawable(R.drawable.file_g_load_s);
fileStatesDrawable[3][0] = context.getResources().getDrawable(R.drawable.file_g);
fileStatesDrawable[3][1] = context.getResources().getDrawable(R.drawable.file_g_s);
fileStatesDrawable[4][0] = context.getResources().getDrawable(R.drawable.file_g_cancel);
fileStatesDrawable[4][1] = context.getResources().getDrawable(R.drawable.file_g_cancel_s);
fileStatesDrawable[5][0] = context.getResources().getDrawable(R.drawable.play_b); // from other = self+5
fileStatesDrawable[5][1] = context.getResources().getDrawable(R.drawable.play_b_s);
fileStatesDrawable[6][0] = context.getResources().getDrawable(R.drawable.pause_b);
fileStatesDrawable[6][1] = context.getResources().getDrawable(R.drawable.pause_b_s);
fileStatesDrawable[7][0] = context.getResources().getDrawable(R.drawable.file_b_load);
fileStatesDrawable[7][1] = context.getResources().getDrawable(R.drawable.file_b_load_s);
fileStatesDrawable[8][0] = context.getResources().getDrawable(R.drawable.file_b);
fileStatesDrawable[8][1] = context.getResources().getDrawable(R.drawable.file_b_s);
fileStatesDrawable[9][0] = context.getResources().getDrawable(R.drawable.file_b_cancel);
fileStatesDrawable[9][1] = context.getResources().getDrawable(R.drawable.file_b_cancel_s);
inlistDrawable[INLIST_FILE] = context.getResources().getDrawable(R.drawable.attach_file_inlist);
inlistDrawable[INLIST_PLAY] = context.getResources().getDrawable(R.drawable.attach_audio_inlist_play);
inlistDrawable[INLIST_TRANSP_PLAY] = context.getResources().getDrawable(R.drawable.video_play);
inlistDrawable[INLIST_PAUSE] = context.getResources().getDrawable(R.drawable.attach_audio_inlist_pause);
photoStatesDrawables[0][0] = context.getResources().getDrawable(R.drawable.photoload);
photoStatesDrawables[0][1] = context.getResources().getDrawable(R.drawable.photoload_pressed);
photoStatesDrawables[1][0] = context.getResources().getDrawable(R.drawable.photocancel);
photoStatesDrawables[1][1] = context.getResources().getDrawable(R.drawable.photocancel_pressed);
photoStatesDrawables[2][0] = context.getResources().getDrawable(R.drawable.photogif);
photoStatesDrawables[2][1] = context.getResources().getDrawable(R.drawable.photogif_pressed);
photoStatesDrawables[3][0] = context.getResources().getDrawable(R.drawable.playvideo);
photoStatesDrawables[3][1] = context.getResources().getDrawable(R.drawable.playvideo_pressed);
//photoStatesDrawables[4] = context.getResources().getDrawable(R.drawable.photopause);
photoStatesDrawables[4][0] = photoStatesDrawables[4][1] = context.getResources().getDrawable(R.drawable.burn);
photoStatesDrawables[5][0] = photoStatesDrawables[5][1] = context.getResources().getDrawable(R.drawable.circle);
photoStatesDrawables[6][0] = photoStatesDrawables[6][1] = context.getResources().getDrawable(R.drawable.photocheck);
photoStatesDrawables[7][0] = context.getResources().getDrawable(R.drawable.photoload_g);
photoStatesDrawables[7][1] = context.getResources().getDrawable(R.drawable.photoload_g_s);
photoStatesDrawables[8][0] = context.getResources().getDrawable(R.drawable.photocancel_g);
photoStatesDrawables[8][1] = context.getResources().getDrawable(R.drawable.photocancel_g_s);
photoStatesDrawables[9][0] = context.getResources().getDrawable(R.drawable.doc_green);
photoStatesDrawables[9][1] = context.getResources().getDrawable(R.drawable.doc_green);
photoStatesDrawables[10][0] = context.getResources().getDrawable(R.drawable.photoload_b);
photoStatesDrawables[10][1] = context.getResources().getDrawable(R.drawable.photoload_b_s);
photoStatesDrawables[11][0] = context.getResources().getDrawable(R.drawable.photocancel_b);
photoStatesDrawables[11][1] = context.getResources().getDrawable(R.drawable.photocancel_b_s);
photoStatesDrawables[12][0] = context.getResources().getDrawable(R.drawable.doc_blue);
photoStatesDrawables[12][1] = context.getResources().getDrawable(R.drawable.doc_blue_s);
docMenuDrawable[0] = context.getResources().getDrawable(R.drawable.doc_actions_b);
docMenuDrawable[1] = context.getResources().getDrawable(R.drawable.doc_actions_g);
docMenuDrawable[2] = context.getResources().getDrawable(R.drawable.doc_actions_b_s);
docMenuDrawable[3] = context.getResources().getDrawable(R.drawable.video_actions);
contactDrawable[0] = context.getResources().getDrawable(R.drawable.contact_blue);
contactDrawable[1] = context.getResources().getDrawable(R.drawable.contact_green);
shareIconDrawable = context.getResources().getDrawable(R.drawable.ic_ab_reply);
newchatIconDrawable = context.getResources().getDrawable(R.drawable.ic_ab_reply);
cornerOuter[0] = context.getResources().getDrawable(R.drawable.corner_out_tl);
cornerOuter[1] = context.getResources().getDrawable(R.drawable.corner_out_tr);
@@ -295,7 +168,6 @@ public class Theme {
int color = ApplicationLoader.getServiceMessageColor();
if (currentColor != color) {
colorFilter = new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY);
colorPressedFilter = new PorterDuffColorFilter(ApplicationLoader.getServiceSelectedMessageColor(), PorterDuff.Mode.MULTIPLY);
currentColor = color;
for (int a = 0; a < 4; a++) {
cornerOuter[a].setColorFilter(colorFilter);
@@ -313,7 +185,7 @@ public class Theme {
attachButtonDrawables[ChatAttachAlert.ATTACH_BUTTON_IDX_MUSIC] = context.getResources().getDrawable(R.drawable.attach_audio_states);
attachButtonDrawables[ChatAttachAlert.ATTACH_BUTTON_IDX_FILE] = context.getResources().getDrawable(R.drawable.attach_file_states);
attachButtonDrawables[ChatAttachAlert.ATTACH_BUTTON_IDX_CONTACT] = context.getResources().getDrawable(R.drawable.attach_contact_states);
attachButtonDrawables[ChatAttachAlert.ATTACH_BUTTON_IDX_LOCATION] = context.getResources().getDrawable(R.drawable.attach_location_states);
attachButtonDrawables[ChatAttachAlert.ATTACH_BUTTON_IDX_EMPTY] = context.getResources().getDrawable(R.drawable.attach_empty_states);
attachButtonDrawables[ChatAttachAlert.ATTACH_BUTTON_IDX_SENDSELECTED]= context.getResources().getDrawable(R.drawable.attach_hide_states);
}
}
@@ -323,7 +195,6 @@ public class Theme {
}
public static Drawable createBarSelectorDrawable(int color, boolean masked) {
Drawable drawable;
if (Build.VERSION.SDK_INT >= 21) {
Drawable maskDrawable = null;
if (masked) {
@@ -30,7 +30,6 @@ import android.widget.BaseAdapter;
import com.b44t.messenger.AndroidUtilities;
import com.b44t.messenger.LocaleController;
import com.b44t.messenger.MessagesController;
import com.b44t.messenger.R;
import com.b44t.messenger.UserConfig;
import com.b44t.ui.Cells.DrawerActionCell;
@@ -99,7 +98,7 @@ public class DrawerLayoutAdapter extends BaseAdapter {
if (view == null) {
view = new DrawerProfileCell(mContext);
}
((DrawerProfileCell) view).setUser(MessagesController.getInstance().getUser(UserConfig.getClientUserId()));
((DrawerProfileCell) view).updateUserName();
} else if (type == typeEmpty) {
if (view == null) {
view = new EmptyCell(mContext, AndroidUtilities.dp(8));
@@ -1,483 +0,0 @@
/*******************************************************************************
*
* Messenger Android Frontend
* (C) 2013-2016 Nikolai Kudashov
* (C) 2017 Björn Petersen
* Contact: r10s@b44t.com, http://b44t.com
*
* This program 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.
*
* This program 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
* this program. If not, see http://www.gnu.org/licenses/ .
*
******************************************************************************/
package com.b44t.ui;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import com.b44t.messenger.AndroidUtilities;
import com.b44t.messenger.ImageLoader;
import com.b44t.messenger.MediaController;
import com.b44t.messenger.MessageObject;
import com.b44t.messenger.NotificationCenter;
import com.b44t.messenger.audioinfo.AudioInfo;
import com.b44t.messenger.FileLoader;
import com.b44t.messenger.R;
import com.b44t.messenger.TLRPC;
import com.b44t.ui.ActionBar.ActionBar;
import com.b44t.ui.ActionBar.BaseFragment;
import com.b44t.ui.ActionBar.Theme;
import com.b44t.ui.Components.LayoutHelper;
import com.b44t.ui.Components.LineProgressView;
import java.io.File;
public class AudioPlayerActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate, MediaController.FileDownloadProgressListener {
//private MessageObject lastMessageObject;
private ImageView placeholder;
private ImageView playButton;
private ImageView nextButton;
private ImageView prevButton;
private ImageView shuffleButton;
private LineProgressView progressView;
private ImageView repeatButton;
private ImageView[] buttons = new ImageView[5];
private TextView durationTextView;
private TextView timeTextView;
private SeekBarView seekBarView;
private int TAG;
private String lastTimeString;
private class SeekBarView extends FrameLayout {
private Paint innerPaint1;
private Paint outerPaint1;
private int thumbWidth;
private int thumbHeight;
public int thumbX = 0;
public int thumbDX = 0;
private boolean pressed = false;
public SeekBarView(Context context) {
super(context);
setWillNotDraw(false);
innerPaint1 = new Paint(Paint.ANTI_ALIAS_FLAG);
innerPaint1.setColor(0x19000000);
outerPaint1 = new Paint(Paint.ANTI_ALIAS_FLAG);
outerPaint1.setColor(0xff23afef);
thumbWidth = AndroidUtilities.dp(24);
thumbHeight = AndroidUtilities.dp(24);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return onTouch(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return onTouch(event);
}
boolean onTouch(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
getParent().requestDisallowInterceptTouchEvent(true);
int additionWidth = (getMeasuredHeight() - thumbWidth) / 2;
if (thumbX - additionWidth <= ev.getX() && ev.getX() <= thumbX + thumbWidth + additionWidth && ev.getY() >= 0 && ev.getY() <= getMeasuredHeight()) {
pressed = true;
thumbDX = (int)(ev.getX() - thumbX);
invalidate();
return true;
}
} else if (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_CANCEL) {
if (pressed) {
if (ev.getAction() == MotionEvent.ACTION_UP) {
onSeekBarDrag((float) thumbX / (float) (getMeasuredWidth() - thumbWidth));
}
pressed = false;
invalidate();
return true;
}
} else if (ev.getAction() == MotionEvent.ACTION_MOVE) {
if (pressed) {
thumbX = (int)(ev.getX() - thumbDX);
if (thumbX < 0) {
thumbX = 0;
} else if (thumbX > getMeasuredWidth() - thumbWidth) {
thumbX = getMeasuredWidth() - thumbWidth;
}
invalidate();
return true;
}
}
return false;
}
public void setProgress(float progress) {
int newThumbX = (int)Math.ceil((getMeasuredWidth() - thumbWidth) * progress);
if (thumbX != newThumbX) {
thumbX = newThumbX;
if (thumbX < 0) {
thumbX = 0;
} else if (thumbX > getMeasuredWidth() - thumbWidth) {
thumbX = getMeasuredWidth() - thumbWidth;
}
invalidate();
}
}
public boolean isDragging() {
return pressed;
}
@Override
protected void onDraw(Canvas canvas) {
int y = (getMeasuredHeight() - thumbHeight) / 2;
canvas.drawRect(thumbWidth / 2, getMeasuredHeight() / 2 - AndroidUtilities.dp(1), getMeasuredWidth() - thumbWidth / 2, getMeasuredHeight() / 2 + AndroidUtilities.dp(1), innerPaint1);
canvas.drawRect(thumbWidth / 2, getMeasuredHeight() / 2 - AndroidUtilities.dp(1), thumbWidth / 2 + thumbX, getMeasuredHeight() / 2 + AndroidUtilities.dp(1), outerPaint1);
canvas.drawCircle(thumbX + thumbWidth / 2, y + thumbHeight / 2, AndroidUtilities.dp(pressed ? 8 : 6), outerPaint1);
}
}
@Override
public boolean onFragmentCreate() {
TAG = MediaController.getInstance().generateObserverTag();
NotificationCenter.getInstance().addObserver(this, NotificationCenter.audioDidReset);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.audioPlayStateChanged);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.audioDidStarted);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.audioProgressDidChanged);
return super.onFragmentCreate();
}
@Override
public void onFragmentDestroy() {
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.audioDidReset);
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.audioPlayStateChanged);
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.audioDidStarted);
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.audioProgressDidChanged);
MediaController.getInstance().removeLoadingFileObserver(this);
super.onFragmentDestroy();
}
@Override
public View createView(Context context) {
FrameLayout frameLayout = new FrameLayout(context);
frameLayout.setBackgroundColor(0xfff0f0f0);
frameLayout.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
fragmentView = frameLayout;
actionBar.setBackgroundColor(Theme.ACTION_BAR_PLAYER_COLOR);
actionBar.setBackButtonImage(R.drawable.pl_back);
actionBar.setItemsBackgroundColor(Theme.ACTION_BAR_AUDIO_SELECTOR_COLOR);
/*if (!AndroidUtilities.isTablet()) {
actionBar.showActionModeTop();
}*/
actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() {
@Override
public void onItemClick(int id) {
if (id == -1) {
finishFragment();
}
}
});
placeholder = new ImageView(context);
frameLayout.addView(placeholder, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT, 0, 0, 0, 66));
View shadow = new View(context);
shadow.setBackgroundResource(R.drawable.header_shadow_reverse);
frameLayout.addView(shadow, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 3, Gravity.BOTTOM | Gravity.LEFT, 0, 0, 0, 96));
FrameLayout seekBarContainer = new FrameLayout(context);
seekBarContainer.setBackgroundColor(0xe5ffffff);
frameLayout.addView(seekBarContainer, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 30, Gravity.BOTTOM | Gravity.LEFT, 0, 0, 0, 66));
timeTextView = new TextView(context);
timeTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12);
timeTextView.setTextColor(0xff19a7e8);
timeTextView.setGravity(Gravity.CENTER);
timeTextView.setText("0:00");
seekBarContainer.addView(timeTextView, LayoutHelper.createFrame(44, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT));
durationTextView = new TextView(context);
durationTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12);
durationTextView.setTextColor(0xff8a8a8a);
durationTextView.setGravity(Gravity.CENTER);
durationTextView.setText("3:00");
seekBarContainer.addView(durationTextView, LayoutHelper.createFrame(44, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.RIGHT));
seekBarView = new SeekBarView(context);
seekBarContainer.addView(seekBarView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT, 32, 0, 32, 0));
progressView = new LineProgressView(context);
progressView.setVisibility(View.INVISIBLE);
progressView.setBackgroundColor(0x19000000);
progressView.setProgressColor(0xff23afef);
seekBarContainer.addView(progressView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 2, Gravity.CENTER_VERTICAL | Gravity.LEFT, 44, 0, 44, 0));
FrameLayout bottomView = new FrameLayout(context) {
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
int dist = ((right - left) - AndroidUtilities.dp(30 + 48 * 5)) / 4;
for (int a = 0; a < 5; a++) {
int l = AndroidUtilities.dp(15 + 48 * a) + dist * a;
int t = AndroidUtilities.dp(9);
buttons[a].layout(l, t, l + buttons[a].getMeasuredWidth(), t + buttons[a].getMeasuredHeight());
}
}
};
bottomView.setBackgroundColor(0xffffffff);
frameLayout.addView(bottomView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 66, Gravity.BOTTOM | Gravity.LEFT));
buttons[0] = repeatButton = new ImageView(context);
repeatButton.setScaleType(ImageView.ScaleType.CENTER);
bottomView.addView(repeatButton, LayoutHelper.createFrame(48, 48, Gravity.LEFT | Gravity.TOP));
repeatButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MediaController.getInstance().toggleRepeatMode();
updateRepeatButton();
}
});
buttons[1] = prevButton = new ImageView(context);
prevButton.setScaleType(ImageView.ScaleType.CENTER);
prevButton.setImageResource(R.drawable.player_prev_states);
bottomView.addView(prevButton, LayoutHelper.createFrame(48, 48, Gravity.LEFT | Gravity.TOP));
prevButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MediaController.getInstance().playPreviousMessage();
}
});
buttons[2] = playButton = new ImageView(context);
playButton.setScaleType(ImageView.ScaleType.CENTER);
playButton.setImageResource(R.drawable.player_play_states);
bottomView.addView(playButton, LayoutHelper.createFrame(48, 48, Gravity.LEFT | Gravity.TOP));
playButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (MediaController.getInstance().isDownloadingCurrentMessage()) {
return;
}
if (MediaController.getInstance().isAudioPaused()) {
MediaController.getInstance().playAudio(MediaController.getInstance().getPlayingMessageObject());
} else {
MediaController.getInstance().pauseAudio(MediaController.getInstance().getPlayingMessageObject());
}
}
});
buttons[3] = nextButton = new ImageView(context);
nextButton.setScaleType(ImageView.ScaleType.CENTER);
nextButton.setImageResource(R.drawable.player_next_states);
bottomView.addView(nextButton, LayoutHelper.createFrame(48, 48, Gravity.LEFT | Gravity.TOP));
nextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MediaController.getInstance().playNextMessage();
}
});
buttons[4] = shuffleButton = new ImageView(context);
shuffleButton.setScaleType(ImageView.ScaleType.CENTER);
bottomView.addView(shuffleButton, LayoutHelper.createFrame(48, 48, Gravity.LEFT | Gravity.TOP));
shuffleButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MediaController.getInstance().toggleShuffleMusic();
updateShuffleButton();
}
});
updateTitle(false);
updateRepeatButton();
updateShuffleButton();
return frameLayout;
}
@Override
public void didReceivedNotification(int id, Object... args) {
if (id == NotificationCenter.audioDidStarted || id == NotificationCenter.audioPlayStateChanged || id == NotificationCenter.audioDidReset) {
updateTitle(id == NotificationCenter.audioDidReset && (Boolean) args[1]);
} else if (id == NotificationCenter.audioProgressDidChanged) {
MessageObject messageObject = MediaController.getInstance().getPlayingMessageObject();
if (messageObject != null && messageObject.isMusic()) {
updateProgress(messageObject);
}
}
}
@Override
public void onFailedDownload(String fileName) {
}
@Override
public void onSuccessDownload(String fileName) {
}
@Override
public void onProgressDownload(String fileName, float progress) {
progressView.setProgress(progress, true);
}
@Override
public void onProgressUpload(String fileName, float progress, boolean isEncrypted) {
}
@Override
public int getObserverTag() {
return TAG;
}
private void onSeekBarDrag(float progress) {
MediaController.getInstance().seekToProgress(MediaController.getInstance().getPlayingMessageObject(), progress);
}
private void updateShuffleButton() {
if (MediaController.getInstance().isShuffleMusic()) {
shuffleButton.setImageResource(R.drawable.pl_shuffle_active);
} else {
shuffleButton.setImageResource(R.drawable.pl_shuffle);
}
}
private void updateRepeatButton() {
int mode = MediaController.getInstance().getRepeatMode();
if (mode == 0) {
repeatButton.setImageResource(R.drawable.pl_repeat);
} else if (mode == 1) {
repeatButton.setImageResource(R.drawable.pl_repeat_active);
} else if (mode == 2) {
repeatButton.setImageResource(R.drawable.pl_repeat1_active);
}
}
private void updateProgress(MessageObject messageObject) {
if (seekBarView != null) {
if (!seekBarView.isDragging()) {
seekBarView.setProgress(messageObject.audioProgress);
}
String timeString = String.format("%d:%02d", messageObject.audioProgressSec / 60, messageObject.audioProgressSec % 60);
if (lastTimeString == null || lastTimeString != null && !lastTimeString.equals(timeString)) {
lastTimeString = timeString;
timeTextView.setText(timeString);
}
}
}
private void checkIfMusicDownloaded(MessageObject messageObject) {
File cacheFile = null;
if (messageObject.messageOwner.attachPath != null && messageObject.messageOwner.attachPath.length() > 0) {
cacheFile = new File(messageObject.messageOwner.attachPath);
if(!cacheFile.exists()) {
cacheFile = null;
}
}
if (cacheFile == null) {
cacheFile = FileLoader.getPathToMessage(messageObject.messageOwner);
}
if (!cacheFile.exists()) {
String fileName = messageObject.getFileName();
MediaController.getInstance().addLoadingFileObserver(fileName, this);
Float progress = ImageLoader.getInstance().getFileProgress(fileName);
progressView.setProgress(progress != null ? progress : 0, false);
progressView.setVisibility(View.VISIBLE);
seekBarView.setVisibility(View.INVISIBLE);
playButton.setEnabled(false);
} else {
MediaController.getInstance().removeLoadingFileObserver(this);
progressView.setVisibility(View.INVISIBLE);
seekBarView.setVisibility(View.VISIBLE);
playButton.setEnabled(true);
}
}
private void updateTitle(boolean shutdown) {
MessageObject messageObject = MediaController.getInstance().getPlayingMessageObject();
if (messageObject == null && shutdown || messageObject != null && !messageObject.isMusic()) {
if (parentLayout != null && !parentLayout.fragmentsStack.isEmpty() && parentLayout.fragmentsStack.get(parentLayout.fragmentsStack.size() - 1) == this) {
finishFragment();
} else {
removeSelfFromStack();
}
} else {
if (messageObject == null) {
return;
}
checkIfMusicDownloaded(messageObject);
updateProgress(messageObject);
if (MediaController.getInstance().isAudioPaused()) {
playButton.setImageResource(R.drawable.player_play_states);
} else {
playButton.setImageResource(R.drawable.player_pause_states);
}
if (actionBar != null) {
actionBar.setTitle(messageObject.getMusicTitle());
actionBar.getTitleTextView().setTextColor(0xff212121);
actionBar.setSubtitle(messageObject.getMusicAuthor());
actionBar.getSubtitleTextView().setTextColor(0xff8a8a8a);
}
AudioInfo audioInfo = MediaController.getInstance().getAudioInfo();
if (audioInfo != null && audioInfo.getCover() != null) {
placeholder.setImageBitmap(audioInfo.getCover());
placeholder.setPadding(0, 0, 0, 0);
placeholder.setScaleType(ImageView.ScaleType.CENTER_CROP);
} else {
placeholder.setImageResource(R.drawable.nocover);
placeholder.setPadding(0, 0, 0, AndroidUtilities.dp(30));
placeholder.setScaleType(ImageView.ScaleType.CENTER);
}
if (durationTextView != null) {
int duration = 0;
TLRPC.Document document = messageObject.getDocument();
if (document != null) {
for (int a = 0; a < document.attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = document.attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeAudio) {
duration = attribute.duration;
break;
}
}
}
durationTextView.setText(duration != 0 ? String.format("%d:%02d", duration / 60, duration % 60) : "-:--");
}
}
}
}
@@ -89,7 +89,7 @@ public class AudioSelectActivity extends BaseFragment implements NotificationCen
super.onFragmentDestroy();
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.closeChats);
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.audioDidReset);
if (playingAudio != null && MediaController.getInstance().isPlayingAudio(playingAudio)) {
if (playingAudio != null && MediaController.getInstance().isMessageOnAir(playingAudio)) {
MediaController.getInstance().cleanupPlayer(true, true);
}
}
@@ -207,8 +207,7 @@ public class AudioSelectActivity extends BaseFragment implements NotificationCen
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.DURATION,
MediaStore.Audio.Media.ALBUM
MediaStore.Audio.Media.DURATION
};
final ArrayList<MediaController.AudioEntry> newAudioEntries = new ArrayList<>();
@@ -223,7 +222,6 @@ public class AudioSelectActivity extends BaseFragment implements NotificationCen
audioEntry.title = cursor.getString(2);
audioEntry.path = cursor.getString(3);
audioEntry.duration = (int) (cursor.getLong(4) / 1000);
audioEntry.genre = cursor.getString(5);
File file = new File(audioEntry.path);
@@ -254,14 +252,13 @@ public class AudioSelectActivity extends BaseFragment implements NotificationCen
attributeAudio.duration = audioEntry.duration;
attributeAudio.title = audioEntry.title;
attributeAudio.performer = audioEntry.author;
attributeAudio.flags |= 3;
message.media.document.attributes.add(attributeAudio);
TLRPC.TL_documentAttributeFilename fileName = new TLRPC.TL_documentAttributeFilename();
fileName.file_name = file.getName();
message.media.document.attributes.add(fileName);
audioEntry.messageObject = new MessageObject(message, null, false);
audioEntry.messageObject = new MessageObject(message, false);
newAudioEntries.add(audioEntry);
id--;
@@ -335,7 +332,7 @@ public class AudioSelectActivity extends BaseFragment implements NotificationCen
});
}
MediaController.AudioEntry audioEntry = audioEntries.get(i);
((AudioCell) view).setAudio(audioEntries.get(i), i != audioEntries.size() - 1, selectedAudios.containsKey(audioEntry.id));
((AudioCell) view).setAudio(audioEntries.get(i), selectedAudios.containsKey(audioEntry.id));
return view;
}
@@ -36,6 +36,7 @@ import android.widget.FrameLayout;
import android.widget.ListView;
import android.widget.TextView;
import com.b44t.messenger.ApplicationLoader;
import com.b44t.messenger.LocaleController;
import com.b44t.messenger.MrContact;
import com.b44t.messenger.MrMailbox;
@@ -81,7 +82,7 @@ public class BlockedUsersActivity extends BaseFragment implements NotificationCe
public View createView(Context context) {
actionBar.setBackButtonImage(R.drawable.ic_ab_back);
actionBar.setAllowOverlayTitle(true);
actionBar.setTitle(LocaleController.getString("BlockedUsers", R.string.BlockedUsers));
actionBar.setTitle(ApplicationLoader.applicationContext.getString(R.string.BlockedContacts));
actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() {
@Override
public void onItemClick(int id) {
@@ -23,13 +23,9 @@
package com.b44t.ui;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.view.View;
import android.view.ViewGroup;
@@ -40,109 +36,34 @@ import android.widget.Toast;
import com.b44t.messenger.AndroidUtilities;
import com.b44t.messenger.ApplicationLoader;
import com.b44t.messenger.ClearCacheService;
import com.b44t.messenger.FileLoader;
import com.b44t.messenger.FileLog;
import com.b44t.messenger.ImageLoader;
import com.b44t.messenger.LocaleController;
import com.b44t.messenger.R;
import com.b44t.messenger.Utilities;
import com.b44t.ui.ActionBar.ActionBar;
import com.b44t.ui.ActionBar.BaseFragment;
import com.b44t.ui.Adapters.BaseFragmentAdapter;
import com.b44t.ui.Cells.HeaderCell;
import com.b44t.ui.Cells.TextInfoPrivacyCell;
import com.b44t.ui.Cells.TextInfoCell;
import com.b44t.ui.Cells.TextSettingsCell;
import com.b44t.ui.Components.LayoutHelper;
import java.io.File;
public class CacheControlActivity extends BaseFragment {
private ListAdapter listAdapter;
private int headlineRow; // EDIT BY MR -- added
private int databaseRow;
private int databaseInfoRow;
private int keepMediaRow;
private int keepMediaInfoRow;
private int cacheRow;
private int cacheInfoRow;
private int rowKeepMediaSetting;
private int rowKeepMediaInfo;
private int rowCount;
private int typeTextSetting = 0; // EDIT BY MR -- no gaps, please
private int typeTextInfo = 1;
private int typeSectionTitle = 2;
private int typeCount = 3; // /EDIT BY MR -- no gaps, please
//private long databaseSize = -1;
//private long cacheSize = -1;
//private long documentsSize = -1;
//private long audioSize = -1;
//private long musicSize = -1;
//private long photoSize = -1;
//private long videoSize = -1;
//private long totalSize = -1;
//private boolean clear[] = new boolean[6];
//private boolean calculating = true;
private volatile boolean canceled = false;
private final int ROWTYPE_TEXT_SETTING = 0; // no gaps here
private final int ROWTYPE_TEXT_INFO = 1;
private final int ROWTYPE_COUNT = 2;
@Override
public boolean onFragmentCreate() {
super.onFragmentCreate();
rowCount = 0;
headlineRow = -1;// rowCount++; // EDIT BY MR -- added
keepMediaRow = rowCount++;
keepMediaInfoRow = rowCount++;
cacheRow = -1; // EDIT BY MR -- rowCount++;
cacheInfoRow = -1; // EDIT BY MR -- rowCount++;
databaseRow = -1; // EDIT BY MR -- was: rowCount++;
databaseInfoRow = -1; // EDIT BY MR -- was: rowCount++;
File file = new File(ApplicationLoader.getFilesDirFixed(), "cache4.db");
//databaseSize = file.length();
/*
Utilities.globalQueue.postRunnable(new Runnable() {
@Override
public void run() {
cacheSize = getDirectorySize(FileLoader.getInstance().checkDirectory(FileLoader.MEDIA_DIR_CACHE), 0);
if (canceled) {
return;
}
photoSize = getDirectorySize(FileLoader.getInstance().checkDirectory(FileLoader.MEDIA_DIR_IMAGE), 0);
if (canceled) {
return;
}
videoSize = getDirectorySize(FileLoader.getInstance().checkDirectory(FileLoader.MEDIA_DIR_VIDEO), 0);
if (canceled) {
return;
}
documentsSize = getDirectorySize(FileLoader.getInstance().checkDirectory(FileLoader.MEDIA_DIR_DOCUMENT), 1);
if (canceled) {
return;
}
musicSize = getDirectorySize(FileLoader.getInstance().checkDirectory(FileLoader.MEDIA_DIR_DOCUMENT), 2);
if (canceled) {
return;
}
audioSize = getDirectorySize(FileLoader.getInstance().checkDirectory(FileLoader.MEDIA_DIR_AUDIO), 0);
totalSize = cacheSize + videoSize + audioSize + photoSize + documentsSize + musicSize;
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
calculating = false;
if (listAdapter != null) {
listAdapter.notifyDataSetChanged();
}
}
});
}
});
*/
rowKeepMediaSetting = rowCount++;
rowKeepMediaInfo = rowCount++;
return true;
}
@@ -150,175 +71,8 @@ public class CacheControlActivity extends BaseFragment {
@Override
public void onFragmentDestroy() {
super.onFragmentDestroy();
canceled = true;
}
/*private long getDirectorySize2(File dir) {
long size = 0;
if (dir.isDirectory()) {
File[] array = dir.listFiles();
if (array != null) {
for (int a = 0; a < array.length; a++) {
File file = array[a];
if (file.isDirectory()) {
size += getDirectorySize2(file);
} else {
size += file.length();
FileLog.e("messenger", "" + file + " size = " + file.length());
}
}
}
} else if (dir.isFile()) {
FileLog.e("messenger", "" + dir + " size = " + dir.length());
size += dir.length();
}
return size;
}*/
private long getDirectorySize(File dir, int documentsMusicType) {
if (dir == null || canceled) {
return 0;
}
long size = 0;
if (dir.isDirectory()) {
try {
File[] array = dir.listFiles();
if (array != null) {
for (int a = 0; a < array.length; a++) {
if (canceled) {
return 0;
}
File file = array[a];
if (documentsMusicType == 1 || documentsMusicType == 2) {
String name = file.getName().toLowerCase();
if (name.endsWith(".mp3") || name.endsWith(".m4a")) {
if (documentsMusicType == 1) {
continue;
}
} else if (documentsMusicType == 2) {
continue;
}
}
if (file.isDirectory()) {
size += getDirectorySize(file, documentsMusicType);
} else {
size += file.length();
}
}
}
} catch (Throwable e) {
FileLog.e("messenger", e);
}
} else if (dir.isFile()) {
size += dir.length();
}
return size;
}
/*
private void cleanupFolders() {
final ProgressDialog progressDialog = new ProgressDialog(getParentActivity());
progressDialog.setMessage(LocaleController.getString("Loading", R.string.Loading));
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.setCancelable(false);
progressDialog.show();
Utilities.globalQueue.postRunnable(new Runnable() {
@Override
public void run() {
boolean imagesCleared = false;
for (int a = 0; a < 6; a++) {
if (!clear[a]) {
continue;
}
int type = -1;
int documentsMusicType = 0;
if (a == 0) {
type = FileLoader.MEDIA_DIR_IMAGE;
} else if (a == 1) {
type = FileLoader.MEDIA_DIR_VIDEO;
} else if (a == 2) {
type = FileLoader.MEDIA_DIR_DOCUMENT;
documentsMusicType = 1;
} else if (a == 3) {
type = FileLoader.MEDIA_DIR_DOCUMENT;
documentsMusicType = 2;
} else if (a == 4) {
type = FileLoader.MEDIA_DIR_AUDIO;
} else if (a == 5) {
type = FileLoader.MEDIA_DIR_CACHE;
}
if (type == -1) {
continue;
}
File file = FileLoader.getInstance().checkDirectory(type);
if (file != null) {
try {
File[] array = file.listFiles();
if (array != null) {
for (int b = 0; b < array.length; b++) {
String name = array[b].getName().toLowerCase();
if (documentsMusicType == 1 || documentsMusicType == 2) {
if (name.endsWith(".mp3") || name.endsWith(".m4a")) {
if (documentsMusicType == 1) {
continue;
}
} else if (documentsMusicType == 2) {
continue;
}
}
if (name.equals(".nomedia")) {
continue;
}
if (array[b].isFile()) {
array[b].delete();
}
}
}
} catch (Throwable e) {
FileLog.e("messenger", e);
}
}
if (type == FileLoader.MEDIA_DIR_CACHE) {
cacheSize = getDirectorySize(FileLoader.getInstance().checkDirectory(FileLoader.MEDIA_DIR_CACHE), documentsMusicType);
imagesCleared = true;
} else if (type == FileLoader.MEDIA_DIR_AUDIO) {
audioSize = getDirectorySize(FileLoader.getInstance().checkDirectory(FileLoader.MEDIA_DIR_AUDIO), documentsMusicType);
} else if (type == FileLoader.MEDIA_DIR_DOCUMENT) {
if (documentsMusicType == 1) {
documentsSize = getDirectorySize(FileLoader.getInstance().checkDirectory(FileLoader.MEDIA_DIR_DOCUMENT), documentsMusicType);
} else {
musicSize = getDirectorySize(FileLoader.getInstance().checkDirectory(FileLoader.MEDIA_DIR_DOCUMENT), documentsMusicType);
}
} else if (type == FileLoader.MEDIA_DIR_IMAGE) {
imagesCleared = true;
photoSize = getDirectorySize(FileLoader.getInstance().checkDirectory(FileLoader.MEDIA_DIR_IMAGE), documentsMusicType);
} else if (type == FileLoader.MEDIA_DIR_VIDEO) {
videoSize = getDirectorySize(FileLoader.getInstance().checkDirectory(FileLoader.MEDIA_DIR_VIDEO), documentsMusicType);
}
}
final boolean imagesClearedFinal = imagesCleared;
totalSize = cacheSize + videoSize + audioSize + photoSize + documentsSize + musicSize;
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
if (imagesClearedFinal) {
ImageLoader.getInstance().clearMemory();
}
if (listAdapter != null) {
listAdapter.notifyDataSetChanged();
}
try {
progressDialog.dismiss();
} catch (Exception e) {
FileLog.e("messenger", e);
}
}
});
}
});
}
*/
@Override
public View createView(final Context context) {
actionBar.setBackButtonImage(R.drawable.ic_ab_back);
@@ -349,216 +103,25 @@ public class CacheControlActivity extends BaseFragment {
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(final AdapterView<?> adapterView, View view, final int i, long l) {
if (i == keepMediaRow) {
if (i == rowKeepMediaSetting) {
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
builder.setItems(new CharSequence[]{context.getResources().getQuantityString(R.plurals.Weeks, 1, 1), context.getResources().getQuantityString(R.plurals.Months, 1, 1), LocaleController.getString("KeepMediaForever", R.string.KeepMediaForever)}, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, final int which) {
SharedPreferences.Editor editor = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE).edit();
editor.putInt("keep_media", which).commit();
editor.putInt("keep_media", which).apply();
if (listAdapter != null) {
listAdapter.notifyDataSetChanged();
}
PendingIntent pintent = PendingIntent.getService(ApplicationLoader.applicationContext, 0, new Intent(ApplicationLoader.applicationContext, ClearCacheService.class), 0);
AlarmManager alarmManager = (AlarmManager) ApplicationLoader.applicationContext.getSystemService(Context.ALARM_SERVICE);
if (which == 2) {
alarmManager.cancel(pintent);
} else {
alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, AlarmManager.INTERVAL_DAY, AlarmManager.INTERVAL_DAY, pintent);
}
Toast.makeText(context, LocaleController.getString("NotYetImplemented", R.string.NotYetImplemented), Toast.LENGTH_SHORT).show();
}
});
showDialog(builder.create());
} else if (i == databaseRow) {
/* EDIT BY MR
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
builder.setMessage(LocaleController.getString("LocalDatabaseClear", R.string.LocalDatabaseClear));
builder.setPositiveButton(LocaleController.getString("CacheClear", R.string.CacheClear), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
final ProgressDialog progressDialog = new ProgressDialog(getParentActivity());
progressDialog.setMessage(LocaleController.getString("Loading", R.string.Loading));
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.setCancelable(false);
progressDialog.show();
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@Override
public void run() {
try {
SQLiteDatabase database = MessagesStorage.getInstance().getDatabase();
ArrayList<Long> dialogsToCleanup = new ArrayList<>();
SQLiteCursor cursor = database.queryFinalized("SELECT did FROM dialogs WHERE 1");
StringBuilder ids = new StringBuilder();
while (cursor.next()) {
long did = cursor.longValue(0);
int lower_id = (int) did;
int high_id = (int) (did >> 32);
if (lower_id != 0 && high_id != 1) {
dialogsToCleanup.add(did);
}
}
cursor.dispose();
SQLitePreparedStatement state5 = database.executeFast("REPLACE INTO messages_holes VALUES(?, ?, ?)");
SQLitePreparedStatement state6 = database.executeFast("REPLACE INTO media_holes_v2 VALUES(?, ?, ?, ?)");
database.beginTransaction();
for (int a = 0; a < dialogsToCleanup.size(); a++) {
Long did = dialogsToCleanup.get(a);
int messagesCount = 0;
cursor = database.queryFinalized("SELECT COUNT(mid) FROM messages WHERE uid = " + did);
if (cursor.next()) {
messagesCount = cursor.intValue(0);
}
cursor.dispose();
if (messagesCount <= 2) {
continue;
}
cursor = database.queryFinalized("SELECT last_mid_i, last_mid FROM dialogs WHERE did = " + did);
int messageId = -1;
if (cursor.next()) {
long last_mid_i = cursor.longValue(0);
long last_mid = cursor.longValue(1);
SQLiteCursor cursor2 = database.queryFinalized("SELECT data FROM messages WHERE uid = " + did + " AND mid IN (" + last_mid_i + "," + last_mid + ")");
try {
while (cursor2.next()) {
NativeByteBuffer data = cursor2.byteBufferValue(0);
if (data != null) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
if (message != null) {
messageId = message.id;
}
}
}
} catch (Exception e) {
FileLog.e("messenger", e);
}
cursor2.dispose();
database.executeFast("DELETE FROM messages WHERE uid = " + did + " AND mid != " + last_mid_i + " AND mid != " + last_mid).stepThis().dispose();
database.executeFast("DELETE FROM messages_holes WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM bot_keyboard WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM media_counts_v2 WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM media_v2 WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM media_holes_v2 WHERE uid = " + did).stepThis().dispose();
BotQuery.clearBotKeyboard(did, null);
if (messageId != -1) {
MessagesStorage.createFirstHoles(did, state5, state6, messageId);
}
}
cursor.dispose();
}
state5.dispose();
state6.dispose();
database.commitTransaction();
database.executeFast("VACUUM").stepThis().dispose();
} catch (Exception e) {
FileLog.e("messenger", e);
} finally {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
try {
progressDialog.dismiss();
} catch (Exception e) {
FileLog.e("messenger", e);
}
if (listAdapter != null) {
File file = new File(ApplicationLoader.getFilesDirFixed(), "cache4.db");
databaseSize = file.length();
listAdapter.notifyDataSetChanged();
}
}
});
}
}
});
}
});
showDialog(builder.create());
*/
} else if (i == cacheRow) {
/* EDIT BY MR
if (totalSize <= 0 || getParentActivity() == null) {
return;
}
BottomSheet.Builder builder = new BottomSheet.Builder(getParentActivity());
builder.setApplyTopPadding(false);
builder.setApplyBottomPadding(false);
LinearLayout linearLayout = new LinearLayout(getParentActivity());
linearLayout.setOrientation(LinearLayout.VERTICAL);
for (int a = 0; a < 6; a++) {
long size = 0;
String name = null;
if (a == 0) {
size = photoSize;
name = LocaleController.getString("LocalPhotoCache", R.string.LocalPhotoCache);
} else if (a == 1) {
size = videoSize;
name = LocaleController.getString("LocalVideoCache", R.string.LocalVideoCache);
} else if (a == 2) {
size = documentsSize;
name = LocaleController.getString("LocalDocumentCache", R.string.LocalDocumentCache);
} else if (a == 3) {
size = musicSize;
name = LocaleController.getString("LocalMusicCache", R.string.LocalMusicCache);
} else if (a == 4) {
size = audioSize;
name = LocaleController.getString("LocalAudioCache", R.string.LocalAudioCache);
} else if (a == 5) {
size = cacheSize;
name = LocaleController.getString("LocalCache", R.string.LocalCache);
}
if (size > 0) {
clear[a] = true;
CheckBoxCell checkBoxCell = new CheckBoxCell(getParentActivity());
checkBoxCell.setTag(a);
checkBoxCell.setBackgroundResource(R.drawable.list_selector);
linearLayout.addView(checkBoxCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48));
checkBoxCell.setText(name, AndroidUtilities.formatFileSize(size), true, true);
checkBoxCell.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CheckBoxCell cell = (CheckBoxCell) v;
int num = (Integer) cell.getTag();
clear[num] = !clear[num];
cell.setChecked(clear[num], true);
}
});
} else {
clear[a] = false;
}
}
BottomSheet.BottomSheetCell cell = new BottomSheet.BottomSheetCell(getParentActivity(), 1);
cell.setBackgroundResource(R.drawable.list_selector);
cell.setTextAndIcon(LocaleController.getString("ClearMediaCache", R.string.ClearMediaCache).toUpperCase(), 0);
cell.setTextColor(0xffcd5a5a);
cell.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
if (visibleDialog != null) {
visibleDialog.dismiss();
}
} catch (Exception e) {
FileLog.e("messenger", e);
}
cleanupFolders();
}
});
linearLayout.addView(cell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48));
builder.setCustomView(linearLayout);
showDialog(builder.create());
*/
}
}
});
Toast.makeText(context, LocaleController.getString("NotYetImplemented", R.string.NotYetImplemented), Toast.LENGTH_SHORT).show();
return fragmentView;
}
@@ -584,7 +147,7 @@ public class CacheControlActivity extends BaseFragment {
@Override
public boolean isEnabled(int i) {
return i == databaseRow || /*i == cacheRow && totalSize > 0 ||*/ i == keepMediaRow;
return i == rowKeepMediaSetting;
}
@Override
@@ -609,32 +172,14 @@ public class CacheControlActivity extends BaseFragment {
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
int type_ = getItemViewType(i);
if (type_ == typeSectionTitle) {
if (view == null) {
view = new HeaderCell(mContext);
view.setBackgroundColor(0xffffffff);
}
if (i == headlineRow) {
((HeaderCell) view).setText(LocaleController.getString("Settings", R.string.Settings));
}
}
else if (type_ == typeTextSetting) {
int type = getItemViewType(i);
if (type == ROWTYPE_TEXT_SETTING) {
if (view == null) {
view = new TextSettingsCell(mContext);
view.setBackgroundColor(0xffffffff);
}
TextSettingsCell textCell = (TextSettingsCell) view;
if (i == databaseRow) {
//textCell.setTextAndValue(LocaleController.getString("LocalDatabase", R.string.LocalDatabase), AndroidUtilities.formatFileSize(databaseSize), false);
} else if (i == cacheRow) {
/*if (calculating) {
textCell.setTextAndValue(LocaleController.getString("ClearMediaCache", R.string.ClearMediaCache), LocaleController.getString("CalculatingSize", R.string.CalculatingSize), false);
} else {
textCell.setTextAndValue(LocaleController.getString("ClearMediaCache", R.string.ClearMediaCache), totalSize == 0 ? LocaleController.getString("CacheEmpty", R.string.CacheEmpty) : AndroidUtilities.formatFileSize(totalSize), false);
}
*/
} else if (i == keepMediaRow) {
if (i == rowKeepMediaSetting) {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
int keepMedia = preferences.getInt("keep_media", 2);
String value;
@@ -647,18 +192,12 @@ public class CacheControlActivity extends BaseFragment {
}
textCell.setTextAndValue(mContext.getString(R.string.KeepMedia), value, false);
}
} else if (type_ == typeTextInfo) {
} else if (type == ROWTYPE_TEXT_INFO) {
if (view == null) {
view = new TextInfoPrivacyCell(mContext);
view = new TextInfoCell(mContext);
}
if (i == databaseInfoRow) {
((TextInfoPrivacyCell) view).setText(LocaleController.getString("LocalDatabaseInfo", R.string.LocalDatabaseInfo));
view.setBackgroundResource(R.drawable.greydivider_bottom);
} else if (i == cacheInfoRow) {
((TextInfoPrivacyCell) view).setText("");
view.setBackgroundResource(R.drawable.greydivider);
} else if (i == keepMediaInfoRow) {
((TextInfoPrivacyCell) view).setText(AndroidUtilities.replaceTags(LocaleController.getString("KeepMediaInfo", R.string.KeepMediaInfo)));
if (i == rowKeepMediaInfo) {
((TextInfoCell) view).setText(AndroidUtilities.replaceTags(LocaleController.getString("KeepMediaInfo", R.string.KeepMediaInfo)));
view.setBackgroundResource(R.drawable.greydivider_bottom);
}
}
@@ -667,20 +206,15 @@ public class CacheControlActivity extends BaseFragment {
@Override
public int getItemViewType(int i) {
if (i == databaseRow || i == cacheRow || i == keepMediaRow) {
return typeTextSetting;
} else if (i == databaseInfoRow || i == cacheInfoRow || i == keepMediaInfoRow) {
return typeTextInfo;
if (i == rowKeepMediaInfo) {
return ROWTYPE_TEXT_INFO;
}
else if(i==headlineRow) {
return typeSectionTitle;
}
return typeTextSetting;
return ROWTYPE_TEXT_SETTING;
}
@Override
public int getViewTypeCount() {
return typeCount;
return ROWTYPE_COUNT;
}
@Override
@@ -49,12 +49,10 @@ public class AudioCell extends FrameLayout {
private ImageView playButton;
private TextView titleTextView;
private TextView authorTextView;
private TextView genreTextView;
private TextView timeTextView;
private CheckBox checkBox;
private MediaController.AudioEntry audioEntry;
private boolean needDivider;
private static Paint paint;
private AudioCellDelegate delegate;
@@ -79,14 +77,12 @@ public class AudioCell extends FrameLayout {
@Override
public void onClick(View v) {
if (audioEntry != null) {
if (MediaController.getInstance().isPlayingAudio(audioEntry.messageObject) && !MediaController.getInstance().isAudioPaused()) {
MediaController.getInstance().pauseAudio(audioEntry.messageObject);
playButton.setImageResource(R.drawable.audiosend_play);
if (MediaController.getInstance().isMessageOnAir(audioEntry.messageObject) && !MediaController.getInstance().isAudioPaused()) {
MediaController.getInstance().stopAudio();
playButton.setImageResource(R.drawable.attach_audio_inlist_play);
} else {
ArrayList<MessageObject> arrayList = new ArrayList<>();
arrayList.add(audioEntry.messageObject);
if (MediaController.getInstance().setPlaylist(arrayList, audioEntry.messageObject)) {
playButton.setImageResource(R.drawable.audiosend_pause);
if (MediaController.getInstance().playAudio(audioEntry.messageObject)) {
playButton.setImageResource(R.drawable.attach_audio_inlist_pause);
if (delegate != null) {
delegate.startedPlayingAudio(audioEntry.messageObject);
}
@@ -99,7 +95,6 @@ public class AudioCell extends FrameLayout {
titleTextView = new TextView(context);
titleTextView.setTextColor(0xff212121);
titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
titleTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
titleTextView.setLines(1);
titleTextView.setMaxLines(1);
titleTextView.setSingleLine(true);
@@ -107,16 +102,6 @@ public class AudioCell extends FrameLayout {
titleTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP);
addView(titleTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 50 : 72, 7, LocaleController.isRTL ? 72 : 50, 0));
genreTextView = new TextView(context);
genreTextView.setTextColor(0xff8a8a8a);
genreTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
genreTextView.setLines(1);
genreTextView.setMaxLines(1);
genreTextView.setSingleLine(true);
genreTextView.setEllipsize(TextUtils.TruncateAt.END);
genreTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP);
addView(genreTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 50 : 72, 28, LocaleController.isRTL ? 72 : 50, 0));
authorTextView = new TextView(context);
authorTextView.setTextColor(0xff8a8a8a);
authorTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
@@ -125,40 +110,43 @@ public class AudioCell extends FrameLayout {
authorTextView.setSingleLine(true);
authorTextView.setEllipsize(TextUtils.TruncateAt.END);
authorTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP);
addView(authorTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 50 : 72, 44, LocaleController.isRTL ? 72 : 50, 0));
addView(authorTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 50 : 72, 28, LocaleController.isRTL ? 72 : 50, 0));
timeTextView = new TextView(context);
timeTextView.setTextColor(0xff999999);
timeTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13);
timeTextView.setTextColor(0xff8a8a8a);
timeTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
timeTextView.setLines(1);
timeTextView.setMaxLines(1);
timeTextView.setSingleLine(true);
timeTextView.setEllipsize(TextUtils.TruncateAt.END);
timeTextView.setGravity((LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.TOP);
addView(timeTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.TOP, LocaleController.isRTL ? 18 : 0, 11, LocaleController.isRTL ? 0 : 18, 0));
timeTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP);
addView(timeTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 50 : 72, 44, LocaleController.isRTL ? 72 : 50, 0));
checkBox = new CheckBox(context, R.drawable.round_check2);
checkBox.setVisibility(VISIBLE);
checkBox.setColor(0xff29b6f7);
addView(checkBox, LayoutHelper.createFrame(22, 22, (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.TOP, LocaleController.isRTL ? 18 : 0, 39, LocaleController.isRTL ? 0 : 18, 0));
addView(checkBox, LayoutHelper.createFrame(
22, // width
22, // height
(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, // gravity
LocaleController.isRTL ? 0 : 44, // marginLeft
39, // marginTop
LocaleController.isRTL ? 44 : 0, // marginRight
0)); // marginBottom
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(72) + (needDivider ? 1 : 0), MeasureSpec.EXACTLY));
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(72), MeasureSpec.EXACTLY));
}
public void setAudio(MediaController.AudioEntry entry, boolean divider, boolean checked) {
public void setAudio(MediaController.AudioEntry entry, boolean checked) {
audioEntry = entry;
titleTextView.setText(audioEntry.title);
genreTextView.setText(audioEntry.genre);
authorTextView.setText(audioEntry.author);
timeTextView.setText(String.format("%d:%02d", audioEntry.duration / 60, audioEntry.duration % 60));
playButton.setImageResource(MediaController.getInstance().isPlayingAudio(audioEntry.messageObject) && !MediaController.getInstance().isAudioPaused() ? R.drawable.audiosend_pause : R.drawable.audiosend_play);
needDivider = divider;
setWillNotDraw(!divider);
playButton.setImageResource(MediaController.getInstance().isMessageOnAir(audioEntry.messageObject) && !MediaController.getInstance().isAudioPaused() ? R.drawable.attach_audio_inlist_pause : R.drawable.attach_audio_inlist_play);
checkBox.setChecked(checked, false);
}
@@ -174,11 +162,4 @@ public class AudioCell extends FrameLayout {
public MediaController.AudioEntry getAudioEntry() {
return audioEntry;
}
@Override
protected void onDraw(Canvas canvas) {
if (needDivider) {
canvas.drawLine(AndroidUtilities.dp(72), getHeight() - 1, getWidth(), getHeight() - 1, paint);
}
}
}
@@ -24,45 +24,26 @@
package com.b44t.ui.Cells;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.text.Layout;
import android.text.Spannable;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.style.URLSpan;
import android.view.MotionEvent;
import android.view.SoundEffectConstants;
import com.b44t.messenger.AndroidUtilities;
import com.b44t.messenger.ApplicationLoader;
import com.b44t.messenger.ImageReceiver;
import com.b44t.messenger.MessageObject;
import com.b44t.messenger.MessagesController;
import com.b44t.messenger.FileLoader;
import com.b44t.messenger.FileLog;
import com.b44t.messenger.TLRPC;
import com.b44t.messenger.UserConfig;
import com.b44t.ui.ActionBar.Theme;
import com.b44t.ui.PhotoViewer;
import com.b44t.ui.Components.AvatarDrawable;
public class ChatActionCell extends BaseCell {
public interface ChatActionCellDelegate {
void didClickedImage(ChatActionCell cell);
void didLongPressed(ChatActionCell cell);
void needOpenUserProfile(int uid);
}
private static TextPaint textPaint;
private static Paint backPaint;
private URLSpan pressedLink;
private ImageReceiver imageReceiver;
private AvatarDrawable avatarDrawable;
private StaticLayout textLayout;
private int textWidth = 0;
private int textHeight = 0;
@@ -70,36 +51,26 @@ public class ChatActionCell extends BaseCell {
private int textY = 0;
private int textXLeft = 0;
private int previousWidth = 0;
private boolean imagePressed = false;
private boolean hasReplyMessage;
private MessageObject currentMessageObject;
private ChatActionCellDelegate delegate;
public ChatActionCell(Context context) {
super(context);
if (textPaint == null) {
textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
textPaint.setColor(0xffffffff);
textPaint.linkColor = 0xffffffff;
textPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
textPaint.setTypeface(Typeface.DEFAULT_BOLD);
backPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
}
backPaint.setColor(ApplicationLoader.getServiceMessageColor());
imageReceiver = new ImageReceiver(this);
imageReceiver.setRoundRadius(AndroidUtilities.dp(32));
avatarDrawable = new AvatarDrawable();
textPaint.setTextSize(AndroidUtilities.dp(MessagesController.getInstance().fontSize - 2));
}
public void setDelegate(ChatActionCellDelegate delegate) {
this.delegate = delegate;
}
public void setMessageObject(MessageObject messageObject) {
if (currentMessageObject == messageObject && (hasReplyMessage || messageObject.replyMessageObject == null)) {
return;
@@ -107,35 +78,6 @@ public class ChatActionCell extends BaseCell {
currentMessageObject = messageObject;
hasReplyMessage = messageObject.replyMessageObject != null;
previousWidth = 0;
if (currentMessageObject.type == 11) {
int id = 0;
if (messageObject.messageOwner.to_id != null) {
if (messageObject.messageOwner.to_id.chat_id != 0) {
id = messageObject.messageOwner.to_id.chat_id;
} else if (messageObject.messageOwner.to_id.channel_id != 0) {
id = messageObject.messageOwner.to_id.channel_id;
} else {
id = messageObject.messageOwner.to_id.user_id;
if (id == UserConfig.getClientUserId()) {
id = messageObject.messageOwner.from_id;
}
}
}
avatarDrawable.setInfoByName(null);
/*if (currentMessageObject.messageOwner.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) {
imageReceiver.setImage(currentMessageObject.messageOwner.action.newUserPhoto.photo_small, "50_50", avatarDrawable, null, false);
} else */ {
TLRPC.PhotoSize photo = FileLoader.getClosestPhotoSizeWithSize(currentMessageObject.photoThumbs, AndroidUtilities.dp(64));
if (photo != null) {
imageReceiver.setImage(photo.location, "50_50", avatarDrawable, null, false);
} else {
imageReceiver.setImageBitmap(avatarDrawable);
}
}
imageReceiver.setVisible(!PhotoViewer.getInstance().isShowingImage(currentMessageObject), false);
} else {
imageReceiver.setImageBitmap((Bitmap)null);
}
requestLayout();
}
@@ -143,95 +85,13 @@ public class ChatActionCell extends BaseCell {
return currentMessageObject;
}
public ImageReceiver getPhotoImage() {
return imageReceiver;
}
@Override
protected void onLongPress() {
if (delegate != null) {
delegate.didLongPressed(this);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
boolean result = false;
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (delegate != null) {
if (currentMessageObject.type == 11 && imageReceiver.isInsideImage(x, y)) {
imagePressed = true;
result = true;
}
if (result) {
startCheckLongPress();
}
}
} else {
if (event.getAction() != MotionEvent.ACTION_MOVE) {
cancelCheckLongPress();
}
if (imagePressed) {
if (event.getAction() == MotionEvent.ACTION_UP) {
imagePressed = false;
if (delegate != null) {
delegate.didClickedImage(this);
playSoundEffect(SoundEffectConstants.CLICK);
}
} else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
imagePressed = false;
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (!imageReceiver.isInsideImage(x, y)) {
imagePressed = false;
}
}
}
}
if (!result) {
if (event.getAction() == MotionEvent.ACTION_DOWN || pressedLink != null && event.getAction() == MotionEvent.ACTION_UP) {
if (x >= textX && y >= textY && x <= textX + textWidth && y <= textY + textHeight) {
y -= textY;
x -= textXLeft;
final int line = textLayout.getLineForVertical((int)y);
final int off = textLayout.getOffsetForHorizontal(line, x);
final float left = textLayout.getLineLeft(line);
if (left <= x && left + textLayout.getLineWidth(line) >= x && currentMessageObject.messageText instanceof Spannable) {
Spannable buffer = (Spannable) currentMessageObject.messageText;
URLSpan[] link = buffer.getSpans(off, off, URLSpan.class);
if (link.length != 0) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
pressedLink = link[0];
result = true;
} else {
if (link[0] == pressedLink) {
if (delegate != null) {
delegate.needOpenUserProfile(Integer.parseInt(link[0].getURL()));
}
result = true;
}
}
} else {
pressedLink = null;
}
} else {
pressedLink = null;
}
} else {
pressedLink = null;
}
}
}
if (!result) {
result = super.onTouchEvent(event);
}
return result;
return false;
}
@Override
@@ -270,12 +130,8 @@ public class ChatActionCell extends BaseCell {
textX = (width - textWidth) / 2;
textY = AndroidUtilities.dp(7);
textXLeft = (width - textLayout.getWidth()) / 2;
if (currentMessageObject.type == 11) {
imageReceiver.setImageCoords((width - AndroidUtilities.dp(64)) / 2, textHeight + AndroidUtilities.dp(15), AndroidUtilities.dp(64), AndroidUtilities.dp(64));
}
}
setMeasuredDimension(width, textHeight + AndroidUtilities.dp(14 + (currentMessageObject.type == 11 ? 70 : 0)));
setMeasuredDimension(width, textHeight + AndroidUtilities.dp(14 + 0));
}
private int findMaxWidthAroundLine(int line) {
@@ -306,10 +162,6 @@ public class ChatActionCell extends BaseCell {
return;
}
if (currentMessageObject.type == 11) {
imageReceiver.draw(canvas);
}
if (textLayout != null) {
final int count = textLayout.getLineCount();
final int corner = AndroidUtilities.dp(6);
File diff suppressed because it is too large Load Diff
@@ -24,6 +24,7 @@
package com.b44t.ui.Cells;
import android.content.Context;
import android.graphics.Typeface;
import android.util.TypedValue;
import android.view.Gravity;
import android.widget.FrameLayout;
@@ -50,8 +51,8 @@ public class ChatUnreadCell extends FrameLayout {
textView = new TextView(context);
textView.setPadding(0, 0, 0, AndroidUtilities.dp(1));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, MessagesController.getInstance().fontSize-2);
textView.setTextColor(Theme.MSG_IN_TIME_TEXT_COLOR);
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
textView.setTextColor(Theme.MSG_IN_TIME_N_FWD_TEXT_COLOR);
textView.setTypeface(Typeface.DEFAULT_BOLD);
addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER));
}
@@ -62,7 +62,7 @@ public class ContextLinkCell extends View implements MediaController.FileDownloa
private final static int DOCUMENT_ATTACH_TYPE_NONE = 0;
private final static int DOCUMENT_ATTACH_TYPE_DOCUMENT = 1;
private final static int DOCUMENT_ATTACH_TYPE_GIF = 2;
private final static int DOCUMENT_ATTACH_TYPE_AUDIO = 3;
private final static int DOCUMENT_ATTACH_TYPE_VOICE = 3;
private final static int DOCUMENT_ATTACH_TYPE_VIDEO = 4;
private final static int DOCUMENT_ATTACH_TYPE_MUSIC = 5;
private final static int DOCUMENT_ATTACH_TYPE_STICKER = 6;
@@ -115,7 +115,6 @@ public class ContextLinkCell extends View implements MediaController.FileDownloa
if (titleTextPaint == null) {
titleTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
titleTextPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
titleTextPaint.setColor(0xff212121);
titleTextPaint.setTextSize(AndroidUtilities.dp(15));
@@ -391,7 +390,7 @@ public class ContextLinkCell extends View implements MediaController.FileDownloa
}
private Drawable getDrawableForCurrentState() {
return buttonState == 1 ? Theme.photoStatesDrawables[5][0] : null;
return buttonState == 1 ? Theme.inlistDrawable[Theme.INLIST_FILE] : null;
}
public void updateButtonState(boolean animated) {
@@ -26,6 +26,7 @@ package com.b44t.ui.Cells;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.Layout;
@@ -79,18 +80,16 @@ public class DialogCell extends BaseCell {
private long currentDialogId;
private final boolean isDialogCell = true; // if it is no dialog cell, it is a search cell ...
private int unreadCount;
private boolean lastUnreadState;
private int lastSendState;
private boolean dialogMuted;
private MessageObject message;
private final MessageObject message = null;
private int index;
private ImageReceiver avatarImage;
private AvatarDrawable avatarDrawable;
private TLRPC.User user = null;
private TLRPC.Chat chat = null;
private CharSequence lastPrintString = null;
private final Object user = null;
private final Object chat = null;
public boolean useSeparator = false;
@@ -143,7 +142,6 @@ public class DialogCell extends BaseCell {
namePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
namePaint.setTextSize(AndroidUtilities.dp(17));
namePaint.setColor(Theme.DIALOGS_TITLE_TEXT_COLOR);
namePaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
messagePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
messagePaint.setTextSize(AndroidUtilities.dp(16));
@@ -167,7 +165,7 @@ public class DialogCell extends BaseCell {
countPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
countPaint.setTextSize(AndroidUtilities.dp(13));
countPaint.setColor(0xffffffff);
countPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
countPaint.setTypeface(Typeface.DEFAULT_BOLD);
checkDrawable = getResources().getDrawable(R.drawable.dialogs_check);
halfCheckDrawable = getResources().getDrawable(R.drawable.dialogs_halfcheck);
@@ -291,18 +289,18 @@ public class DialogCell extends BaseCell {
{
checkMessage = false;
String mess = m_summary.getText();
String mess = m_summary.getText2();
if (mess.length() > 150) {
mess = mess.substring(0, 150);
}
String title = m_summary.getTitle();
String title = m_summary.getText1();
if( !title.isEmpty() )
{
int title_meaning = m_summary.getTitleMeaning();
int title_meaning = m_summary.getText1Meaning();
int title_color = Theme.DIALOGS_NAME_TEXT_COLOR;
switch( title_meaning ) {
case MrPoortext.MR_TITLE_SELF: title_color = Theme.DIALOGS_SELF_TEXT_COLOR; break;
case MrPoortext.MR_TITLE_DRAFT: title_color = Theme.DIALOGS_DRAFT_TEXT_COLOR; break;
case MrPoortext.MR_TEXT1_SELF: title_color = Theme.DIALOGS_SELF_TEXT_COLOR; break;
case MrPoortext.MR_TEXT1_DRAFT: title_color = Theme.DIALOGS_DRAFT_TEXT_COLOR; break;
}
SpannableStringBuilder stringBuilder = SpannableStringBuilder.valueOf(String.format("%s: %s", title, mess));
stringBuilder.setSpan(new ForegroundColorSpan(title_color), 0, title.length() + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
@@ -534,7 +532,7 @@ public class DialogCell extends BaseCell {
public void checkCurrentDialogIndex() {
if (index < MrMailbox.m_currChatlist.getCnt()) { // EDIT BY MR - was: index < getDialogsArray().size()
TLRPC.TL_dialog dialog = MrMailbox.m_currChatlist.get_TLRPC_TL_dialog(index); // EDIT BY MR - was: getDialogsArray().get(index);
MessageObject newMessageObject = MessagesController.getInstance().dialogMessage.get(dialog.id);
final MessageObject newMessageObject = null;
if (currentDialogId != dialog.id ||
message != null && message.getId() != dialog.top_message ||
unreadCount != dialog.unread_count ||
@@ -553,14 +551,6 @@ public class DialogCell extends BaseCell {
if (mask != 0) {
boolean continueUpdate = false;
if (isDialogCell) {
if ((mask & MessagesController.UPDATE_MASK_USER_PRINT) != 0) {
CharSequence printString = MessagesController.getInstance().printingStrings.get(currentDialogId);
if (lastPrintString != null && printString == null || lastPrintString == null && printString != null || lastPrintString != null && printString != null && !lastPrintString.equals(printString)) {
continueUpdate = true;
}
}
}
if (!continueUpdate && (mask & MessagesController.UPDATE_MASK_AVATAR) != 0) {
if (chat == null) {
continueUpdate = true;
@@ -581,18 +571,6 @@ public class DialogCell extends BaseCell {
continueUpdate = true;
}
}
if (!continueUpdate && (mask & MessagesController.UPDATE_MASK_READ_DIALOG_MESSAGE) != 0) {
if (message != null && lastUnreadState != message.isUnread()) {
lastUnreadState = message.isUnread();
continueUpdate = true;
} else if (isDialogCell) {
TLRPC.TL_dialog dialog = MessagesController.getInstance().dialogs_dict.get(currentDialogId);
if (dialog != null && unreadCount != dialog.unread_count) {
unreadCount = dialog.unread_count;
continueUpdate = true;
}
}
}
if (!continueUpdate && (mask & MessagesController.UPDATE_MASK_SEND_STATE) != 0) {
if (message != null && lastSendState != message.messageOwner.send_state) {
lastSendState = message.messageOwner.send_state;
@@ -606,10 +584,10 @@ public class DialogCell extends BaseCell {
}
dialogMuted = isDialogCell && MessagesController.getInstance().isDialogMuted(currentDialogId);
user = null;
chat = null;
//user = null;
//chat = null;
int lower_id = (int)currentDialogId;
/*int lower_id = (int)currentDialogId;
int high_id = (int)(currentDialogId >> 32);
if (lower_id != 0) {
if (high_id == 1) {
@@ -621,7 +599,7 @@ public class DialogCell extends BaseCell {
user = MessagesController.getInstance().getUser(lower_id);
}
}
}
}*/
ContactsController.setupAvatar(this, avatarImage, avatarDrawable, null, m_mrChat);
@@ -41,9 +41,8 @@ public class DrawerActionCell extends FrameLayout {
super(context);
textView = new TextView(context);
textView.setTextColor(0xff444444);
textView.setTextColor(0xff000000);
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
textView.setLines(1);
textView.setMaxLines(1);
textView.setSingleLine(true);
@@ -55,26 +55,22 @@ public class DrawerProfileCell extends FrameLayout {
private TextView nameTextView;
private TextView subtitleTextView;
private ImageView shadowView;
private Rect srcRect = new Rect();
private Rect destRect = new Rect();
private Paint paint = new Paint();
private int currentColor;
public DrawerProfileCell(Context context) {
super(context);
setBackgroundColor(Theme.ACTION_BAR_COLOR);
shadowView = new ImageView(context);
shadowView.setVisibility(INVISIBLE);
ImageView shadowView = new ImageView(context);
shadowView.setScaleType(ImageView.ScaleType.FIT_XY);
shadowView.setImageResource(R.drawable.bottom_shadow);
addView(shadowView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 100/*EDIT BY MR, was 70*/, Gravity.LEFT | Gravity.BOTTOM));
nameTextView = new TextView(context);
nameTextView.setTextColor(0xffffffff);
nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 22 /*EDIT BY MR, was 15*/);
nameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 23);
nameTextView.setLines(1);
nameTextView.setMaxLines(1);
nameTextView.setSingleLine(true);
@@ -89,12 +85,13 @@ public class DrawerProfileCell extends FrameLayout {
subtitleTextView.setMaxLines(1);
subtitleTextView.setSingleLine(true);
subtitleTextView.setGravity(Gravity.LEFT);
subtitleTextView.setTextColor(0xffffffff);
addView(subtitleTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.BOTTOM, 16, 0, 16, 9));
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int mrHeight = 180; // EDIT BY MR -- was: 148
int mrHeight = 180;
if (Build.VERSION.SDK_INT >= 21) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(mrHeight) + AndroidUtilities.statusBarHeight, MeasureSpec.EXACTLY));
} else {
@@ -110,43 +107,25 @@ public class DrawerProfileCell extends FrameLayout {
@Override
protected void onDraw(Canvas canvas) {
Drawable backgroundDrawable = ApplicationLoader.getCachedWallpaper();
int color = ApplicationLoader.getServiceMessageColor();
if (currentColor != color) {
currentColor = color;
shadowView.getDrawable().setColorFilter(new PorterDuffColorFilter(color | 0xff000000, PorterDuff.Mode.MULTIPLY));
}
if ( backgroundDrawable != null) {
subtitleTextView.setTextColor(0xffffffff);
shadowView.setVisibility(VISIBLE);
if (backgroundDrawable instanceof ColorDrawable) {
backgroundDrawable.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight());
backgroundDrawable.draw(canvas);
} else if (backgroundDrawable instanceof BitmapDrawable) {
Bitmap bitmap = ((BitmapDrawable) backgroundDrawable).getBitmap();
float scaleX = (float) getMeasuredWidth() / (float) bitmap.getWidth();
float scaleY = (float) getMeasuredHeight() / (float) bitmap.getHeight();
float scale = scaleX < scaleY ? scaleY : scaleX;
int width = (int) (getMeasuredWidth() / scale);
int height = (int) (getMeasuredHeight() / scale);
int x = (bitmap.getWidth() - width) / 2;
int y = (bitmap.getHeight() - height) / 2;
srcRect.set(x, y, x + width, y + height);
destRect.set(0, 0, getMeasuredWidth(), getMeasuredHeight());
canvas.drawBitmap(bitmap, srcRect, destRect, paint);
}
} else {
shadowView.setVisibility(INVISIBLE);
subtitleTextView.setTextColor(0xffc2e5ff);
super.onDraw(canvas);
if (backgroundDrawable instanceof ColorDrawable) {
backgroundDrawable.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight());
backgroundDrawable.draw(canvas);
} else if (backgroundDrawable instanceof BitmapDrawable) {
Bitmap bitmap = ((BitmapDrawable) backgroundDrawable).getBitmap();
float scaleX = (float) getMeasuredWidth() / (float) bitmap.getWidth();
float scaleY = (float) getMeasuredHeight() / (float) bitmap.getHeight();
float scale = scaleX < scaleY ? scaleY : scaleX;
int width = (int) (getMeasuredWidth() / scale);
int height = (int) (getMeasuredHeight() / scale);
int x = (bitmap.getWidth() - width) / 2;
int y = (bitmap.getHeight() - height) / 2;
srcRect.set(x, y, x + width, y + height);
destRect.set(0, 0, getMeasuredWidth(), getMeasuredHeight());
canvas.drawBitmap(bitmap, srcRect, destRect, paint);
}
}
public void setUser(TLRPC.User user) {
if (user == null) {
return;
}
public void updateUserName() {
String displayname = MrMailbox.getConfig("displayname", LocaleController.getString("MyAccount", R.string.MyAccount));
String addr;
if( MrMailbox.isConfigured()!=0) {
@@ -48,10 +48,15 @@ public class EditTextCell extends FrameLayout {
private TextView labelTextView;
private static Paint paint;
private boolean needDivider;
private String originalValue;
private boolean useLabel;
public EditTextCell(Context context) {
this(context, true);
}
public EditTextCell(Context context, boolean useLabel__) {
super(context);
useLabel = useLabel__;
if (paint == null) {
paint = new Paint();
@@ -60,7 +65,7 @@ public class EditTextCell extends FrameLayout {
}
labelTextView = new TextView(context);
labelTextView.setTextColor(0xff8a8a8a);
labelTextView.setTextColor(0xff212121);
labelTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13);
labelTextView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT);
labelTextView.setLines(1);
@@ -68,7 +73,7 @@ public class EditTextCell extends FrameLayout {
labelTextView.setSingleLine(true);
labelTextView.setPadding(0, 0, 0, 0);
addView(labelTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP,
17, 10, 17, 0));
17, 8, 17, 0));
editView = new EditText(context);
@@ -97,23 +102,21 @@ public class EditTextCell extends FrameLayout {
*/
addView(editView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP,
17, 25, 17, 0));
17, useLabel? 25 : 25-17, 17, 0));
setBackgroundColor(0xffffffff);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(64) + (needDivider ? 1 : 0), MeasureSpec.EXACTLY));
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(useLabel? 64 : 64-15) + (needDivider ? 1 : 0), MeasureSpec.EXACTLY));
}
public void setValueHintAndLabel(String value, String hint, String label, boolean divider) {
originalValue = value;
editView.setText(value);
editView.setSelection(value.length());
editView.setHint(hint.isEmpty()? "" : ("<"+hint+">"));
editView.setHint(hint);
if( label.isEmpty()) {
labelTextView.setVisibility(INVISIBLE);
@@ -132,11 +135,6 @@ public class EditTextCell extends FrameLayout {
return editView.getText().toString();
}
public boolean isModified()
{
return !originalValue.equals(getValue());
}
public EditText getEditTextView()
{
return editView;
@@ -24,6 +24,7 @@
package com.b44t.ui.Cells;
import android.content.Context;
import android.graphics.Typeface;
import android.util.TypedValue;
import android.view.Gravity;
import android.widget.FrameLayout;
@@ -43,7 +44,7 @@ public class GreySectionCell extends FrameLayout {
textView = new TextView(getContext());
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13);
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
textView.setTypeface(Typeface.DEFAULT_BOLD);
textView.setTextColor(0xff8a8a8a);
textView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 16, 0, 16, 0));
@@ -24,6 +24,7 @@
package com.b44t.ui.Cells;
import android.content.Context;
import android.graphics.Typeface;
import android.util.TypedValue;
import android.view.Gravity;
import android.widget.FrameLayout;
@@ -42,8 +43,8 @@ public class HeaderCell extends FrameLayout {
textView = new TextView(getContext());
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
textView.setTextColor(0xff3e90cf);
textView.setTypeface(Typeface.DEFAULT_BOLD);
textView.setTextColor(0xff5099c9);
textView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 17, 15, 17, 0));
}
@@ -1,51 +0,0 @@
/*******************************************************************************
*
* Messenger Android Frontend
* (C) 2013-2016 Nikolai Kudashov
* (C) 2017 Björn Petersen
* Contact: r10s@b44t.com, http://b44t.com
*
* This program 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.
*
* This program 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
* this program. If not, see http://www.gnu.org/licenses/ .
*
******************************************************************************/
package com.b44t.ui.Cells;
import android.annotation.SuppressLint;
import android.content.Context;
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.b44t.messenger.AndroidUtilities;
import com.b44t.messenger.R;
import com.b44t.ui.Components.LayoutHelper;
@SuppressLint("NewApi")
public class PhotoAttachCameraCell extends FrameLayout {
public PhotoAttachCameraCell(Context context) {
super(context);
ImageView imageView = new ImageView(context);
imageView.setScaleType(ImageView.ScaleType.CENTER);
imageView.setImageResource(R.drawable.instant_camera);
addView(imageView, LayoutHelper.createFrame(80, 80));
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(86), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(80), MeasureSpec.EXACTLY));
}
}
@@ -51,7 +51,6 @@ public class PhotoEditToolCell extends FrameLayout {
nameTextView.setGravity(Gravity.CENTER);
nameTextView.setTextColor(0xffffffff);
nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 10);
nameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
nameTextView.setMaxLines(1);
nameTextView.setSingleLine(true);
nameTextView.setEllipsize(TextUtils.TruncateAt.END);
@@ -60,7 +59,6 @@ public class PhotoEditToolCell extends FrameLayout {
valueTextView = new TextView(context);
valueTextView.setTextColor(0xff6cc3ff);
valueTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 11);
valueTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
addView(valueTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 57, 3, 0, 0));
}
@@ -70,7 +70,7 @@ public class PhotoPickerAlbumsCell extends FrameLayout {
addView(linearLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 28, Gravity.LEFT | Gravity.BOTTOM));
nameTextView = new TextView(context);
nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13);
nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
nameTextView.setTextColor(0xffffffff);
nameTextView.setSingleLine(true);
nameTextView.setEllipsize(TextUtils.TruncateAt.END);
@@ -75,7 +75,7 @@ public class PhotoPickerPhotoCell extends FrameLayout {
}
if (animated) {
if (checked) {
setBackgroundColor(0xff0A0A0A);
setBackgroundColor(0xffffffff);
}
animator = new AnimatorSet();
animator.playTogether(ObjectAnimator.ofFloat(photoImage, "scaleX", checked ? 0.85f : 1.0f),
@@ -101,7 +101,7 @@ public class PhotoPickerPhotoCell extends FrameLayout {
});
animator.start();
} else {
setBackgroundColor(checked ? 0xff0A0A0A : 0);
setBackgroundColor(checked ? 0xffffffff : 0);
photoImage.setScaleX(checked ? 0.85f : 1.0f);
photoImage.setScaleY(checked ? 0.85f : 1.0f);
}
@@ -1,165 +0,0 @@
/*******************************************************************************
*
* Messenger Android Frontend
* (C) 2013-2016 Nikolai Kudashov
* (C) 2017 Björn Petersen
* Contact: r10s@b44t.com, http://b44t.com
*
* This program 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.
*
* This program 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
* this program. If not, see http://www.gnu.org/licenses/ .
*
******************************************************************************/
package com.b44t.ui.Cells;
import android.content.Context;
import android.os.Build;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.b44t.messenger.AndroidUtilities;
import com.b44t.messenger.LocaleController;
import com.b44t.messenger.R;
import com.b44t.ui.Components.LayoutHelper;
public class PhotoPickerSearchCell extends LinearLayout {
public interface PhotoPickerSearchCellDelegate {
void didPressedSearchButton(int index);
}
private class SearchButton extends FrameLayout {
private TextView textView1;
private TextView textView2;
private ImageView imageView;
private View selector;
public SearchButton(Context context) {
super(context);
setBackgroundColor(0xff1a1a1a);
selector = new View(context);
selector.setBackgroundResource(R.drawable.list_selector);
addView(selector, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
imageView = new ImageView(context);
imageView.setScaleType(ImageView.ScaleType.CENTER);
addView(imageView, LayoutHelper.createFrame(48, 48, Gravity.LEFT | Gravity.TOP));
textView1 = new TextView(context);
textView1.setGravity(Gravity.CENTER_VERTICAL);
textView1.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
textView1.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
textView1.setTextColor(0xffffffff);
textView1.setSingleLine(true);
textView1.setEllipsize(TextUtils.TruncateAt.END);
addView(textView1, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.LEFT, 51, 8, 4, 0));
textView2 = new TextView(context);
textView2.setGravity(Gravity.CENTER_VERTICAL);
textView2.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 10);
textView2.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
textView2.setTextColor(0xff666666);
textView2.setSingleLine(true);
textView2.setEllipsize(TextUtils.TruncateAt.END);
addView(textView2, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.LEFT, 51, 26, 4, 0));
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (Build.VERSION.SDK_INT >= 21) {
selector.drawableHotspotChanged(event.getX(), event.getY());
}
return super.onTouchEvent(event);
}
}
private PhotoPickerSearchCellDelegate delegate;
public PhotoPickerSearchCell(Context context, boolean allowGifs) {
super(context);
setOrientation(HORIZONTAL);
SearchButton searchButton = new SearchButton(context);
searchButton.textView1.setText(LocaleController.getString("SearchImages", R.string.SearchImages));
searchButton.textView2.setText(LocaleController.getString("SearchImagesInfo", R.string.SearchImagesInfo));
searchButton.imageView.setImageResource(R.drawable.search_web);
addView(searchButton);
LayoutParams layoutParams = (LayoutParams) searchButton.getLayoutParams();
layoutParams.weight = 0.5f;
layoutParams.topMargin = AndroidUtilities.dp(4);
layoutParams.height = AndroidUtilities.dp(48);
layoutParams.width = 0;
searchButton.setLayoutParams(layoutParams);
searchButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (delegate != null) {
delegate.didPressedSearchButton(0);
}
}
});
FrameLayout frameLayout = new FrameLayout(context);
frameLayout.setBackgroundColor(0);
addView(frameLayout);
layoutParams = (LayoutParams) frameLayout.getLayoutParams();
layoutParams.topMargin = AndroidUtilities.dp(4);
layoutParams.height = AndroidUtilities.dp(48);
layoutParams.width = AndroidUtilities.dp(4);
frameLayout.setLayoutParams(layoutParams);
searchButton = new SearchButton(context);
searchButton.textView1.setText(LocaleController.getString("SearchGifs", R.string.SearchGifs));
searchButton.textView2.setText("GIPHY");
searchButton.imageView.setImageResource(R.drawable.search_gif);
addView(searchButton);
layoutParams = (LayoutParams) searchButton.getLayoutParams();
layoutParams.weight = 0.5f;
layoutParams.topMargin = AndroidUtilities.dp(4);
layoutParams.height = AndroidUtilities.dp(48);
layoutParams.width = 0;
searchButton.setLayoutParams(layoutParams);
if (allowGifs) {
searchButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (delegate != null) {
delegate.didPressedSearchButton(1);
}
}
});
} else {
searchButton.setAlpha(0.5f);
}
}
public void setDelegate(PhotoPickerSearchCellDelegate delegate) {
this.delegate = delegate;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(52), MeasureSpec.EXACTLY));
}
}
@@ -1,482 +0,0 @@
/*******************************************************************************
*
* Messenger Android Frontend
* (C) 2013-2016 Nikolai Kudashov
* (C) 2017 Björn Petersen
* Contact: r10s@b44t.com, http://b44t.com
*
* This program 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.
*
* This program 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
* this program. If not, see http://www.gnu.org/licenses/ .
*
******************************************************************************/
package com.b44t.ui.Cells;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.view.MotionEvent;
import com.b44t.messenger.AndroidUtilities;
import com.b44t.messenger.ImageReceiver;
import com.b44t.messenger.LocaleController;
import com.b44t.messenger.MessagesController;
import com.b44t.messenger.UserObject;
import com.b44t.messenger.R;
import com.b44t.messenger.ConnectionsManager;
import com.b44t.messenger.TLObject;
import com.b44t.messenger.TLRPC;
import com.b44t.messenger.UserConfig;
import com.b44t.ui.Components.AvatarDrawable;
import com.b44t.ui.ActionBar.Theme;
public class ProfileSearchCell extends BaseCell {
private static TextPaint namePaint;
private static TextPaint onlinePaint;
private static TextPaint offlinePaint;
private static TextPaint countPaint;
private static Drawable groupDrawable;
private static Drawable countDrawable;
private static Drawable countDrawableGrey;
private static Paint linePaint;
private CharSequence currentName;
private ImageReceiver avatarImage;
private AvatarDrawable avatarDrawable;
private CharSequence subLabel;
private TLRPC.User user = null;
private TLRPC.Chat chat = null;
private final Object encryptedChat = null;
private long dialog_id;
private String lastName = null;
private int lastStatus = 0;
private TLRPC.FileLocation lastAvatar = null;
public boolean useSeparator = false;
public float drawAlpha = 1;
private int nameLeft;
private int nameTop;
private StaticLayout nameLayout;
private boolean drawNameGroup;
private int nameLockLeft;
private int nameLockTop;
private boolean drawCount;
private int lastUnreadCount;
private int countTop = AndroidUtilities.dp(25);
private int countLeft;
private int countWidth;
private StaticLayout countLayout;
private int onlineLeft;
private StaticLayout onlineLayout;
public ProfileSearchCell(Context context) {
super(context);
if (namePaint == null) {
namePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
namePaint.setTextSize(AndroidUtilities.dp(17));
namePaint.setColor(0xff212121);
namePaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
onlinePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
onlinePaint.setTextSize(AndroidUtilities.dp(16));
onlinePaint.setColor(Theme.MSG_LINK_TEXT_COLOR);
offlinePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
offlinePaint.setTextSize(AndroidUtilities.dp(16));
offlinePaint.setColor(0xff999999);
linePaint = new Paint();
linePaint.setColor(0xffdcdcdc);
countPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
countPaint.setTextSize(AndroidUtilities.dp(13));
countPaint.setColor(0xffffffff);
countPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
groupDrawable = getResources().getDrawable(R.drawable.list_group);
countDrawable = getResources().getDrawable(R.drawable.dialogs_badge);
countDrawableGrey = getResources().getDrawable(R.drawable.dialogs_badge2);
}
avatarImage = new ImageReceiver(this);
avatarImage.setRoundRadius(AndroidUtilities.dp(26));
avatarDrawable = new AvatarDrawable();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (Build.VERSION.SDK_INT >= 21 && getBackground() != null) {
if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE) {
getBackground().setHotspot(event.getX(), event.getY());
}
}
return super.onTouchEvent(event);
}
public void setData(TLObject object, Object ec, CharSequence n, CharSequence s, boolean needCount) {
currentName = n;
if (object instanceof TLRPC.User) {
user = (TLRPC.User) object;
chat = null;
} else if (object instanceof TLRPC.Chat) {
chat = (TLRPC.Chat) object;
user = null;
}
subLabel = s;
drawCount = needCount;
update(0);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
avatarImage.onDetachedFromWindow();
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
avatarImage.onAttachedToWindow();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), AndroidUtilities.dp(72));
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
if (user == null && chat == null && encryptedChat == null) {
super.onLayout(changed, left, top, right, bottom);
return;
}
if (changed) {
buildLayout();
}
}
public void buildLayout() {
CharSequence nameString;
TextPaint currentNamePaint;
drawNameGroup = false;
{
if (chat != null) {
/*if (chat.id < 0) {
dialog_id = AndroidUtilities.makeBroadcastId(chat.id);
drawNameBroadcast = true;
nameLockTop = AndroidUtilities.dp(28.5f);
} else*/ {
dialog_id = -chat.id;
/*if (ChatObject.isChannel(chat) && !chat.megagroup) {
drawNameBroadcast = true;
nameLockTop = AndroidUtilities.dp(28.5f);
} else*/ {
drawNameGroup = true;
nameLockTop = AndroidUtilities.dp(30);
}
}
if (!LocaleController.isRTL) {
nameLockLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline);
nameLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline + 4) + (groupDrawable.getIntrinsicWidth());
} else {
nameLockLeft = getMeasuredWidth() - AndroidUtilities.dp(AndroidUtilities.leftBaseline + 2) - (groupDrawable.getIntrinsicWidth());
nameLeft = AndroidUtilities.dp(11);
}
} else {
dialog_id = user.id;
if (!LocaleController.isRTL) {
nameLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline);
} else {
nameLeft = AndroidUtilities.dp(11);
}
nameLockTop = AndroidUtilities.dp(17);
}
}
if (currentName != null) {
nameString = currentName;
} else {
String nameString2 = "";
if (chat != null) {
nameString2 = chat.title;
} else if (user != null) {
nameString2 = UserObject.getUserName(user);
}
nameString = nameString2.replace('\n', ' ');
}
currentNamePaint = namePaint;
int onlineWidth;
int nameWidth;
if (!LocaleController.isRTL) {
onlineWidth = nameWidth = getMeasuredWidth() - nameLeft - AndroidUtilities.dp(14);
} else {
onlineWidth = nameWidth = getMeasuredWidth() - nameLeft - AndroidUtilities.dp(AndroidUtilities.leftBaseline);
}
/*if (drawNameLock) {
nameWidth -= AndroidUtilities.dp(6) + lockDrawable.getIntrinsicWidth();
} else*/ if (drawNameGroup) {
nameWidth -= AndroidUtilities.dp(6) + groupDrawable.getIntrinsicWidth();
}
if (drawCount) {
TLRPC.TL_dialog dialog = MessagesController.getInstance().dialogs_dict.get(dialog_id);
if (dialog != null && dialog.unread_count != 0) {
lastUnreadCount = dialog.unread_count;
String countString = String.format("%d", dialog.unread_count);
countWidth = Math.max(AndroidUtilities.dp(12), (int) Math.ceil(countPaint.measureText(countString)));
countLayout = new StaticLayout(countString, countPaint, countWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
int w = countWidth + AndroidUtilities.dp(18);
nameWidth -= w;
if (!LocaleController.isRTL) {
countLeft = getMeasuredWidth() - countWidth - AndroidUtilities.dp(19);
} else {
countLeft = AndroidUtilities.dp(19);
nameLeft += w;
}
} else {
lastUnreadCount = 0;
countLayout = null;
}
} else {
lastUnreadCount = 0;
countLayout = null;
}
CharSequence nameStringFinal = TextUtils.ellipsize(nameString, currentNamePaint, nameWidth - AndroidUtilities.dp(12), TextUtils.TruncateAt.END);
nameLayout = new StaticLayout(nameStringFinal, currentNamePaint, nameWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
if (chat == null || subLabel != null) {
if (!LocaleController.isRTL) {
onlineLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline);
} else {
onlineLeft = AndroidUtilities.dp(11);
}
CharSequence onlineString = "";
TextPaint currentOnlinePaint = offlinePaint;
if (subLabel != null) {
onlineString = subLabel;
} else if (user != null) {
onlineString = "ErrOnline";
}
CharSequence onlineStringFinal = TextUtils.ellipsize(onlineString, currentOnlinePaint, onlineWidth - AndroidUtilities.dp(12), TextUtils.TruncateAt.END);
onlineLayout = new StaticLayout(onlineStringFinal, currentOnlinePaint, onlineWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
nameTop = AndroidUtilities.dp(13);
if (subLabel != null && chat != null) {
nameLockTop -= AndroidUtilities.dp(12);
}
} else {
onlineLayout = null;
nameTop = AndroidUtilities.dp(25);
}
int avatarLeft;
if (!LocaleController.isRTL) {
avatarLeft = AndroidUtilities.dp(AndroidUtilities.isTablet() ? 13 : 9);
} else {
avatarLeft = getMeasuredWidth() - AndroidUtilities.dp(AndroidUtilities.isTablet() ? 65 : 61);
}
avatarImage.setImageCoords(avatarLeft, AndroidUtilities.dp(10), AndroidUtilities.dp(52), AndroidUtilities.dp(52));
double widthpx;
float left;
if (LocaleController.isRTL) {
if (nameLayout.getLineCount() > 0) {
left = nameLayout.getLineLeft(0);
if (left == 0) {
widthpx = Math.ceil(nameLayout.getLineWidth(0));
if (widthpx < nameWidth) {
nameLeft += (nameWidth - widthpx);
}
}
}
if (onlineLayout != null && onlineLayout.getLineCount() > 0) {
left = onlineLayout.getLineLeft(0);
if (left == 0) {
widthpx = Math.ceil(onlineLayout.getLineWidth(0));
if (widthpx < onlineWidth) {
onlineLeft += (onlineWidth - widthpx);
}
}
}
} else {
if (nameLayout.getLineCount() > 0) {
left = nameLayout.getLineRight(0);
if (left == nameWidth) {
widthpx = Math.ceil(nameLayout.getLineWidth(0));
if (widthpx < nameWidth) {
nameLeft -= (nameWidth - widthpx);
}
}
}
if (onlineLayout != null && onlineLayout.getLineCount() > 0) {
left = onlineLayout.getLineRight(0);
if (left == onlineWidth) {
widthpx = Math.ceil(onlineLayout.getLineWidth(0));
if (widthpx < onlineWidth) {
onlineLeft -= (onlineWidth - widthpx);
}
}
}
}
}
public void update(int mask) {
TLRPC.FileLocation photo = null;
if (user != null) {
if (user.photo != null) {
photo = user.photo.photo_small;
}
avatarDrawable.setInfoByUser(user);
} else if (chat != null) {
if (chat.photo != null) {
photo = chat.photo.photo_small;
}
avatarDrawable.setInfoByChat(chat);
} else {
avatarDrawable.setInfoByName(null);
}
if (mask != 0) {
boolean continueUpdate = false;
if ((mask & MessagesController.UPDATE_MASK_AVATAR) != 0 && user != null || (mask & MessagesController.UPDATE_MASK_CHAT_AVATAR) != 0 && chat != null) {
if (lastAvatar != null && photo == null || lastAvatar == null && photo != null && lastAvatar != null && photo != null && (lastAvatar.volume_id != photo.volume_id || lastAvatar.local_id != photo.local_id)) {
continueUpdate = true;
}
}
if (!continueUpdate && (mask & MessagesController.UPDATE_MASK_STATUS) != 0 && user != null) {
int newStatus = 0;
if (newStatus != lastStatus) {
continueUpdate = true;
}
}
if (!continueUpdate && ((mask & MessagesController.UPDATE_MASK_NAME) != 0 && user != null) || (mask & MessagesController.UPDATE_MASK_CHAT_NAME) != 0 && chat != null) {
String newName;
if (user != null) {
newName = user.first_name + user.last_name;
} else {
newName = chat.title;
}
if (!newName.equals(lastName)) {
continueUpdate = true;
}
}
if (!continueUpdate && drawCount && (mask & MessagesController.UPDATE_MASK_READ_DIALOG_MESSAGE) != 0) {
TLRPC.TL_dialog dialog = MessagesController.getInstance().dialogs_dict.get(dialog_id);
if (dialog != null && dialog.unread_count != lastUnreadCount) {
continueUpdate = true;
}
}
if (!continueUpdate) {
return;
}
}
if (user != null) {
lastStatus = 0;
lastName = user.first_name + user.last_name;
} else if (chat != null) {
lastName = chat.title;
}
lastAvatar = photo;
avatarImage.setImage(photo, "50_50", avatarDrawable, null, false);
if (getMeasuredWidth() != 0 || getMeasuredHeight() != 0) {
buildLayout();
} else {
requestLayout();
}
postInvalidate();
}
@Override
protected void onDraw(Canvas canvas) {
if (user == null && chat == null && encryptedChat == null) {
return;
}
if (useSeparator) {
if (LocaleController.isRTL) {
canvas.drawLine(0, getMeasuredHeight() - 1, getMeasuredWidth() - AndroidUtilities.dp(AndroidUtilities.leftBaseline), getMeasuredHeight() - 1, linePaint);
} else {
canvas.drawLine(AndroidUtilities.dp(AndroidUtilities.leftBaseline), getMeasuredHeight() - 1, getMeasuredWidth(), getMeasuredHeight() - 1, linePaint);
}
}
if (drawAlpha != 1) {
canvas.saveLayerAlpha(0, 0, canvas.getWidth(), canvas.getHeight(), (int)(255 * drawAlpha), Canvas.HAS_ALPHA_LAYER_SAVE_FLAG);
}
/*if (drawNameLock) {
setDrawableBounds(lockDrawable, nameLockLeft, nameLockTop);
lockDrawable.draw(canvas);
} else*/ if (drawNameGroup) {
setDrawableBounds(groupDrawable, nameLockLeft, nameLockTop);
groupDrawable.draw(canvas);
}
if (nameLayout != null) {
canvas.save();
canvas.translate(nameLeft, nameTop);
nameLayout.draw(canvas);
canvas.restore();
}
if (onlineLayout != null) {
canvas.save();
canvas.translate(onlineLeft, AndroidUtilities.dp(40));
onlineLayout.draw(canvas);
canvas.restore();
}
if (countLayout != null) {
if (MessagesController.getInstance().isDialogMuted(dialog_id)) {
setDrawableBounds(countDrawableGrey, countLeft - AndroidUtilities.dp(5.5f), countTop, countWidth + AndroidUtilities.dp(11), countDrawableGrey.getIntrinsicHeight());
countDrawableGrey.draw(canvas);
} else {
setDrawableBounds(countDrawable, countLeft - AndroidUtilities.dp(5.5f), countTop, countWidth + AndroidUtilities.dp(11), countDrawable.getIntrinsicHeight());
countDrawable.draw(canvas);
}
canvas.save();
canvas.translate(countLeft, countTop + AndroidUtilities.dp(4));
countLayout.draw(canvas);
canvas.restore();
}
avatarImage.draw(canvas);
}
}
@@ -34,48 +34,24 @@ import android.widget.ImageView;
import android.widget.TextView;
import com.b44t.messenger.AndroidUtilities;
import com.b44t.messenger.ImageLoader;
import com.b44t.messenger.ImageReceiver;
import com.b44t.messenger.LocaleController;
import com.b44t.messenger.MediaController;
import com.b44t.messenger.MessageObject;
import com.b44t.messenger.FileLoader;
import com.b44t.messenger.R;
import com.b44t.ui.Components.BackupImageView;
import com.b44t.ui.Components.CheckBox;
import com.b44t.ui.Components.LayoutHelper;
import com.b44t.ui.Components.LineProgressView;
import java.io.File;
public class SharedDocumentCell extends FrameLayout {
public class SharedDocumentCell extends FrameLayout implements MediaController.FileDownloadProgressListener {
private ImageView placeholderImabeView;
private ImageView placeholderImageView;
private BackupImageView thumbImageView;
private TextView nameTextView;
private TextView extTextView;
private TextView dateTextView;
private ImageView statusImageView;
private LineProgressView progressView;
private CheckBox checkBox;
private boolean needDivider;
private static Paint paint;
private int TAG;
private MessageObject message;
private boolean loading;
private boolean loaded;
private int icons[] = {
R.drawable.media_doc_blue,
R.drawable.media_doc_green,
R.drawable.media_doc_red,
R.drawable.media_doc_yellow
};
public SharedDocumentCell(Context context) {
super(context);
@@ -85,36 +61,21 @@ public class SharedDocumentCell extends FrameLayout implements MediaController.F
paint.setStrokeWidth(1);
}
TAG = MediaController.getInstance().generateObserverTag();
placeholderImabeView = new ImageView(context);
addView(placeholderImabeView, LayoutHelper.createFrame(40, 40, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 0 : 12, 8, LocaleController.isRTL ? 12 : 0, 0));
extTextView = new TextView(context);
extTextView.setTextColor(0xffffffff);
extTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
extTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
extTextView.setLines(1);
extTextView.setMaxLines(1);
extTextView.setSingleLine(true);
extTextView.setGravity(Gravity.CENTER);
extTextView.setEllipsize(TextUtils.TruncateAt.END);
addView(extTextView, LayoutHelper.createFrame(32, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 0 : 16, 22, LocaleController.isRTL ? 16 : 0, 0));
placeholderImageView = new ImageView(context);
addView(placeholderImageView, LayoutHelper.createFrame(40, 40, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 0 : 12, 8, LocaleController.isRTL ? 12 : 0, 0));
thumbImageView = new BackupImageView(context);
addView(thumbImageView, LayoutHelper.createFrame(40, 40, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 0 : 12, 8, LocaleController.isRTL ? 12 : 0, 0));
thumbImageView.getImageReceiver().setDelegate(new ImageReceiver.ImageReceiverDelegate() {
@Override
public void didSetImage(ImageReceiver imageReceiver, boolean set, boolean thumb) {
extTextView.setVisibility(set ? INVISIBLE : VISIBLE);
placeholderImabeView.setVisibility(set ? INVISIBLE : VISIBLE);
placeholderImageView.setVisibility(set ? INVISIBLE : VISIBLE);
}
});
nameTextView = new TextView(context);
nameTextView.setTextColor(0xff212121);
nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
nameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
nameTextView.setLines(1);
nameTextView.setMaxLines(1);
nameTextView.setSingleLine(true);
@@ -122,10 +83,6 @@ public class SharedDocumentCell extends FrameLayout implements MediaController.F
nameTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
addView(nameTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 8 : 72, 5, LocaleController.isRTL ? 72 : 8, 0));
statusImageView = new ImageView(context);
statusImageView.setVisibility(INVISIBLE);
addView(statusImageView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 8 : 72, 35, LocaleController.isRTL ? 72 : 8, 0));
dateTextView = new TextView(context);
dateTextView.setTextColor(0xff999999);
dateTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
@@ -136,54 +93,24 @@ public class SharedDocumentCell extends FrameLayout implements MediaController.F
dateTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
addView(dateTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 8 : 72, 30, LocaleController.isRTL ? 72 : 8, 0));
progressView = new LineProgressView(context);
addView(progressView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 2, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 0 : 72, 54, LocaleController.isRTL ? 72 : 0, 0));
checkBox = new CheckBox(context, R.drawable.round_check2);
checkBox.setVisibility(INVISIBLE);
addView(checkBox, LayoutHelper.createFrame(22, 22, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 0 : 34, 30, LocaleController.isRTL ? 34 : 0, 0));
}
private int getThumbForNameOrMime(String name, String mime) {
if (name != null && name.length() != 0) {
int color = -1;
if (name.contains(".doc") || name.contains(".txt") || name.contains(".psd")) {
color = 0;
} else if (name.contains(".xls") || name.contains(".csv")) {
color = 1;
} else if (name.contains(".pdf") || name.contains(".ppt") || name.contains(".key")) {
color = 2;
} else if (name.contains(".zip") || name.contains(".rar") || name.contains(".ai") || name.contains(".mp3") || name.contains(".mov") || name.contains(".avi")) {
color = 3;
}
if (color == -1) {
int idx;
String ext = (idx = name.lastIndexOf('.')) == -1 ? "" : name.substring(idx + 1);
if (ext.length() != 0) {
color = ext.charAt(0) % icons.length;
} else {
color = name.charAt(0) % icons.length;
}
}
return icons[color];
}
return icons[0];
}
public void setTextAndValueAndTypeAndThumb(String text, String value, String type, String thumb, int resId) {
nameTextView.setText(text);
dateTextView.setText(value);
if (type != null) {
extTextView.setVisibility(VISIBLE);
extTextView.setText(type);
} else {
extTextView.setVisibility(INVISIBLE);
if( type != null ) {
dateTextView.setText(value + " " + type);
}
else {
dateTextView.setText(value);
}
if (resId == 0) {
placeholderImabeView.setImageResource(getThumbForNameOrMime(text, type));
placeholderImabeView.setVisibility(VISIBLE);
placeholderImageView.setImageResource(R.drawable.attach_file_inlist);
placeholderImageView.setVisibility(VISIBLE);
} else {
placeholderImabeView.setVisibility(INVISIBLE);
placeholderImageView.setVisibility(INVISIBLE);
}
if (thumb != null || resId != 0) {
if (thumb != null) {
@@ -197,12 +124,6 @@ public class SharedDocumentCell extends FrameLayout implements MediaController.F
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
MediaController.getInstance().removeLoadingFileObserver(this);
}
public void setChecked(boolean checked, boolean animated) {
if (checkBox.getVisibility() != VISIBLE) {
checkBox.setVisibility(VISIBLE);
@@ -210,161 +131,8 @@ public class SharedDocumentCell extends FrameLayout implements MediaController.F
checkBox.setChecked(checked, animated);
}
/*
public void setDocument(MessageObject messageObject, boolean divider) {
needDivider = divider;
message = messageObject;
loaded = false;
loading = false;
if (messageObject != null && messageObject.getDocument() != null) {
int idx;
String name = null;
if (messageObject.isMusic()) {
TLRPC.Document document;
if (messageObject.type == 0) {
document = messageObject.messageOwner.media.webpage.document;
} else {
document = messageObject.messageOwner.media.document;
}
for (int a = 0; a < document.attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = document.attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeAudio) {
if (attribute.performer != null && attribute.performer.length() != 0 || attribute.title != null && attribute.title.length() != 0) {
name = messageObject.getMusicAuthor() + " - " + messageObject.getMusicTitle();
}
}
}
}
String fileName = FileLoader.getDocumentFileName(messageObject.getDocument());
if (name == null) {
name = fileName;
}
nameTextView.setText(name);
placeholderImabeView.setVisibility(VISIBLE);
extTextView.setVisibility(VISIBLE);
placeholderImabeView.setImageResource(getThumbForNameOrMime(fileName, messageObject.getDocument().mime_type));
extTextView.setText((idx = fileName.lastIndexOf('.')) == -1 ? "" : fileName.substring(idx + 1).toLowerCase());
if (messageObject.getDocument().thumb instanceof TLRPC.TL_photoSizeEmpty || messageObject.getDocument().thumb == null) {
thumbImageView.setVisibility(INVISIBLE);
thumbImageView.setImageBitmap(null);
} else {
thumbImageView.setVisibility(VISIBLE);
thumbImageView.setImage(messageObject.getDocument().thumb.location, "40_40", (Drawable) null);
}
long date = (long) messageObject.messageOwner.date * 1000;
dateTextView.setText(String.format("%s, %s", AndroidUtilities.formatFileSize(messageObject.getDocument().size), LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, LocaleController.getInstance().formatterYear.format(new Date(date)), LocaleController.getInstance().formatterDay.format(new Date(date)))));
} else {
nameTextView.setText("");
extTextView.setText("");
dateTextView.setText("");
placeholderImabeView.setVisibility(VISIBLE);
extTextView.setVisibility(VISIBLE);
thumbImageView.setVisibility(INVISIBLE);
thumbImageView.setImageBitmap(null);
}
setWillNotDraw(!needDivider);
progressView.setProgress(0, false);
updateFileExistIcon();
}
*/
public void updateFileExistIcon() {
if (message != null && message.messageOwner.media != null) {
String fileName = null;
File cacheFile;
if (message.messageOwner.attachPath == null || message.messageOwner.attachPath.length() == 0 || !(new File(message.messageOwner.attachPath).exists())) {
cacheFile = FileLoader.getPathToMessage(message.messageOwner);
if (!cacheFile.exists()) {
fileName = FileLoader.getAttachFileName(message.getDocument());
}
}
loaded = false;
if (fileName == null) {
statusImageView.setVisibility(INVISIBLE);
dateTextView.setPadding(0, 0, 0, 0);
loading = false;
loaded = true;
MediaController.getInstance().removeLoadingFileObserver(this);
} else {
MediaController.getInstance().addLoadingFileObserver(fileName, this);
loading = FileLoader.getInstance().isLoadingFile(fileName);
statusImageView.setVisibility(VISIBLE);
statusImageView.setImageResource(loading ? R.drawable.media_doc_pause : R.drawable.media_doc_load);
dateTextView.setPadding(LocaleController.isRTL ? 0 : AndroidUtilities.dp(14), 0, LocaleController.isRTL ? AndroidUtilities.dp(14) : 0, 0);
if (loading) {
progressView.setVisibility(VISIBLE);
Float progress = ImageLoader.getInstance().getFileProgress(fileName);
if (progress == null) {
progress = 0.0f;
}
progressView.setProgress(progress, false);
} else {
progressView.setVisibility(INVISIBLE);
}
}
} else {
loading = false;
loaded = true;
progressView.setVisibility(INVISIBLE);
progressView.setProgress(0, false);
statusImageView.setVisibility(INVISIBLE);
dateTextView.setPadding(0, 0, 0, 0);
MediaController.getInstance().removeLoadingFileObserver(this);
}
}
public MessageObject getMessage() {
return message;
}
public boolean isLoaded() {
return loaded;
}
public boolean isLoading() {
return loading;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(56) + (needDivider ? 1 : 0), MeasureSpec.EXACTLY));
}
@Override
protected void onDraw(Canvas canvas) {
if (needDivider) {
canvas.drawLine(AndroidUtilities.dp(72), getHeight() - 1, getWidth() - getPaddingRight(), getHeight() - 1, paint);
}
}
@Override
public void onFailedDownload(String name) {
updateFileExistIcon();
}
@Override
public void onSuccessDownload(String name) {
progressView.setProgress(1, true);
updateFileExistIcon();
}
@Override
public void onProgressDownload(String fileName, float progress) {
if (progressView.getVisibility() != VISIBLE) {
updateFileExistIcon();
}
progressView.setProgress(progress, true);
}
@Override
public void onProgressUpload(String fileName, float progress, boolean isEncrypted) {
}
@Override
public int getObserverTag() {
return TAG;
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(56) /*+ (needDivider ? 1 : 0)*/, MeasureSpec.EXACTLY));
}
}
@@ -1,159 +0,0 @@
/*******************************************************************************
*
* Messenger Android Frontend
* (C) 2013-2016 Nikolai Kudashov
* (C) 2017 Björn Petersen
* Contact: r10s@b44t.com, http://b44t.com
*
* This program 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.
*
* This program 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
* this program. If not, see http://www.gnu.org/licenses/ .
*
******************************************************************************/
package com.b44t.ui.Cells;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Build;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import com.b44t.messenger.AndroidUtilities;
import com.b44t.messenger.LocaleController;
import com.b44t.messenger.R;
import com.b44t.messenger.TLRPC;
import com.b44t.ui.ActionBar.Theme;
import com.b44t.ui.Components.BackupImageView;
import com.b44t.ui.Components.LayoutHelper;
import java.util.ArrayList;
public class StickerSetCell extends FrameLayout {
private TextView textView;
private TextView valueTextView;
private BackupImageView imageView;
private boolean needDivider;
private ImageView optionsButton;
private TLRPC.TL_messages_stickerSet stickersSet;
private Rect rect = new Rect();
private static Paint paint;
public StickerSetCell(Context context) {
super(context);
if (paint == null) {
paint = new Paint();
paint.setColor(0xffd9d9d9);
}
textView = new TextView(context);
textView.setTextColor(0xff212121);
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
textView.setLines(1);
textView.setMaxLines(1);
textView.setSingleLine(true);
textView.setEllipsize(TextUtils.TruncateAt.END);
textView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT);
addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT, LocaleController.isRTL ? 40 : 71, 10, LocaleController.isRTL ? 71 : 40, 0));
valueTextView = new TextView(context);
valueTextView.setTextColor(0xff8a8a8a);
valueTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13);
valueTextView.setLines(1);
valueTextView.setMaxLines(1);
valueTextView.setSingleLine(true);
valueTextView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT);
addView(valueTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT, LocaleController.isRTL ? 40 : 71, 35, LocaleController.isRTL ? 71 : 40, 0));
imageView = new BackupImageView(context);
imageView.setAspectFit(true);
addView(imageView, LayoutHelper.createFrame(48, 48, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 0 : 12, 8, LocaleController.isRTL ? 12 : 0, 0));
optionsButton = new ImageView(context);
optionsButton.setFocusable(false);
optionsButton.setBackgroundDrawable(Theme.createBarSelectorDrawable(Theme.ACTION_BAR_AUDIO_SELECTOR_COLOR));
optionsButton.setImageResource(R.drawable.doc_actions_b);
optionsButton.setScaleType(ImageView.ScaleType.CENTER);
addView(optionsButton, LayoutHelper.createFrame(40, 40, (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.TOP));
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(64) + (needDivider ? 1 : 0), MeasureSpec.EXACTLY));
}
public void setStickersSet(TLRPC.TL_messages_stickerSet set, boolean divider) {
needDivider = divider;
stickersSet = set;
textView.setText(stickersSet.set.title);
if (stickersSet.set.disabled) {
textView.setAlpha(0.5f);
valueTextView.setAlpha(0.5f);
imageView.setAlpha(0.5f);
} else {
textView.setAlpha(1.0f);
valueTextView.setAlpha(1.0f);
imageView.setAlpha(1.0f);
}
ArrayList<TLRPC.Document> documents = set.documents;
if (documents != null && !documents.isEmpty()) {
valueTextView.setText(LocaleController.formatPluralString("Stickers", documents.size()));
TLRPC.Document document = documents.get(0);
if (document.thumb != null && document.thumb.location != null) {
imageView.setImage(document.thumb.location, null, "webp", null);
}
} else {
valueTextView.setText(LocaleController.formatPluralString("Stickers", 0));
}
}
public void setOnOptionsClick(OnClickListener listener) {
optionsButton.setOnClickListener(listener);
}
public TLRPC.TL_messages_stickerSet getStickersSet() {
return stickersSet;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (Build.VERSION.SDK_INT >= 21 && getBackground() != null) {
optionsButton.getHitRect(rect);
if (rect.contains((int) event.getX(), (int) event.getY())) {
return true;
}
if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE) {
getBackground().setHotspot(event.getX(), event.getY());
}
}
return super.onTouchEvent(event);
}
@Override
protected void onDraw(Canvas canvas) {
if (needDivider) {
canvas.drawLine(0, getHeight() - 1, getWidth() - getPaddingRight(), getHeight() - 1, paint);
}
}
}
@@ -1,7 +1,6 @@
/*******************************************************************************
*
* Messenger Android Frontend
* (C) 2013-2016 Nikolai Kudashov
* (C) 2017 Björn Petersen
* Contact: r10s@b44t.com, http://b44t.com
*
@@ -24,7 +23,6 @@
package com.b44t.ui.Cells;
import android.content.Context;
import android.text.method.LinkMovementMethod;
import android.util.TypedValue;
import android.view.Gravity;
import android.widget.FrameLayout;
@@ -33,23 +31,29 @@ import android.widget.TextView;
import com.b44t.messenger.AndroidUtilities;
import com.b44t.messenger.LocaleController;
import com.b44t.ui.Components.LayoutHelper;
import com.b44t.ui.ActionBar.Theme;
public class TextInfoPrivacyCell extends FrameLayout {
public class TextInfoCell extends FrameLayout {
private TextView textView;
private TextView iconView;
public TextInfoPrivacyCell(Context context) {
private final int iconDp = 34;
public TextInfoCell(Context context) {
super(context);
textView = new TextView(context);
textView.setTextColor(0xff808080);
textView.setLinkTextColor(Theme.MSG_LINK_TEXT_COLOR);
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
textView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT);
textView.setPadding(0, AndroidUtilities.dp(10), 0, AndroidUtilities.dp(17));
textView.setMovementMethod(LinkMovementMethod.getInstance());
addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 17, 0, 17, 0));
addView(textView);
iconView = new TextView(context);
iconView.setTextColor(0xff212121);
iconView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, iconDp);
iconView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT);
addView(iconView);
}
@Override
@@ -57,8 +61,43 @@ public class TextInfoPrivacyCell extends FrameLayout {
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
}
public void setText(CharSequence text) {
public void setText(CharSequence text)
{
setText(text, null, true);
}
public void setText(CharSequence text, CharSequence icon, boolean borderBotton)
{
textView.setText(text);
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) textView.getLayoutParams();
lp.width = LayoutHelper.WRAP_CONTENT;
lp.height = LayoutHelper.WRAP_CONTENT;
lp.gravity = (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP;
lp.leftMargin = AndroidUtilities.dp(17);
lp.topMargin = AndroidUtilities.dp(13);
lp.rightMargin = AndroidUtilities.dp(17 + (icon!=null?iconDp:0));
lp.bottomMargin = borderBotton? AndroidUtilities.dp(13) : 0;
textView.setLayoutParams(lp);
if( icon != null )
{
iconView.setText(icon);
iconView.setVisibility(VISIBLE);
lp = (FrameLayout.LayoutParams) iconView.getLayoutParams();
lp.width = LayoutHelper.WRAP_CONTENT;
lp.height = LayoutHelper.WRAP_CONTENT;
lp.gravity = (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.TOP;
lp.leftMargin = AndroidUtilities.dp(17);
lp.topMargin = AndroidUtilities.dp(3);
lp.rightMargin = AndroidUtilities.dp(20);
iconView.setLayoutParams(lp);
}
else
{
iconView.setVisibility(GONE);
}
}
public void setTextColor(int color) {
File diff suppressed because it is too large Load Diff
@@ -40,7 +40,6 @@ import com.b44t.messenger.MediaController;
import com.b44t.messenger.TLRPC;
import com.b44t.messenger.FileLoader;
import com.b44t.messenger.FileLog;
import com.b44t.messenger.NotificationCenter;
import com.b44t.messenger.UserConfig;
import com.b44t.ui.LaunchActivity;
import com.b44t.ui.PhotoAlbumPickerActivity;
@@ -51,7 +50,7 @@ import com.b44t.ui.PhotoViewer;
import java.io.File;
import java.util.ArrayList;
public class AvatarUpdater implements NotificationCenter.NotificationCenterDelegate, PhotoCropActivity.PhotoEditActivityDelegate {
public class AvatarUpdater implements PhotoCropActivity.PhotoEditActivityDelegate {
public String currentPicturePath;
private TLRPC.PhotoSize smallPhoto;
@@ -84,7 +83,7 @@ public class AvatarUpdater implements NotificationCenter.NotificationCenterDeleg
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(image));
currentPicturePath = image.getAbsolutePath();
}
parentFragment.startActivityForResult(takePictureIntent, 13);
parentFragment.startActivityForResult(takePictureIntent, BaseFragment.RC13_AVATAR_IMAGE_CAPTURE);
} catch (Exception e) {
FileLog.e("messenger", e);
}
@@ -97,10 +96,10 @@ public class AvatarUpdater implements NotificationCenter.NotificationCenterDeleg
return;
}
}
PhotoAlbumPickerActivity fragment = new PhotoAlbumPickerActivity(true, false, null);
PhotoAlbumPickerActivity fragment = new PhotoAlbumPickerActivity(true, null);
fragment.setDelegate(new PhotoAlbumPickerActivity.PhotoAlbumPickerActivityDelegate() {
@Override
public void didSelectPhotos(ArrayList<String> photos, ArrayList<String> captions, ArrayList<MediaController.SearchImage> webPhotos) {
public void didSelectPhotos(ArrayList<String> photos, ArrayList<String> captions) {
if (!photos.isEmpty()) {
Bitmap bitmap = ImageLoader.loadBitmap(photos.get(0), null, 800, 800, true);
processBitmap(bitmap);
@@ -109,13 +108,14 @@ public class AvatarUpdater implements NotificationCenter.NotificationCenterDeleg
@Override
public void startPhotoSelectActivity() {
/* -- this is the fallback implementation of the gallery selection, see ID_OPEN_SYSTEM_SELECTOR
try {
Intent photoPickerIntent = new Intent(Intent.ACTION_GET_CONTENT);
photoPickerIntent.setType("image/*");
parentFragment.startActivityForResult(photoPickerIntent, 14);
parentFragment.startActivityForResult(photoPickerIntent, BaseFragment.RC14_AVATAR_GET_CONTENT);
} catch (Exception e) {
FileLog.e("messenger", e);
}
} */
}
@Override
@@ -150,7 +150,7 @@ public class AvatarUpdater implements NotificationCenter.NotificationCenterDeleg
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
if (requestCode == 13) {
if (requestCode == BaseFragment.RC13_AVATAR_IMAGE_CAPTURE) {
PhotoViewer.getInstance().setParentActivity(parentFragment.getParentActivity());
int orientation = 0;
try {
@@ -188,11 +188,12 @@ public class AvatarUpdater implements NotificationCenter.NotificationCenterDeleg
}, null);
AndroidUtilities.addMediaToGallery(currentPicturePath);
currentPicturePath = null;
} else if (requestCode == 14) {
} else if (requestCode == BaseFragment.RC14_AVATAR_GET_CONTENT) {
/* -- this is the fallback implementation of the gallery selection, see ID_OPEN_SYSTEM_SELECTOR
if (data == null || data.getData() == null) {
return;
}
startCrop(null, data.getData());
startCrop(null, data.getData()); */
}
}
}
@@ -212,9 +213,7 @@ public class AvatarUpdater implements NotificationCenter.NotificationCenterDeleg
} else {
UserConfig.saveConfig(false);
uploadingAvatar = FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE) + "/" + bigPhoto.location.volume_id + "_" + bigPhoto.location.local_id + ".jpg";
NotificationCenter.getInstance().addObserver(AvatarUpdater.this, NotificationCenter.FileDidUpload);
NotificationCenter.getInstance().addObserver(AvatarUpdater.this, NotificationCenter.FileDidFailUpload);
FileLoader.getInstance().uploadFile(uploadingAvatar, false, true);
//FileLoader.getInstance().uploadFile(uploadingAvatar, false, true);
}
}
}
@@ -223,34 +222,4 @@ public class AvatarUpdater implements NotificationCenter.NotificationCenterDeleg
public void didFinishEdit(Bitmap bitmap) {
processBitmap(bitmap);
}
@Override
public void didReceivedNotification(int id, final Object... args) {
if (id == NotificationCenter.FileDidUpload) {
String location = (String)args[0];
if (uploadingAvatar != null && location.equals(uploadingAvatar)) {
NotificationCenter.getInstance().removeObserver(AvatarUpdater.this, NotificationCenter.FileDidUpload);
NotificationCenter.getInstance().removeObserver(AvatarUpdater.this, NotificationCenter.FileDidFailUpload);
if (delegate != null) {
delegate.didUploadedPhoto((TLRPC.InputFile)args[1], smallPhoto, bigPhoto);
}
uploadingAvatar = null;
if (clearAfterUpdate) {
parentFragment = null;
delegate = null;
}
}
} else if (id == NotificationCenter.FileDidFailUpload) {
String location = (String)args[0];
if (uploadingAvatar != null && location.equals(uploadingAvatar)) {
NotificationCenter.getInstance().removeObserver(AvatarUpdater.this, NotificationCenter.FileDidUpload);
NotificationCenter.getInstance().removeObserver(AvatarUpdater.this, NotificationCenter.FileDidFailUpload);
uploadingAvatar = null;
if (clearAfterUpdate) {
parentFragment = null;
delegate = null;
}
}
}
}
}
File diff suppressed because it is too large Load Diff
@@ -29,11 +29,7 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.*;
import android.graphics.Rect;
@@ -42,12 +38,9 @@ import android.os.Build;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.SoundEffectConstants;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
@@ -55,8 +48,7 @@ import android.widget.ImageView;
import android.widget.TextView;
import com.b44t.messenger.AndroidUtilities;
import com.b44t.messenger.MessagesController;
import com.b44t.messenger.ContactsController;
import com.b44t.messenger.ApplicationLoader;
import com.b44t.messenger.FileLog;
import com.b44t.messenger.LocaleController;
import com.b44t.messenger.MediaController;
@@ -68,13 +60,10 @@ import com.b44t.messenger.support.widget.RecyclerView;
import com.b44t.messenger.TLRPC;
import com.b44t.ui.ActionBar.BottomSheet;
import com.b44t.ui.ActionBar.Theme;
import com.b44t.ui.Cells.PhotoAttachCameraCell;
import com.b44t.ui.Cells.PhotoAttachPhotoCell;
import com.b44t.ui.Cells.ShadowSectionCell;
import com.b44t.ui.ChatActivity;
import com.b44t.ui.PhotoViewer;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
@@ -82,10 +71,10 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
public final static int ATTACH_BUTTON_IDX_CAMERA = 0;
public final static int ATTACH_BUTTON_IDX_VIDEO = 1;
public final static int ATTACH_BUTTON_IDX_LOCATION = 2;
public final static int ATTACH_BUTTON_IDX_CONTACT = 3;
public final static int ATTACH_BUTTON_IDX_GALLERY = 4;
public final static int ATTACH_BUTTON_IDX_FILE = 5;
public final static int ATTACH_BUTTON_IDX_GALLERY = 2;
public final static int ATTACH_BUTTON_IDX_EMPTY = 3;
public final static int ATTACH_BUTTON_IDX_FILE = 4;
public final static int ATTACH_BUTTON_IDX_CONTACT = 5;
public final static int ATTACH_BUTTON_IDX_MUSIC = 6;
public final static int ATTACH_BUTTON_IDX_SENDSELECTED = 7;
public final static int ATTACH_BUTTON_COUNT = 8;
@@ -113,16 +102,8 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
private LinearLayoutManager layoutManager;
private Drawable shadowDrawable;
private ViewGroup attachView;
private ListAdapter adapter;
//private TextView hintTextView;
private ArrayList<InnerAnimator> innerAnimators = new ArrayList<>();
//private AnimatorSet currentHintAnimation;
//private boolean hintShowed;
//private Runnable hideHintRunnable;
private boolean deviceHasGoodCamera = false;//Build.VERSION.SDK_INT >= 16;
private DecelerateInterpolator decelerateInterpolator = new DecelerateInterpolator();
private boolean loading = true;
@@ -180,9 +161,6 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
super(context, false);
setDelegate(this);
setUseRevealAnimation(true);
if (deviceHasGoodCamera) {
//CameraController.getInstance().initCamera();
}
NotificationCenter.getInstance().addObserver(this, NotificationCenter.albumsDidLoaded);
shadowDrawable = context.getResources().getDrawable(R.drawable.sheet_shadow);
@@ -260,7 +238,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
listView.setClipToPadding(false);
listView.setLayoutManager(layoutManager = new LinearLayoutManager(getContext()));
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
listView.setAdapter(adapter = new ListAdapter(context));
listView.setAdapter(new ListAdapter(context));
listView.setVerticalScrollBarEnabled(false);
listView.setEnabled(true);
listView.setGlowColor(0xfff5f6f7);
@@ -280,13 +258,6 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
if (listView.getChildCount() <= 0) {
return;
}
/*if (hintShowed) {
if (layoutManager.findLastVisibleItemPosition() > 1) {
hideHint();
hintShowed = false;
ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE).edit().putBoolean("bothint", true).commit();
}
}*/
updateLayout();
}
});
@@ -306,7 +277,6 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
attachPhotoRecyclerView.layout(0, t, width, t + attachPhotoRecyclerView.getMeasuredHeight());
progressView.layout(0, t, width, t + progressView.getMeasuredHeight());
lineView.layout(0, AndroidUtilities.dp(96), width, AndroidUtilities.dp(96) + lineView.getMeasuredHeight());
//hintTextView.layout(width - hintTextView.getMeasuredWidth() - AndroidUtilities.dp(5), height - hintTextView.getMeasuredHeight() - AndroidUtilities.dp(5), width - AndroidUtilities.dp(5), height - AndroidUtilities.dp(5));
int diff = (width - AndroidUtilities.dp(85 * 4 + 20)) / 3;
for (int a = 0; a < 8; a++) {
@@ -341,60 +311,13 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
if (baseFragment == null || baseFragment.getParentActivity() == null) {
return;
}
if (!deviceHasGoodCamera || position != 0) {
if (deviceHasGoodCamera) {
position--;
}
ArrayList<Object> arrayList = (ArrayList) MediaController.allPhotosAlbumEntry.photos;
if (position < 0 || position >= arrayList.size()) {
return;
}
PhotoViewer.getInstance().setParentActivity(baseFragment.getParentActivity());
PhotoViewer.getInstance().openPhotoForSelect(arrayList, position, 0, ChatAttachAlert.this, baseFragment);
AndroidUtilities.hideKeyboard(baseFragment.getFragmentView().findFocus());
} else {
final File path = AndroidUtilities.generatePicturePath();
/*CameraController.getInstance().takePicture(path, ((PhotoAttachCameraCell) view).cameraSession, new Runnable() {
@Override
public void run() {
PhotoViewer.getInstance().setParentActivity(baseFragment.getParentActivity());
final ArrayList<Object> arrayList = new ArrayList<>();
int orientation = 0;
try {
ExifInterface ei = new ExifInterface(path.getAbsolutePath());
int exif = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (exif) {
case ExifInterface.ORIENTATION_ROTATE_90:
orientation = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
orientation = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
orientation = 270;
break;
}
} catch (Exception e) {
FileLog.e("messenger", e);
}
arrayList.add(new MediaController.PhotoEntry(0, 0, 0, path.getAbsolutePath(), orientation, false));
PhotoViewer.getInstance().openPhotoForSelect(arrayList, 0, 2, new PhotoViewer.EmptyPhotoViewerProvider() {
@Override
public void sendButtonPressed(int index) {
AndroidUtilities.addMediaToGallery(path.getAbsolutePath());
baseFragment.sendPhoto((MediaController.PhotoEntry) arrayList.get(0));
}
@Override
public boolean cancelButtonPressed() {
path.delete();
return true;
}
}, baseFragment);
}
});*/
ArrayList<Object> arrayList = (ArrayList) MediaController.allPhotosAlbumEntry.photos;
if (position < 0 || position >= arrayList.size()) {
return;
}
PhotoViewer.getInstance().setParentActivity(baseFragment.getParentActivity());
PhotoViewer.getInstance().openPhotoForSelect(arrayList, position, 0, ChatAttachAlert.this, baseFragment);
AndroidUtilities.hideKeyboard(baseFragment.getFragmentView().findFocus());
}
});
@@ -419,13 +342,13 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
attachView.addView(lineView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1, Gravity.TOP | Gravity.LEFT));
CharSequence[] labels = new CharSequence[ATTACH_BUTTON_COUNT];
labels[ATTACH_BUTTON_IDX_CAMERA] = LocaleController.getString("ChatCamera", R.string.ChatCamera);
labels[ATTACH_BUTTON_IDX_GALLERY] = LocaleController.getString("ChatGallery", R.string.ChatGallery);
labels[ATTACH_BUTTON_IDX_VIDEO] = LocaleController.getString("ChatVideo", R.string.ChatVideo);
labels[ATTACH_BUTTON_IDX_MUSIC] = LocaleController.getString("AttachMusic", R.string.AttachMusic);
labels[ATTACH_BUTTON_IDX_FILE] = LocaleController.getString("ChatDocument", R.string.ChatDocument);
labels[ATTACH_BUTTON_IDX_CONTACT] = LocaleController.getString("AttachContact", R.string.AttachContact);
labels[ATTACH_BUTTON_IDX_LOCATION] = LocaleController.getString("ChatLocation", R.string.ChatLocation);
labels[ATTACH_BUTTON_IDX_CAMERA] = ApplicationLoader.applicationContext.getString(R.string.ChatCamera);
labels[ATTACH_BUTTON_IDX_GALLERY] = ApplicationLoader.applicationContext.getString(R.string.ChatGallery);
labels[ATTACH_BUTTON_IDX_VIDEO] = ApplicationLoader.applicationContext.getString(R.string.AttachVideo);
labels[ATTACH_BUTTON_IDX_MUSIC] = ApplicationLoader.applicationContext.getString(R.string.AttachMusic);
labels[ATTACH_BUTTON_IDX_FILE] = ApplicationLoader.applicationContext.getString(R.string.AttachDocument);
labels[ATTACH_BUTTON_IDX_CONTACT] = ApplicationLoader.applicationContext.getString(R.string.AttachContact);
labels[ATTACH_BUTTON_IDX_EMPTY] = "";
labels[ATTACH_BUTTON_IDX_SENDSELECTED]= "";
for (int a = 0; a < ATTACH_BUTTON_COUNT; a++) {
@@ -446,20 +369,6 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
});
}
/*
hintTextView = new TextView(context);
hintTextView.setBackgroundResource(R.drawable.tooltip);
hintTextView.setTextColor(Theme.CHAT_GIF_HINT_TEXT_COLOR);
hintTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
hintTextView.setPadding(AndroidUtilities.dp(10), 0, AndroidUtilities.dp(10), 0);
hintTextView.setText(LocaleController.getString("AttachBotsHelp", R.string.AttachBotsHelp));
hintTextView.setGravity(Gravity.CENTER_VERTICAL);
hintTextView.setVisibility(View.INVISIBLE);
hintTextView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.scroll_tip, 0, 0, 0);
hintTextView.setCompoundDrawablePadding(AndroidUtilities.dp(8));
attachView.addView(hintTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, 32, Gravity.RIGHT | Gravity.BOTTOM, 5, 0, 5, 5));
*/
for (int a = 0; a < 8; a++) {
viewsCache.add(photoAttachAdapter.createHolder());
}
@@ -471,90 +380,6 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
}
}
/*
private void hideHint() {
if (hideHintRunnable != null) {
AndroidUtilities.cancelRunOnUIThread(hideHintRunnable);
hideHintRunnable = null;
}
if (hintTextView == null) {
return;
}
currentHintAnimation = new AnimatorSet();
currentHintAnimation.playTogether(
ObjectAnimator.ofFloat(hintTextView, "alpha", 0.0f)
);
currentHintAnimation.setInterpolator(decelerateInterpolator);
currentHintAnimation.addListener(new AnimatorListenerAdapterProxy() {
@Override
public void onAnimationEnd(Animator animation) {
if (currentHintAnimation == null || !currentHintAnimation.equals(animation)) {
return;
}
currentHintAnimation = null;
if (hintTextView != null) {
hintTextView.setVisibility(View.INVISIBLE);
}
}
@Override
public void onAnimationCancel(Animator animation) {
if (currentHintAnimation != null && currentHintAnimation.equals(animation)) {
currentHintAnimation = null;
}
}
});
currentHintAnimation.setDuration(300);
currentHintAnimation.start();
}
private void showHint() {
if (SearchQuery.inlineBots.isEmpty()) {
return;
}
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
if (preferences.getBoolean("bothint", false)) {
return;
}
hintShowed = true;
hintTextView.setVisibility(View.VISIBLE);
currentHintAnimation = new AnimatorSet();
currentHintAnimation.playTogether(
ObjectAnimator.ofFloat(hintTextView, "alpha", 0.0f, 1.0f)
);
currentHintAnimation.setInterpolator(decelerateInterpolator);
currentHintAnimation.addListener(new AnimatorListenerAdapterProxy() {
@Override
public void onAnimationEnd(Animator animation) {
if (currentHintAnimation == null || !currentHintAnimation.equals(animation)) {
return;
}
currentHintAnimation = null;
AndroidUtilities.runOnUIThread(hideHintRunnable = new Runnable() {
@Override
public void run() {
if (hideHintRunnable != this) {
return;
}
hideHintRunnable = null;
hideHint();
}
}, 2000);
}
@Override
public void onAnimationCancel(Animator animation) {
if (currentHintAnimation != null && currentHintAnimation.equals(animation)) {
currentHintAnimation = null;
}
}
});
currentHintAnimation.setDuration(300);
currentHintAnimation.start();
}
*/
@Override
public void didReceivedNotification(int id, Object... args) {
if (id == NotificationCenter.albumsDidLoaded) {
@@ -631,14 +456,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
photoEntry.thumbPath = null;
}
}
/*
if (currentHintAnimation != null) {
currentHintAnimation.cancel();
currentHintAnimation = null;
}
hintTextView.setAlpha(0.0f);
hintTextView.setVisibility(View.INVISIBLE);
*/
attachPhotoLayoutManager.scrollToPositionWithOffset(0, 1000000);
photoAttachAdapter.clearSelectedPhotos();
baseFragment = parentFragment;
@@ -802,9 +620,6 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
if (open && Build.VERSION.SDK_INT <= 19 && MediaController.allPhotosAlbumEntry == null) {
MediaController.loadGalleryPhotosAlbums(0);
}
/*if (open) {
showHint();
}*/
}
@Override
@@ -826,63 +641,19 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
private class ListAdapter extends RecyclerView.Adapter {
private Context mContext;
private final int TYPE_ATTACH_CELLS = 0;
public ListAdapter(Context context) {
mContext = context;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
switch (viewType) {
case 0:
view = attachView;
break;
case 1:
view = new ShadowSectionCell(mContext);
break;
default:
FrameLayout frameLayout = new FrameLayout(mContext);/* -- not used, this is the old "swipe up bot stuff" -- {
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
int diff = (right - left - AndroidUtilities.dp(85 * 4 + 20)) / 3;
for (int a = 0; a < 4; a++) {
int x = AndroidUtilities.dp(10) + (a % 4) * (AndroidUtilities.dp(85) + diff);
View child = getChildAt(a);
child.layout(x, 0, x + child.getMeasuredWidth(), child.getMeasuredHeight());
}
}
};
for (int a = 0; a < 4; a++) {
frameLayout.addView(new AttachBotButton(mContext));
}*/
view = frameLayout;
//frameLayout.setLayoutParams(new RecyclerView.LayoutParams(LayoutHelper.MATCH_PARENT, AndroidUtilities.dp(100)));
break;
}
return new Holder(view);
// currently, we only use one viewType, TYPE_ATTACH_CELLS
return new Holder(attachView);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (position > 1) {
/*
position -= 2;
position *= 4;
FrameLayout frameLayout = (FrameLayout) holder.itemView;
for (int a = 0; a < 4; a++) {
AttachBotButton child = (AttachBotButton) frameLayout.getChildAt(a);
if (position + a >= SearchQuery.inlineBots.size()) {
child.setVisibility(View.INVISIBLE);
} else {
child.setVisibility(View.VISIBLE);
child.setTag(position + a);
child.setUser(MessagesController.getInstance().getUser(SearchQuery.inlineBots.get(position + a).peer.user_id));
}
}
*/
}
}
@Override
@@ -892,19 +663,14 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
@Override
public int getItemViewType(int position) {
switch (position) {
case 0:
return 0;
case 1:
return 1;
default:
return 2;
}
return TYPE_ATTACH_CELLS;
}
}
private class PhotoAttachAdapter extends RecyclerView.Adapter {
private final int TYPE_ATTACH_PHOTO_CELL = 0;
private Context mContext;
private HashMap<Integer, MediaController.PhotoEntry> selectedPhotos = new HashMap<>();
@@ -954,45 +720,30 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (!deviceHasGoodCamera || position != 0) {
if (deviceHasGoodCamera) {
position--;
}
PhotoAttachPhotoCell cell = (PhotoAttachPhotoCell) holder.itemView;
MediaController.PhotoEntry photoEntry = MediaController.allPhotosAlbumEntry.photos.get(position);
cell.setPhotoEntry(photoEntry, position == MediaController.allPhotosAlbumEntry.photos.size() - 1);
cell.setChecked(selectedPhotos.containsKey(photoEntry.imageId), false);
cell.getImageView().setTag(position);
cell.setTag(position);
}
PhotoAttachPhotoCell cell = (PhotoAttachPhotoCell) holder.itemView;
MediaController.PhotoEntry photoEntry = MediaController.allPhotosAlbumEntry.photos.get(position);
cell.setPhotoEntry(photoEntry, position == MediaController.allPhotosAlbumEntry.photos.size() - 1);
cell.setChecked(selectedPhotos.containsKey(photoEntry.imageId), false);
cell.getImageView().setTag(position);
cell.setTag(position);
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// currently, we only use one viewType, TYPE_ATTACH_PHOTO_CELL
Holder holder;
switch (viewType) {
case 1:
holder = new Holder(new PhotoAttachCameraCell(mContext));
break;
default:
if (!viewsCache.isEmpty()) {
holder = viewsCache.get(0);
viewsCache.remove(0);
} else {
holder = createHolder();
}
break;
if (!viewsCache.isEmpty()) {
holder = viewsCache.get(0);
viewsCache.remove(0);
} else {
holder = createHolder();
}
return holder;
}
@Override
public int getItemCount() {
int count = 0;
if (deviceHasGoodCamera) {
count++;
}
if (MediaController.allPhotosAlbumEntry != null) {
count += MediaController.allPhotosAlbumEntry.photos.size();
}
@@ -1001,10 +752,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
@Override
public int getItemViewType(int position) {
if (deviceHasGoodCamera && position == 0) {
return 1;
}
return 0;
return TYPE_ATTACH_PHOTO_CELL;
}
}
@@ -24,6 +24,7 @@
package com.b44t.ui.Components;
import android.content.Context;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Bundle;
import android.view.Gravity;
@@ -61,7 +62,6 @@ public class ChatAvatarContainer extends FrameLayout {
titleTextView.setTextColor(Theme.ACTION_BAR_TITLE_COLOR);
titleTextView.setTextSize(18);
titleTextView.setGravity(Gravity.LEFT);
titleTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
titleTextView.setLeftDrawableTopPadding(-AndroidUtilities.dp(1.3f));
titleTextView.setRightDrawableTopPadding(-AndroidUtilities.dp(1.3f));
addView(titleTextView);
@@ -1,158 +0,0 @@
/*******************************************************************************
*
* Messenger Android Frontend
* (C) 2013-2016 Nikolai Kudashov
* (C) 2017 Björn Petersen
* Contact: r10s@b44t.com, http://b44t.com
*
* This program 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.
*
* This program 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
* this program. If not, see http://www.gnu.org/licenses/ .
*
******************************************************************************/
package com.b44t.ui.Components;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.view.animation.DecelerateInterpolator;
import com.b44t.messenger.AndroidUtilities;
public class CloseProgressDrawable2 extends Drawable {
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private long lastFrameTime;
private DecelerateInterpolator interpolator = new DecelerateInterpolator();
private RectF rect = new RectF();
private float angle;
private boolean animating;
public CloseProgressDrawable2() {
super();
paint.setColor(0xffadadad);
paint.setStrokeWidth(AndroidUtilities.dp(2));
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStyle(Paint.Style.STROKE);
}
public void startAnimation() {
animating = true;
lastFrameTime = System.currentTimeMillis();
invalidateSelf();
}
public void stopAnimation() {
animating = false;
}
@Override
public void draw(Canvas canvas) {
long newTime = System.currentTimeMillis();
boolean invalidate = false;
if (lastFrameTime != 0) {
long dt = (newTime - lastFrameTime);
if (animating || angle != 0) {
angle += 360 * dt / 500.0f;
if (!animating && angle >= 720) {
angle = 0;
} else {
angle -= (int) (angle / 720) * 720;
}
invalidateSelf();
}
}
canvas.save();
canvas.translate(getIntrinsicWidth() / 2, getIntrinsicHeight() / 2);
canvas.rotate(-45);
float progress1 = 1.0f;
float progress2 = 1.0f;
float progress3 = 1.0f;
float progress4 = 0.0f;
if (angle >= 0 && angle < 90) {
progress1 = (1.0f - angle / 90.0f);
} else if (angle >= 90 && angle < 180) {
progress1 = 0.0f;
progress2 = 1.0f - (angle - 90) / 90.0f;
} else if (angle >= 180 && angle < 270) {
progress1 = progress2 = 0;
progress3 = 1.0f - (angle - 180) / 90.0f;
} else if (angle >= 270 && angle < 360) {
progress1 = progress2 = progress3 = 0;
progress4 = (angle - 270) / 90.0f;
} else if (angle >= 360 && angle < 450) {
progress1 = progress2 = progress3 = 0;
progress4 = 1.0f - (angle - 360) / 90.0f;
} else if (angle >= 450 && angle < 540) {
progress2 = progress3 = 0;
progress1 = (angle - 450) / 90.0f;
} else if (angle >= 540 && angle < 630) {
progress3 = 0;
progress2 = (angle - 540) / 90.0f;
} else if (angle >= 630 && angle < 720) {
progress3 = (angle - 630) / 90.0f;
}
if (progress1 != 0) {
canvas.drawLine(0, 0, 0, AndroidUtilities.dp(8) * progress1, paint);
}
if (progress2 != 0) {
canvas.drawLine(-AndroidUtilities.dp(8) * progress2, 0, 0, 0, paint);
}
if (progress3 != 0) {
canvas.drawLine(0, -AndroidUtilities.dp(8) * progress3, 0, 0, paint);
}
if (progress4 != 1) {
canvas.drawLine(AndroidUtilities.dp(8) * progress4, 0, AndroidUtilities.dp(8), 0, paint);
}
canvas.restore();
int cx = getBounds().centerX();
int cy = getBounds().centerY();
rect.set(cx - AndroidUtilities.dp(8), cy - AndroidUtilities.dp(8), cx + AndroidUtilities.dp(8), cy + AndroidUtilities.dp(8));
canvas.drawArc(rect, (angle < 360 ? 0 : angle - 360) - 45, (angle < 360 ? angle : 720 - angle), false, paint);
lastFrameTime = newTime;
}
@Override
public void setAlpha(int alpha) {
}
@Override
public void setColorFilter(ColorFilter cf) {
}
@Override
public int getOpacity() {
return PixelFormat.TRANSPARENT;
}
@Override
public int getIntrinsicWidth() {
return AndroidUtilities.dp(24);
}
@Override
public int getIntrinsicHeight() {
return AndroidUtilities.dp(24);
}
}
@@ -1001,7 +1001,7 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
public void clearRecentEmoji() {
SharedPreferences preferences = getContext().getSharedPreferences("emoji", Activity.MODE_PRIVATE);
preferences.edit().putBoolean("filled_default", true).commit();
preferences.edit().putBoolean("filled_default", true).apply();
emojiUseHistory.clear();
recentEmoji.clear();
saveRecentEmoji();
@@ -1108,7 +1108,7 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
stringBuilder.append("=");
stringBuilder.append(entry.getValue());
}
preferences.edit().putString("emojis2", stringBuilder.toString()).commit();
preferences.edit().putString("emojis2", stringBuilder.toString()).apply();
}
private void saveEmojiColors() {
@@ -1122,7 +1122,7 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
stringBuilder.append("=");
stringBuilder.append(entry.getValue());
}
preferences.edit().putString("color", stringBuilder.toString()).commit();
preferences.edit().putString("color", stringBuilder.toString()).apply();
}
private void saveRecentStickers() {
@@ -1135,7 +1135,7 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
stringBuilder.append(newRecentStickers.get(a));
}
editor.putString("stickers2", stringBuilder.toString());
editor.commit();
editor.apply();
}
public void switchToGifRecent() {
@@ -1331,7 +1331,7 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
}
}
}
preferences.edit().remove("emojis").commit();
preferences.edit().remove("emojis").apply();
saveRecentEmoji();
} else {
str = preferences.getString("emojis2", "");
@@ -1355,7 +1355,7 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
for (int i = 0; i < newRecent.length; i++) {
emojiUseHistory.put(newRecent[i], newRecent.length - i);
}
preferences.edit().putBoolean("filled_default", true).commit();
preferences.edit().putBoolean("filled_default", true).apply();
saveRecentEmoji();
}
}
@@ -1412,7 +1412,7 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
return 0;
}
});
preferences.edit().remove("stickers").commit();
preferences.edit().remove("stickers").apply();
saveRecentStickers();
} else {
str = preferences.getString("stickers2", "");
@@ -1,127 +0,0 @@
/*******************************************************************************
*
* Messenger Android Frontend
* (C) 2013-2016 Nikolai Kudashov
* (C) 2017 Björn Petersen
* Contact: r10s@b44t.com, http://b44t.com
*
* This program 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.
*
* This program 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
* this program. If not, see http://www.gnu.org/licenses/ .
*
******************************************************************************/
package com.b44t.ui.Components;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.View;
import android.view.animation.DecelerateInterpolator;
import com.b44t.messenger.AndroidUtilities;
public class LineProgressView extends View {
private long lastUpdateTime = 0;
private float currentProgress = 0;
private float animationProgressStart = 0;
private long currentProgressTime = 0;
private float animatedProgressValue = 0;
private float animatedAlphaValue = 1.0f;
private int backColor;
private int progressColor = 0xff36a2ee;
private static DecelerateInterpolator decelerateInterpolator = null;
private static Paint progressPaint = null;
public LineProgressView(Context context) {
super(context);
if (decelerateInterpolator == null) {
decelerateInterpolator = new DecelerateInterpolator();
progressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
progressPaint.setStyle(Paint.Style.STROKE);
progressPaint.setStrokeCap(Paint.Cap.ROUND);
progressPaint.setStrokeWidth(AndroidUtilities.dp(2));
}
}
private void updateAnimation() {
long newTime = System.currentTimeMillis();
long dt = newTime - lastUpdateTime;
lastUpdateTime = newTime;
if (animatedProgressValue != 1 && animatedProgressValue != currentProgress) {
float progressDiff = currentProgress - animationProgressStart;
if (progressDiff > 0) {
currentProgressTime += dt;
if (currentProgressTime >= 300) {
animatedProgressValue = currentProgress;
animationProgressStart = currentProgress;
currentProgressTime = 0;
} else {
animatedProgressValue = animationProgressStart + progressDiff * decelerateInterpolator.getInterpolation(currentProgressTime / 300.0f);
}
}
invalidate();
}
if (animatedProgressValue >= 1 && animatedProgressValue == 1 && animatedAlphaValue != 0) {
animatedAlphaValue -= dt / 200.0f;
if (animatedAlphaValue <= 0) {
animatedAlphaValue = 0.0f;
}
invalidate();
}
}
public void setProgressColor(int color) {
progressColor = color;
}
public void setBackColor(int color) {
backColor = color;
}
public void setProgress(float value, boolean animated) {
if (!animated) {
animatedProgressValue = value;
animationProgressStart = value;
} else {
animationProgressStart = animatedProgressValue;
}
if (value != 1) {
animatedAlphaValue = 1;
}
currentProgress = value;
currentProgressTime = 0;
lastUpdateTime = System.currentTimeMillis();
invalidate();
}
public void onDraw(Canvas canvas) {
if (backColor != 0 && animatedProgressValue != 1) {
progressPaint.setColor(backColor);
progressPaint.setAlpha((int) (255 * animatedAlphaValue));
int start = (int) (getWidth() * animatedProgressValue);
canvas.drawRect(start, 0, getWidth(), getHeight(), progressPaint);
}
progressPaint.setColor(progressColor);
progressPaint.setAlpha((int)(255 * animatedAlphaValue));
canvas.drawRect(0, 0, getWidth() * animatedProgressValue, getHeight(), progressPaint);
updateAnimation();
}
}
@@ -30,7 +30,6 @@ import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Rect;
@@ -49,7 +48,6 @@ import android.text.method.PasswordTransformationMethod;
import android.util.TypedValue;
import android.view.ActionMode;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
@@ -70,6 +68,7 @@ import com.b44t.messenger.FileLog;
import com.b44t.messenger.R;
import com.b44t.messenger.UserConfig;
import com.b44t.messenger.AnimatorListenerAdapterProxy;
import com.b44t.ui.ActionBar.Theme;
import java.util.ArrayList;
import java.util.Locale;
@@ -80,336 +79,6 @@ public class PasscodeView extends FrameLayout {
void didAcceptedPassword();
}
private class AnimatingTextView extends FrameLayout {
private ArrayList<TextView> characterTextViews;
private ArrayList<TextView> dotTextViews;
private StringBuilder stringBuilder;
private String DOT = "\u2022";
private AnimatorSet currentAnimation;
private Runnable dotRunnable;
public AnimatingTextView(Context context) {
super(context);
characterTextViews = new ArrayList<>(4);
dotTextViews = new ArrayList<>(4);
stringBuilder = new StringBuilder(4);
for (int a = 0; a < 4; a++) {
TextView textView = new TextView(context);
textView.setTextColor(0xffffffff);
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 36);
textView.setGravity(Gravity.CENTER);
textView.setAlpha(0);
textView.setPivotX(AndroidUtilities.dp(25));
textView.setPivotY(AndroidUtilities.dp(25));
addView(textView);
LayoutParams layoutParams = (LayoutParams) textView.getLayoutParams();
layoutParams.width = AndroidUtilities.dp(50);
layoutParams.height = AndroidUtilities.dp(50);
layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
textView.setLayoutParams(layoutParams);
characterTextViews.add(textView);
textView = new TextView(context);
textView.setTextColor(0xffffffff);
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 36);
textView.setGravity(Gravity.CENTER);
textView.setAlpha(0);
textView.setText(DOT);
textView.setPivotX(AndroidUtilities.dp(25));
textView.setPivotY(AndroidUtilities.dp(25));
addView(textView);
layoutParams = (LayoutParams) textView.getLayoutParams();
layoutParams.width = AndroidUtilities.dp(50);
layoutParams.height = AndroidUtilities.dp(50);
layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
textView.setLayoutParams(layoutParams);
dotTextViews.add(textView);
}
}
private int getXForTextView(int pos) {
return (getMeasuredWidth() - stringBuilder.length() * AndroidUtilities.dp(30)) / 2 + pos * AndroidUtilities.dp(30) - AndroidUtilities.dp(10);
}
public void appendCharacter(String c) {
if (stringBuilder.length() == 4) {
return;
}
try {
performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP);
} catch (Exception e) {
FileLog.e("messenger", e);
}
ArrayList<Animator> animators = new ArrayList<>();
final int newPos = stringBuilder.length();
stringBuilder.append(c);
TextView textView = characterTextViews.get(newPos);
textView.setText(c);
textView.setTranslationX(getXForTextView(newPos));
animators.add(ObjectAnimator.ofFloat(textView, "scaleX", 0, 1));
animators.add(ObjectAnimator.ofFloat(textView, "scaleY", 0, 1));
animators.add(ObjectAnimator.ofFloat(textView, "alpha", 0, 1));
animators.add(ObjectAnimator.ofFloat(textView, "translationY", AndroidUtilities.dp(20), 0));
textView = dotTextViews.get(newPos);
textView.setTranslationX(getXForTextView(newPos));
textView.setAlpha(0);
animators.add(ObjectAnimator.ofFloat(textView, "scaleX", 0, 1));
animators.add(ObjectAnimator.ofFloat(textView, "scaleY", 0, 1));
animators.add(ObjectAnimator.ofFloat(textView, "translationY", AndroidUtilities.dp(20), 0));
for (int a = newPos + 1; a < 4; a++) {
textView = characterTextViews.get(a);
if (textView.getAlpha() != 0) {
animators.add(ObjectAnimator.ofFloat(textView, "scaleX", 0));
animators.add(ObjectAnimator.ofFloat(textView, "scaleY", 0));
animators.add(ObjectAnimator.ofFloat(textView, "alpha", 0));
}
textView = dotTextViews.get(a);
if (textView.getAlpha() != 0) {
animators.add(ObjectAnimator.ofFloat(textView, "scaleX", 0));
animators.add(ObjectAnimator.ofFloat(textView, "scaleY", 0));
animators.add(ObjectAnimator.ofFloat(textView, "alpha", 0));
}
}
if (dotRunnable != null) {
AndroidUtilities.cancelRunOnUIThread(dotRunnable);
}
dotRunnable = new Runnable() {
@Override
public void run() {
if (dotRunnable != this) {
return;
}
ArrayList<Animator> animators = new ArrayList<>();
TextView textView = characterTextViews.get(newPos);
animators.add(ObjectAnimator.ofFloat(textView, "scaleX", 0));
animators.add(ObjectAnimator.ofFloat(textView, "scaleY", 0));
animators.add(ObjectAnimator.ofFloat(textView, "alpha", 0));
textView = dotTextViews.get(newPos);
animators.add(ObjectAnimator.ofFloat(textView, "scaleX", 1));
animators.add(ObjectAnimator.ofFloat(textView, "scaleY", 1));
animators.add(ObjectAnimator.ofFloat(textView, "alpha", 1));
currentAnimation = new AnimatorSet();
currentAnimation.setDuration(150);
currentAnimation.playTogether(animators);
currentAnimation.addListener(new AnimatorListenerAdapterProxy() {
@Override
public void onAnimationEnd(Animator animation) {
if (currentAnimation != null && currentAnimation.equals(animation)) {
currentAnimation = null;
}
}
});
currentAnimation.start();
}
};
AndroidUtilities.runOnUIThread(dotRunnable, 1500);
for (int a = 0; a < newPos; a++) {
textView = characterTextViews.get(a);
animators.add(ObjectAnimator.ofFloat(textView, "translationX", getXForTextView(a)));
animators.add(ObjectAnimator.ofFloat(textView, "scaleX", 0));
animators.add(ObjectAnimator.ofFloat(textView, "scaleY", 0));
animators.add(ObjectAnimator.ofFloat(textView, "alpha", 0));
animators.add(ObjectAnimator.ofFloat(textView, "translationY", 0));
textView = dotTextViews.get(a);
animators.add(ObjectAnimator.ofFloat(textView, "translationX", getXForTextView(a)));
animators.add(ObjectAnimator.ofFloat(textView, "scaleX", 1));
animators.add(ObjectAnimator.ofFloat(textView, "scaleY", 1));
animators.add(ObjectAnimator.ofFloat(textView, "alpha", 1));
animators.add(ObjectAnimator.ofFloat(textView, "translationY", 0));
}
if (currentAnimation != null) {
currentAnimation.cancel();
}
currentAnimation = new AnimatorSet();
currentAnimation.setDuration(150);
currentAnimation.playTogether(animators);
currentAnimation.addListener(new AnimatorListenerAdapterProxy() {
@Override
public void onAnimationEnd(Animator animation) {
if (currentAnimation != null && currentAnimation.equals(animation)) {
currentAnimation = null;
}
}
});
currentAnimation.start();
}
public String getString() {
return stringBuilder.toString();
}
public int lenght() {
return stringBuilder.length();
}
public void eraseLastCharacter() {
if (stringBuilder.length() == 0) {
return;
}
try {
performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP);
} catch (Exception e) {
FileLog.e("messenger", e);
}
ArrayList<Animator> animators = new ArrayList<>();
int deletingPos = stringBuilder.length() - 1;
if (deletingPos != 0) {
stringBuilder.deleteCharAt(deletingPos);
}
for (int a = deletingPos; a < 4; a++) {
TextView textView = characterTextViews.get(a);
if (textView.getAlpha() != 0) {
animators.add(ObjectAnimator.ofFloat(textView, "scaleX", 0));
animators.add(ObjectAnimator.ofFloat(textView, "scaleY", 0));
animators.add(ObjectAnimator.ofFloat(textView, "alpha", 0));
animators.add(ObjectAnimator.ofFloat(textView, "translationY", 0));
animators.add(ObjectAnimator.ofFloat(textView, "translationX", getXForTextView(a)));
}
textView = dotTextViews.get(a);
if (textView.getAlpha() != 0) {
animators.add(ObjectAnimator.ofFloat(textView, "scaleX", 0));
animators.add(ObjectAnimator.ofFloat(textView, "scaleY", 0));
animators.add(ObjectAnimator.ofFloat(textView, "alpha", 0));
animators.add(ObjectAnimator.ofFloat(textView, "translationY", 0));
animators.add(ObjectAnimator.ofFloat(textView, "translationX", getXForTextView(a)));
}
}
if (deletingPos == 0) {
stringBuilder.deleteCharAt(deletingPos);
}
for (int a = 0; a < deletingPos; a++) {
TextView textView = characterTextViews.get(a);
animators.add(ObjectAnimator.ofFloat(textView, "translationX", getXForTextView(a)));
textView = dotTextViews.get(a);
animators.add(ObjectAnimator.ofFloat(textView, "translationX", getXForTextView(a)));
}
if (dotRunnable != null) {
AndroidUtilities.cancelRunOnUIThread(dotRunnable);
dotRunnable = null;
}
if (currentAnimation != null) {
currentAnimation.cancel();
}
currentAnimation = new AnimatorSet();
currentAnimation.setDuration(150);
currentAnimation.playTogether(animators);
currentAnimation.addListener(new AnimatorListenerAdapterProxy() {
@Override
public void onAnimationEnd(Animator animation) {
if (currentAnimation != null && currentAnimation.equals(animation)) {
currentAnimation = null;
}
}
});
currentAnimation.start();
}
private void eraseAllCharacters(final boolean animated) {
if (stringBuilder.length() == 0) {
return;
}
if (dotRunnable != null) {
AndroidUtilities.cancelRunOnUIThread(dotRunnable);
dotRunnable = null;
}
if (currentAnimation != null) {
currentAnimation.cancel();
currentAnimation = null;
}
stringBuilder.delete(0, stringBuilder.length());
if (animated) {
ArrayList<Animator> animators = new ArrayList<>();
for (int a = 0; a < 4; a++) {
TextView textView = characterTextViews.get(a);
if (textView.getAlpha() != 0) {
animators.add(ObjectAnimator.ofFloat(textView, "scaleX", 0));
animators.add(ObjectAnimator.ofFloat(textView, "scaleY", 0));
animators.add(ObjectAnimator.ofFloat(textView, "alpha", 0));
}
textView = dotTextViews.get(a);
if (textView.getAlpha() != 0) {
animators.add(ObjectAnimator.ofFloat(textView, "scaleX", 0));
animators.add(ObjectAnimator.ofFloat(textView, "scaleY", 0));
animators.add(ObjectAnimator.ofFloat(textView, "alpha", 0));
}
}
currentAnimation = new AnimatorSet();
currentAnimation.setDuration(150);
currentAnimation.playTogether(animators);
currentAnimation.addListener(new AnimatorListenerAdapterProxy() {
@Override
public void onAnimationEnd(Animator animation) {
if (currentAnimation != null && currentAnimation.equals(animation)) {
currentAnimation = null;
}
}
});
currentAnimation.start();
} else {
for (int a = 0; a < 4; a++) {
characterTextViews.get(a).setAlpha(0);
dotTextViews.get(a).setAlpha(0);
}
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
if (dotRunnable != null) {
AndroidUtilities.cancelRunOnUIThread(dotRunnable);
dotRunnable = null;
}
if (currentAnimation != null) {
currentAnimation.cancel();
currentAnimation = null;
}
for (int a = 0; a < 4; a++) {
if (a < stringBuilder.length()) {
TextView textView = characterTextViews.get(a);
textView.setAlpha(0);
textView.setScaleX(1);
textView.setScaleY(1);
textView.setTranslationY(0);
textView.setTranslationX(getXForTextView(a));
textView = dotTextViews.get(a);
textView.setAlpha(1);
textView.setScaleX(1);
textView.setScaleY(1);
textView.setTranslationY(0);
textView.setTranslationX(getXForTextView(a));
} else {
characterTextViews.get(a).setAlpha(0);
dotTextViews.get(a).setAlpha(0);
}
}
super.onLayout(changed, left, top, right, bottom);
}
}
private Drawable backgroundDrawable;
private FrameLayout numbersFrameLayout;
private ArrayList<TextView> numberTextViews;
@@ -418,14 +87,12 @@ public class PasscodeView extends FrameLayout {
private FrameLayout passwordFrameLayout;
private ImageView eraseView;
private EditText passwordEditText;
private AnimatingTextView passwordEditText2;
private FrameLayout backgroundFrameLayout;
private TextView passcodeTextView;
private ImageView checkImage;
private int keyboardHeight = 0;
private CancellationSignal cancellationSignal;
private ImageView fingerprintImageView;
private TextView fingerprintStatusTextView;
private boolean selfCancelled;
private AlertDialog fingerprintDialog;
@@ -434,9 +101,6 @@ public class PasscodeView extends FrameLayout {
private PasscodeViewDelegate delegate;
private final static int id_fingerprint_textview = 1000;
private final static int id_fingerprint_imageview = 1001;
public PasscodeView(final Context context) {
super(context);
@@ -486,17 +150,6 @@ public class PasscodeView extends FrameLayout {
layoutParams.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
passcodeTextView.setLayoutParams(layoutParams);
passwordEditText2 = new AnimatingTextView(context);
passwordFrameLayout.addView(passwordEditText2);
layoutParams = (FrameLayout.LayoutParams) passwordEditText2.getLayoutParams();
layoutParams.height = LayoutHelper.WRAP_CONTENT;
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.leftMargin = AndroidUtilities.dp(70);
layoutParams.rightMargin = AndroidUtilities.dp(70);
layoutParams.bottomMargin = AndroidUtilities.dp(6);
layoutParams.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
passwordEditText2.setLayoutParams(layoutParams);
passwordEditText = new EditText(context);
passwordEditText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 36);
passwordEditText.setTextColor(0xffffffff);
@@ -678,7 +331,6 @@ public class PasscodeView extends FrameLayout {
@Override
public boolean onLongClick(View v) {
passwordEditText.setText("");
passwordEditText2.eraseAllCharacters(true);
return true;
}
});
@@ -689,40 +341,43 @@ public class PasscodeView extends FrameLayout {
int tag = (Integer) v.getTag();
switch (tag) {
case 0:
passwordEditText2.appendCharacter("0");
appendCharacter("0");
break;
case 1:
passwordEditText2.appendCharacter("1");
appendCharacter("1");
break;
case 2:
passwordEditText2.appendCharacter("2");
appendCharacter("2");
break;
case 3:
passwordEditText2.appendCharacter("3");
appendCharacter("3");
break;
case 4:
passwordEditText2.appendCharacter("4");
appendCharacter("4");
break;
case 5:
passwordEditText2.appendCharacter("5");
appendCharacter("5");
break;
case 6:
passwordEditText2.appendCharacter("6");
appendCharacter("6");
break;
case 7:
passwordEditText2.appendCharacter("7");
appendCharacter("7");
break;
case 8:
passwordEditText2.appendCharacter("8");
appendCharacter("8");
break;
case 9:
passwordEditText2.appendCharacter("9");
appendCharacter("9");
break;
case 10:
passwordEditText2.eraseLastCharacter();
String text = passwordEditText.getText().toString();
if( text.length()>0) {
passwordEditText.setText(text.substring(0,text.length()-1));
}
break;
}
if (passwordEditText2.lenght() == 4) {
if (passwordEditText.getText().toString().length() == 4) {
processDone(false);
}
}
@@ -740,25 +395,24 @@ public class PasscodeView extends FrameLayout {
}
}
private void appendCharacter(String c)
{
passwordEditText.setText(passwordEditText.getText()+c);
}
public void setDelegate(PasscodeViewDelegate delegate) {
this.delegate = delegate;
}
private void processDone(boolean fingerprint) {
if (!fingerprint) {
String password = "";
if (UserConfig.passcodeType == 0) {
password = passwordEditText2.getString();
} else if (UserConfig.passcodeType == 1) {
password = passwordEditText.getText().toString();
}
String password = passwordEditText.getText().toString();
if (password.length() == 0) {
onPasscodeError();
return;
}
if (!UserConfig.checkPasscode(password)) {
passwordEditText.setText("");
passwordEditText2.eraseAllCharacters(true);
onPasscodeError();
return;
}
@@ -866,35 +520,14 @@ public class PasscodeView extends FrameLayout {
FingerprintManagerCompat fingerprintManager = FingerprintManagerCompat.from(ApplicationLoader.applicationContext);
if (fingerprintManager.isHardwareDetected() && fingerprintManager.hasEnrolledFingerprints()) {
RelativeLayout relativeLayout = new RelativeLayout(getContext());
relativeLayout.setPadding(AndroidUtilities.dp(24), AndroidUtilities.dp(16), AndroidUtilities.dp(24), AndroidUtilities.dp(8));
TextView fingerprintTextView = new TextView(getContext());
fingerprintTextView.setTextColor(0xff939393);
fingerprintTextView.setId(id_fingerprint_textview);
fingerprintTextView.setTextAppearance(android.R.style.TextAppearance_Material_Subhead);
fingerprintTextView.setText(LocaleController.getString("FingerprintInfo", R.string.FingerprintInfo));
relativeLayout.addView(fingerprintTextView);
RelativeLayout.LayoutParams layoutParams = LayoutHelper.createRelative(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_START);
fingerprintTextView.setLayoutParams(layoutParams);
fingerprintImageView = new ImageView(getContext());
fingerprintImageView.setImageResource(R.drawable.ic_fp_40px);
fingerprintImageView.setId(id_fingerprint_imageview);
relativeLayout.addView(fingerprintImageView, LayoutHelper.createRelative(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, 0, 20, 0, 0, RelativeLayout.ALIGN_PARENT_START, RelativeLayout.BELOW, id_fingerprint_textview));
relativeLayout.setPadding(AndroidUtilities.dp(16), AndroidUtilities.dp(16), AndroidUtilities.dp(16), AndroidUtilities.dp(8));
fingerprintStatusTextView = new TextView(getContext());
fingerprintStatusTextView.setGravity(Gravity.CENTER_VERTICAL);
fingerprintStatusTextView.setText(LocaleController.getString("FingerprintHelp", R.string.FingerprintHelp));
fingerprintStatusTextView.setTextAppearance(android.R.style.TextAppearance_Material_Body1);
fingerprintStatusTextView.setTextColor(0x42000000);
fingerprintStatusTextView.setText(ApplicationLoader.applicationContext.getString(R.string.FingerprintInfo));
fingerprintStatusTextView.setTextAppearance(android.R.style.TextAppearance_Material_Subhead);
relativeLayout.addView(fingerprintStatusTextView);
layoutParams = LayoutHelper.createRelative(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT);
layoutParams.setMarginStart(AndroidUtilities.dp(16));
layoutParams.addRule(RelativeLayout.ALIGN_BOTTOM, id_fingerprint_imageview);
layoutParams.addRule(RelativeLayout.ALIGN_TOP, id_fingerprint_imageview);
layoutParams.addRule(RelativeLayout.END_OF, id_fingerprint_imageview);
RelativeLayout.LayoutParams layoutParams = LayoutHelper.createRelative(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT);
fingerprintStatusTextView.setLayoutParams(layoutParams);
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
@@ -983,46 +616,31 @@ public class PasscodeView extends FrameLayout {
}
setAlpha(1.0f);
setTranslationY(0);
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
int selectedBackground = preferences.getInt("selectedBackground", 1000001);
if (selectedBackground == 1000001) {
backgroundFrameLayout.setBackgroundColor(0xff517c9e);
backgroundDrawable = ApplicationLoader.getCachedWallpaper();
if (backgroundDrawable != null) {
backgroundFrameLayout.setBackgroundColor(0xb6000000);
} else {
backgroundDrawable = ApplicationLoader.getCachedWallpaper();
if (backgroundDrawable != null) {
backgroundFrameLayout.setBackgroundColor(0xbf000000);
} else {
backgroundFrameLayout.setBackgroundColor(0xff517c9e);
}
backgroundFrameLayout.setBackgroundColor(Theme.ACTION_BAR_COLOR);
}
passcodeTextView.setText(LocaleController.getString("EnterYourPasscode", R.string.EnterYourPasscode));
if (UserConfig.passcodeType == 0) {
//InputFilter[] filterArray = new InputFilter[1];
//filterArray[0] = new InputFilter.LengthFilter(4);
//passwordEditText.setFilters(filterArray);
//passwordEditText.setInputType(InputType.TYPE_CLASS_PHONE);
//passwordEditText.setFocusable(false);
//passwordEditText.setFocusableInTouchMode(false);
numbersFrameLayout.setVisibility(VISIBLE);
passwordEditText.setVisibility(GONE);
passwordEditText2.setVisibility(VISIBLE);
passwordEditText.setFocusable(false);
passwordEditText.setFocusableInTouchMode(false);
checkImage.setVisibility(GONE);
} else if (UserConfig.passcodeType == 1) {
passwordEditText.setFilters(new InputFilter[0]);
passwordEditText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
numbersFrameLayout.setVisibility(GONE);
passwordEditText.setFocusable(true);
passwordEditText.setFocusableInTouchMode(true);
passwordEditText.setVisibility(VISIBLE);
passwordEditText2.setVisibility(GONE);
checkImage.setVisibility(VISIBLE);
}
setVisibility(VISIBLE);
passwordEditText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_TEXT_VARIATION_PASSWORD);
passwordEditText.setTransformationMethod(PasswordTransformationMethod.getInstance());
passwordEditText.setText("");
passwordEditText2.eraseAllCharacters(false);
setOnTouchListener(new OnTouchListener() {
@Override
@@ -1033,7 +651,6 @@ public class PasscodeView extends FrameLayout {
}
private void showFingerprintError(CharSequence error) {
fingerprintImageView.setImageResource(R.drawable.ic_fingerprint_error);
fingerprintStatusTextView.setText(error);
fingerprintStatusTextView.setTextColor(0xfff4511e);
Vibrator v = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE);
@@ -31,6 +31,7 @@ import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.SurfaceTexture;
import android.graphics.Typeface;
import android.opengl.GLES20;
import android.opengl.GLUtils;
import android.os.Build;
@@ -2087,7 +2088,6 @@ public class PhotoFilterView extends FrameLayout {
cancelTextView.setBackgroundDrawable(Theme.createBarSelectorDrawable(Theme.ACTION_BAR_PICKER_SELECTOR_COLOR, false));
cancelTextView.setPadding(AndroidUtilities.dp(29), 0, AndroidUtilities.dp(29), 0);
cancelTextView.setText(LocaleController.getString("Cancel", R.string.Cancel).toUpperCase());
cancelTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
frameLayout.addView(cancelTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT));
doneTextView = new TextView(context);
@@ -2097,7 +2097,7 @@ public class PhotoFilterView extends FrameLayout {
doneTextView.setBackgroundDrawable(Theme.createBarSelectorDrawable(Theme.ACTION_BAR_PICKER_SELECTOR_COLOR, false));
doneTextView.setPadding(AndroidUtilities.dp(29), 0, AndroidUtilities.dp(29), 0);
doneTextView.setText(LocaleController.getString("Done", R.string.Done).toUpperCase());
doneTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
doneTextView.setTypeface(Typeface.DEFAULT_BOLD);
frameLayout.addView(doneTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.RIGHT));
recyclerListView = new RecyclerListView(context);
@@ -2315,7 +2315,6 @@ public class PhotoFilterView extends FrameLayout {
} else if (a == 3) {
curveTextView[a].setText(LocaleController.getString("CurvesBlue", R.string.CurvesBlue).toUpperCase());
}
curveTextView[a].setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
curveTextViewContainer.addView(curveTextView[a], LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, 28, a == 0 ? 0 : 30, 0, 0, 0));
curveTextView[a].setOnClickListener(new OnClickListener() {
@Override
@@ -2341,7 +2340,6 @@ public class PhotoFilterView extends FrameLayout {
tintShadowsButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
tintShadowsButton.setGravity(Gravity.CENTER_VERTICAL);
tintShadowsButton.setText(LocaleController.getString("TintShadows", R.string.TintShadows).toUpperCase());
tintShadowsButton.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
tintTextViewContainer.addView(tintShadowsButton, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, 28));
tintShadowsButton.setOnClickListener(new OnClickListener() {
@Override
@@ -2355,7 +2353,6 @@ public class PhotoFilterView extends FrameLayout {
tintHighlightsButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
tintHighlightsButton.setGravity(Gravity.CENTER_VERTICAL);
tintHighlightsButton.setText(LocaleController.getString("TintHighlights", R.string.TintHighlights).toUpperCase());
tintHighlightsButton.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
tintTextViewContainer.addView(tintHighlightsButton, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, 28, 100, 0, 0, 0));
tintHighlightsButton.setOnClickListener(new OnClickListener() {
@Override
@@ -24,6 +24,7 @@
package com.b44t.ui.Components;
import android.content.Context;
import android.graphics.Typeface;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
@@ -62,7 +63,6 @@ public class PickerBottomLayout extends FrameLayout {
cancelButton.setBackgroundDrawable(Theme.createBarSelectorDrawable(isDarkTheme ? Theme.ACTION_BAR_PICKER_SELECTOR_COLOR : Theme.ACTION_BAR_AUDIO_SELECTOR_COLOR, false));
cancelButton.setPadding(AndroidUtilities.dp(29), 0, AndroidUtilities.dp(29), 0);
cancelButton.setText(LocaleController.getString("Cancel", R.string.Cancel).toUpperCase());
cancelButton.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
addView(cancelButton, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT));
doneButton = new LinearLayout(context);
@@ -72,7 +72,6 @@ public class PickerBottomLayout extends FrameLayout {
addView(doneButton, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.RIGHT));
doneButtonBadgeTextView = new TextView(context);
doneButtonBadgeTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
doneButtonBadgeTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13);
doneButtonBadgeTextView.setTextColor(0xffffffff);
doneButtonBadgeTextView.setGravity(Gravity.CENTER);
@@ -87,7 +86,7 @@ public class PickerBottomLayout extends FrameLayout {
doneButtonTextView.setGravity(Gravity.CENTER);
doneButtonTextView.setCompoundDrawablePadding(AndroidUtilities.dp(8));
doneButtonTextView.setText(LocaleController.getString("Send", R.string.Send).toUpperCase());
doneButtonTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
doneButtonTextView.setTypeface(Typeface.DEFAULT_BOLD);
doneButton.addView(doneButtonTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_VERTICAL));
}
@@ -1,275 +0,0 @@
/*******************************************************************************
*
* Messenger Android Frontend
* (C) 2013-2016 Nikolai Kudashov
* (C) 2017 Björn Petersen
* Contact: r10s@b44t.com, http://b44t.com
*
* This program 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.
*
* This program 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
* this program. If not, see http://www.gnu.org/licenses/ .
*
******************************************************************************/
package com.b44t.ui.Components;
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import com.b44t.messenger.AndroidUtilities;
import com.b44t.messenger.AnimatorListenerAdapterProxy;
import com.b44t.messenger.MediaController;
import com.b44t.messenger.MessageObject;
import com.b44t.messenger.NotificationCenter;
import com.b44t.messenger.R;
import com.b44t.ui.ActionBar.BaseFragment;
import com.b44t.ui.ActionBar.Theme;
import com.b44t.ui.AudioPlayerActivity;
public class PlayerView extends FrameLayout implements NotificationCenter.NotificationCenterDelegate {
private ImageView playButton;
private TextView titleTextView;
private MessageObject lastMessageObject;
private AnimatorSet animatorSet;
private float yPosition;
private BaseFragment fragment;
private float topPadding;
private boolean visible;
public PlayerView(Context context, BaseFragment parentFragment) {
super(context);
fragment = parentFragment;
visible = true;
((ViewGroup) fragment.getFragmentView()).setClipToPadding(false);
setTag(1);
FrameLayout frameLayout = new FrameLayout(context);
frameLayout.setBackgroundColor(Theme.INAPP_PLAYER_BACKGROUND_COLOR);
addView(frameLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 36, Gravity.TOP | Gravity.LEFT, 0, 0, 0, 0));
View shadow = new View(context);
shadow.setBackgroundResource(R.drawable.header_shadow);
addView(shadow, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 3, Gravity.LEFT | Gravity.TOP, 0, 36, 0, 0));
playButton = new ImageView(context);
playButton.setScaleType(ImageView.ScaleType.CENTER);
addView(playButton, LayoutHelper.createFrame(36, 36, Gravity.TOP | Gravity.LEFT, 0, 0, 0, 0));
playButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (MediaController.getInstance().isAudioPaused()) {
MediaController.getInstance().playAudio(MediaController.getInstance().getPlayingMessageObject());
} else {
MediaController.getInstance().pauseAudio(MediaController.getInstance().getPlayingMessageObject());
}
}
});
titleTextView = new TextView(context);
titleTextView.setTextColor(Theme.INAPP_PLAYER_TITLE_TEXT_COLOR);
titleTextView.setMaxLines(1);
titleTextView.setLines(1);
titleTextView.setSingleLine(true);
titleTextView.setEllipsize(TextUtils.TruncateAt.END);
titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
titleTextView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
addView(titleTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 36, Gravity.LEFT | Gravity.TOP, 35, 0, 36, 0));
ImageView closeButton = new ImageView(context);
closeButton.setImageResource(R.drawable.miniplayer_close);
closeButton.setScaleType(ImageView.ScaleType.CENTER);
addView(closeButton, LayoutHelper.createFrame(36, 36, Gravity.RIGHT | Gravity.TOP));
closeButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
MediaController.getInstance().cleanupPlayer(true, true);
}
});
setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MessageObject messageObject = MediaController.getInstance().getPlayingMessageObject();
if (messageObject != null && messageObject.isMusic() && fragment != null) {
fragment.presentFragment(new AudioPlayerActivity());
}
}
});
}
public float getTopPadding() {
return topPadding;
}
public void setTopPadding(float value) {
topPadding = value;
if (fragment != null) {
View view = fragment.getFragmentView();
if (view != null) {
view.setPadding(0, (int) topPadding, 0, 0);
}
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
topPadding = 0;
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.audioDidReset);
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.audioPlayStateChanged);
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.audioDidStarted);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
NotificationCenter.getInstance().addObserver(this, NotificationCenter.audioDidReset);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.audioPlayStateChanged);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.audioDidStarted);
checkPlayer(true);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, AndroidUtilities.dp(39));
}
@Override
public void didReceivedNotification(int id, Object... args) {
if (id == NotificationCenter.audioDidStarted || id == NotificationCenter.audioPlayStateChanged || id == NotificationCenter.audioDidReset) {
checkPlayer(false);
}
}
private void checkPlayer(boolean create) {
MessageObject messageObject = MediaController.getInstance().getPlayingMessageObject();
View fragmentView = fragment.getFragmentView();
if (!create && fragmentView != null) {
if (fragmentView.getParent() == null || ((View) fragmentView.getParent()).getVisibility() != VISIBLE) {
create = true;
}
}
if (messageObject == null || messageObject.getId() == 0/* || !messageObject.isMusic()*/) {
lastMessageObject = null;
if (visible) {
visible = false;
if (create) {
if (getVisibility() != GONE) {
setVisibility(GONE);
}
setTopPadding(0);
} else {
if (animatorSet != null) {
animatorSet.cancel();
animatorSet = null;
}
animatorSet = new AnimatorSet();
animatorSet.playTogether(ObjectAnimator.ofFloat(this, "translationY", -AndroidUtilities.dp(36)),
ObjectAnimator.ofFloat(this, "topPadding", 0));
animatorSet.setDuration(200);
animatorSet.addListener(new AnimatorListenerAdapterProxy() {
@Override
public void onAnimationEnd(Animator animation) {
if (animatorSet != null && animatorSet.equals(animation)) {
setVisibility(GONE);
animatorSet = null;
}
}
});
animatorSet.start();
}
}
} else {
if (create && topPadding == 0) {
setTopPadding(AndroidUtilities.dp(36));
setTranslationY(0);
yPosition = 0;
}
if (!visible) {
if (!create) {
if (animatorSet != null) {
animatorSet.cancel();
animatorSet = null;
}
animatorSet = new AnimatorSet();
animatorSet.playTogether(ObjectAnimator.ofFloat(this, "translationY", -AndroidUtilities.dp(36), 0),
ObjectAnimator.ofFloat(this, "topPadding", AndroidUtilities.dp(36)));
animatorSet.setDuration(200);
animatorSet.addListener(new AnimatorListenerAdapterProxy() {
@Override
public void onAnimationEnd(Animator animation) {
if (animatorSet != null && animatorSet.equals(animation)) {
animatorSet = null;
}
}
});
animatorSet.start();
}
visible = true;
setVisibility(VISIBLE);
}
if (MediaController.getInstance().isAudioPaused()) {
playButton.setImageResource(R.drawable.miniplayer_play);
} else {
playButton.setImageResource(R.drawable.miniplayer_pause);
}
if (lastMessageObject != messageObject) {
lastMessageObject = messageObject;
SpannableStringBuilder stringBuilder;
if (lastMessageObject.isVoice()) {
stringBuilder = new SpannableStringBuilder(String.format("%s %s", messageObject.getMusicAuthor(), messageObject.getMusicTitle()));
titleTextView.setEllipsize(TextUtils.TruncateAt.MIDDLE);
} else {
stringBuilder = new SpannableStringBuilder(String.format("%s - %s", messageObject.getMusicAuthor(), messageObject.getMusicTitle()));
titleTextView.setEllipsize(TextUtils.TruncateAt.END);
}
TypefaceSpan span = new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf"), 0, Theme.INAPP_PLAYER_PERFORMER_TEXT_COLOR);
stringBuilder.setSpan(span, 0, messageObject.getMusicAuthor().length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
titleTextView.setText(stringBuilder);
}
}
}
@Override
public void setTranslationY(float translationY) {
super.setTranslationY(translationY);
yPosition = translationY;
invalidate();
}
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
int restoreToCount = canvas.save();
if (yPosition < 0) {
canvas.clipRect(0, (int) -yPosition, child.getMeasuredWidth(), AndroidUtilities.dp(39));
}
final boolean result = super.drawChild(canvas, child, drawingTime);
canvas.restoreToCount(restoreToCount);
return result;
}
}
@@ -30,7 +30,6 @@ import android.view.MotionEvent;
import android.view.View;
import com.b44t.messenger.AndroidUtilities;
import com.b44t.messenger.MessageObject;
public class SeekBarWaveform {
@@ -45,13 +44,10 @@ public class SeekBarWaveform {
private int height;
private SeekBar.SeekBarDelegate delegate;
private byte[] waveformBytes;
private MessageObject messageObject;
private View parentView;
private boolean selected;
private int innerColor;
private int outerColor;
private int selectedColor;
public SeekBarWaveform(Context context) {
if (paintInner == null) {
@@ -64,24 +60,15 @@ public class SeekBarWaveform {
delegate = seekBarDelegate;
}
public void setColors(int inner, int outer, int selected) {
public void setColors(int inner, int outer) {
innerColor = inner;
outerColor = outer;
selectedColor = selected;
}
public void setWaveform(byte[] waveform) {
waveformBytes = waveform;
}
public void setSelected(boolean value) {
selected = value;
}
public void setMessageObject(MessageObject object) {
messageObject = object;
}
public void setParentView(View view) {
parentView = view;
}
@@ -162,7 +149,7 @@ public class SeekBarWaveform {
float barCounter = 0;
int nextBarNum = 0;
paintInner.setColor(messageObject != null && !messageObject.isOutOwner() && messageObject.isContentUnread() && messageObject.messageOwner.to_id.channel_id == 0 ? outerColor : (selected ? selectedColor : innerColor));
paintInner.setColor(innerColor);
paintOuter.setColor(outerColor);
int y = (height - AndroidUtilities.dp(14)) / 2;
@@ -45,6 +45,7 @@ import android.widget.TextView;
import com.b44t.messenger.AndroidUtilities;
import com.b44t.messenger.AnimatorListenerAdapterProxy;
import com.b44t.messenger.ApplicationLoader;
import com.b44t.messenger.Emoji;
import com.b44t.messenger.LocaleController;
import com.b44t.messenger.NotificationCenter;
@@ -167,7 +168,6 @@ public class StickersAlert extends BottomSheet implements NotificationCenter.Not
titleTextView.setEllipsize(TextUtils.TruncateAt.MIDDLE);
titleTextView.setPadding(AndroidUtilities.dp(18), 0, AndroidUtilities.dp(18), 0);
titleTextView.setGravity(Gravity.CENTER_VERTICAL);
titleTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
containerView.addView(titleTextView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48));
titleTextView.setOnTouchListener(new View.OnTouchListener() {
@Override
@@ -326,7 +326,6 @@ public class StickersAlert extends BottomSheet implements NotificationCenter.Not
previewSendButton.setBackgroundColor(0xffffffff);
previewSendButton.setPadding(AndroidUtilities.dp(29), 0, AndroidUtilities.dp(29), 0);
previewSendButton.setText(LocaleController.getString("Close", R.string.Close).toUpperCase());
previewSendButton.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
previewSendButton.setVisibility(View.GONE);
stickerPreviewLayout.addView(previewSendButton, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.BOTTOM | Gravity.LEFT));
previewSendButton.setOnClickListener(new View.OnClickListener() {
@@ -343,7 +342,7 @@ public class StickersAlert extends BottomSheet implements NotificationCenter.Not
stickerPreviewLayout.addView(previewSendButtonShadow, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 3, Gravity.BOTTOM | Gravity.LEFT, 0, 0, 0, 48));
if (delegate != null) {
previewSendButton.setText(LocaleController.getString("SendSticker", R.string.SendSticker).toUpperCase());
previewSendButton.setText(ApplicationLoader.applicationContext.getString(R.string.Send).toUpperCase());
stickerImageView.setLayoutParams(LayoutHelper.createFrame(size, size, Gravity.CENTER, 0, 0, 0, 30));
previewSendButton.setVisibility(View.VISIBLE);
previewSendButtonShadow.setVisibility(View.VISIBLE);
@@ -1,39 +0,0 @@
/*******************************************************************************
*
* Messenger Android Frontend
* (C) 2013-2016 Nikolai Kudashov
* (C) 2017 Björn Petersen
* Contact: r10s@b44t.com, http://b44t.com
*
* This program 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.
*
* This program 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
* this program. If not, see http://www.gnu.org/licenses/ .
*
******************************************************************************/
package com.b44t.ui.Components;
import android.text.TextPaint;
import android.text.style.URLSpan;
public class URLSpanNoUnderline extends URLSpan {
public URLSpanNoUnderline(String url) {
super(url);
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
}
}
@@ -1,41 +0,0 @@
/*******************************************************************************
*
* Messenger Android Frontend
* (C) 2013-2016 Nikolai Kudashov
* (C) 2017 Björn Petersen
* Contact: r10s@b44t.com, http://b44t.com
*
* This program 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.
*
* This program 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
* this program. If not, see http://www.gnu.org/licenses/ .
*
******************************************************************************/
package com.b44t.ui.Components;
import android.text.TextPaint;
import com.b44t.messenger.AndroidUtilities;
public class URLSpanNoUnderlineBold extends URLSpanNoUnderline {
public URLSpanNoUnderlineBold(String url) {
super(url);
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
ds.setUnderlineText(false);
}
}
@@ -1,32 +0,0 @@
/*******************************************************************************
*
* Messenger Android Frontend
* (C) 2013-2016 Nikolai Kudashov
* (C) 2017 Björn Petersen
* Contact: r10s@b44t.com, http://b44t.com
*
* This program 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.
*
* This program 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
* this program. If not, see http://www.gnu.org/licenses/ .
*
******************************************************************************/
package com.b44t.ui.Components;
import android.text.style.URLSpan;
public class URLSpanReplacement extends URLSpan {
public URLSpanReplacement(String url) {
super(url);
}
}
@@ -37,7 +37,7 @@ import com.b44t.messenger.R;
public class VideoSeekBarView extends View {
private static Drawable thumbDrawable1;
private static Paint innerPaint1 = new Paint();
//private static Paint innerPaint1 = new Paint();
private static int thumbWidth;
private static int thumbHeight;
private int thumbDX = 0;
@@ -52,7 +52,7 @@ public class VideoSeekBarView extends View {
private void init(Context context) {
if (thumbDrawable1 == null) {
thumbDrawable1 = context.getResources().getDrawable(R.drawable.videolapse);
innerPaint1.setColor(0x99999999);
//innerPaint1.setColor(0x99999999);
thumbWidth = thumbDrawable1.getIntrinsicWidth();
thumbHeight = thumbDrawable1.getIntrinsicHeight();
}
@@ -133,7 +133,7 @@ public class VideoSeekBarView extends View {
protected void onDraw(Canvas canvas) {
int y = (getMeasuredHeight() - thumbHeight) / 2;
int thumbX = (int)((getMeasuredWidth() - thumbWidth) * progress);
canvas.drawRect(thumbWidth / 2, getMeasuredHeight() / 2 - AndroidUtilities.dp(1), getMeasuredWidth() - thumbWidth / 2, getMeasuredHeight() / 2 + AndroidUtilities.dp(1), innerPaint1);
//canvas.drawRect(thumbWidth / 2, getMeasuredHeight() / 2 - AndroidUtilities.dp(1), getMeasuredWidth() - thumbWidth / 2, getMeasuredHeight() / 2 + AndroidUtilities.dp(1), innerPaint1);
thumbDrawable1.setBounds(thumbX, y, thumbX + thumbWidth, y + thumbHeight);
thumbDrawable1.draw(canvas);
}
@@ -113,7 +113,7 @@ public class ContactAddActivity extends BaseFragment implements NotificationCent
@Override
public View createView(Context context) {
actionBar.setBackButtonImage(R.drawable.ic_ab_back);
actionBar.setBackButtonImage(R.drawable.ic_close_white);
actionBar.setAllowOverlayTitle(true);
if (do_what==CREATE_CONTACT) {
actionBar.setTitle(LocaleController.getString("NewContactTitle", R.string.NewContactTitle));
@@ -99,6 +99,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
public final static int SELECT_CONTACTS_FOR_NEW_GROUP = 2;
public final static int ADD_CONTACTS_TO_GROUP = 3;
public final static int SELECT_CONTACT_TO_BLOCK = 4;
public final static int SELECT_CONTACT_TO_ATTACH = 5;
private ContactsActivityDelegate delegate;
@@ -146,6 +147,10 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
{
title = LocaleController.getString("BlockContact", R.string.BlockContact);
}
else if( do_what == SELECT_CONTACT_TO_ATTACH )
{
title = ApplicationLoader.applicationContext.getString(R.string.SelectContact);
}
return true;
}
@@ -175,12 +180,12 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
}
// initialize action
actionBar.setBackButtonImage(R.drawable.ic_ab_back);
actionBar.setBackButtonImage(do_what == SELECT_CONTACTS_FOR_NEW_GROUP? R.drawable.ic_close_white : R.drawable.ic_ab_back);
actionBar.setAllowOverlayTitle(true);
if( title != null ) {
actionBar.setTitle(title);
if( subtitle != null ) {
actionBar.setSubtitle(do_sync_now? LocaleController.getString("OneMomentPlease", R.string.OneMomentPlease) : subtitle);
actionBar.setSubtitle(do_sync_now? ApplicationLoader.applicationContext.getString(R.string.OneMoment) : subtitle);
}
}
@@ -251,7 +256,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
ActionBarMenu menu = actionBar.createMenu();
if( do_what == SELECT_CONTACTS_FOR_NEW_GROUP ) {
menu.addItem(id_done_button, R.drawable.ic_done);
menu.addItem(id_done_button, R.drawable.ic_done); // should the "done" button be right or left of other buttons? Esp. for the "more" button, it looks better if it is right left of it - beside the title describing the action and nearer to "cancel"; the other buttons has not so much to do with the group but switches to other types. In other situations, the icon-oder-decision may be different.
}
ActionBarMenuItem item = menu.addItem(10, R.drawable.ic_ab_other);
@@ -260,6 +265,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
}
item.addSubItem(id_add_contact, LocaleController.getString("NewContactTitle", R.string.NewContactTitle), 0);
listViewAdapter = new ContactsAdapter(context);
listViewAdapter.setCheckedMap(selectedContacts);
@@ -290,7 +296,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
AndroidUtilities.clearCursorDrawable(userSelectEditText);
frameLayout.addView(userSelectEditText, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.LEFT, 10, 0, 10, 0));
userSelectEditText.setHint(LocaleController.getString("SeachUser", R.string.SeachUser));
userSelectEditText.setHint(ApplicationLoader.applicationContext.getString(R.string.Search));
userSelectEditText.setTextIsSelectable(false);
userSelectEditText.addTextChangedListener(new TextWatcher() {
@Override
@@ -43,6 +43,7 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.ViewOutlineProvider;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.EditText;
import android.widget.FrameLayout;
@@ -57,6 +58,7 @@ import com.b44t.messenger.LocaleController;
import com.b44t.messenger.MrChat;
import com.b44t.messenger.MrMailbox;
import com.b44t.messenger.MrMsg;
import com.b44t.messenger.Utilities;
import com.b44t.messenger.support.widget.LinearLayoutManager;
import com.b44t.messenger.support.widget.RecyclerView;
import com.b44t.messenger.FileLog;
@@ -66,7 +68,6 @@ import com.b44t.messenger.R;
import com.b44t.messenger.UserConfig;
import com.b44t.ui.Adapters.DialogsAdapter;
import com.b44t.ui.Adapters.DialogsSearchAdapter;
import com.b44t.ui.Cells.ProfileSearchCell;
import com.b44t.ui.Cells.UserCell;
import com.b44t.ui.Cells.DialogCell;
import com.b44t.ui.ActionBar.ActionBar;
@@ -74,7 +75,6 @@ import com.b44t.ui.ActionBar.ActionBarMenu;
import com.b44t.ui.ActionBar.ActionBarMenuItem;
import com.b44t.ui.ActionBar.BaseFragment;
import com.b44t.ui.ActionBar.MenuDrawable;
import com.b44t.ui.Components.PlayerView;
import com.b44t.ui.Components.EmptyTextProgressView;
import com.b44t.ui.Components.LayoutHelper;
import com.b44t.ui.Components.RecyclerListView;
@@ -119,6 +119,8 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
private DialogsActivityDelegate delegate;
private static final int ID_LOCK_APP = 1;
public interface DialogsActivityDelegate {
void didSelectDialog(DialogsActivity fragment, long dialog_id, boolean param);
}
@@ -148,7 +150,6 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
NotificationCenter.getInstance().addObserver(this, NotificationCenter.notificationsSettingsUpdated);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.messageSendError);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.didSetPasscode);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.reloadHints);
if (!dialogsLoaded) {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload); // this is the rest of the first call to the removed MessagesController.loadDialogs(); not sure, if this is really needed
@@ -169,7 +170,6 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.notificationsSettingsUpdated);
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.messageSendError);
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.didSetPasscode);
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.reloadHints);
delegate = null;
}
@@ -188,7 +188,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
ActionBarMenu menu = actionBar.createMenu();
if (!onlySelect ) {
passcodeItem = menu.addItem(1, R.drawable.lock_close);
passcodeItem = menu.addItem(ID_LOCK_APP, R.drawable.lock_close);
updatePasscodeButton();
}
final ActionBarMenuItem item = menu.addItem(0, R.drawable.ic_ab_search).setIsSearchField(true, true).setActionBarMenuItemSearchListener(new ActionBarMenuItem.ActionBarMenuItemSearchListener() {
@@ -274,10 +274,32 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
} else if (parentLayout != null) {
parentLayout.getDrawerLayoutContainer().openDrawer(false);
}
} else if (id == 1) {
} else if (id == ID_LOCK_APP) {
listView.setVisibility(View.INVISIBLE);
UserConfig.appLocked = !UserConfig.appLocked;
UserConfig.saveConfig(false);
updatePasscodeButton();
if( UserConfig.appLocked )
{
// hide list as it is visible in the "last app switcher" otherwise, save state
updatePasscodeButton();
// finish the activity after a little delay; 200 ms shoud be enough to
// let the system update its screenshots for the "last app switcher".
// FLAG_SECURE may be a little too much as it affects display and screenshots;
// it also does not really direct this problem.
Utilities.searchQueue.postRunnable(new Runnable() {
@Override
public void run() {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
getParentActivity().finish();
}
});
}
}, 200);
}
}
}
});
@@ -481,10 +503,6 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
searchEmptyView.setVisibility(View.GONE);
listView.setEmptyView(emptyView);
if (!onlySelect ) {
frameLayout.addView(new PlayerView(context, this), LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 39, Gravity.TOP | Gravity.LEFT, 0, -36, 0, 0));
}
return fragmentView;
}
@@ -517,8 +535,8 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
ArrayList<String> permissons = new ArrayList<>();
if (activity.checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
permissons.add(Manifest.permission.READ_CONTACTS);
permissons.add(Manifest.permission.WRITE_CONTACTS);
permissons.add(Manifest.permission.GET_ACCOUNTS);
//permissons.add(Manifest.permission.WRITE_CONTACTS);
//permissons.add(Manifest.permission.GET_ACCOUNTS);
}
if (activity.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
permissons.add(Manifest.permission.READ_EXTERNAL_STORAGE);
@@ -636,10 +654,6 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
updateVisibleRows(MessagesController.UPDATE_MASK_SEND_STATE);
} else if (id == NotificationCenter.didSetPasscode) {
updatePasscodeButton();
} else if (id == NotificationCenter.reloadHints) {
if (dialogsSearchAdapter != null) {
dialogsSearchAdapter.notifyDataSetChanged();
}
}
}
@@ -695,18 +709,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
}
} else if (child instanceof UserCell) {
((UserCell) child).update(mask);
} else if (child instanceof ProfileSearchCell) {
((ProfileSearchCell) child).update(mask);
} /*else if (child instanceof RecyclerListView) {
RecyclerListView innerListView = (RecyclerListView) child;
int count2 = innerListView.getChildCount();
for (int b = 0; b < count2; b++) {
View child2 = innerListView.getChildAt(b);
if (child2 instanceof HintDialogCell) {
((HintDialogCell) child2).checkUnreadCounter(mask);
}
}
}*/
}
}
}
@@ -27,7 +27,6 @@ import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -85,7 +84,6 @@ public class DocumentSelectActivity extends BaseFragment {
private ArrayList<ListItem> items = new ArrayList<>();
private boolean receiverRegistered = false;
private ArrayList<HistoryEntry> history = new ArrayList<>();
private long sizeLimit = 1024 * 1024 * 1536;
private DocumentSelectActivityDelegate delegate;
private HashMap<String, ListItem> selectedFiles = new HashMap<>();
private ArrayList<View> actionModeViews = new ArrayList<>();
@@ -192,7 +190,6 @@ public class DocumentSelectActivity extends BaseFragment {
selectedMessagesCountTextView = new NumberTextView(actionMode.getContext());
selectedMessagesCountTextView.setTextSize(18);
selectedMessagesCountTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
selectedMessagesCountTextView.setTextColor(0xff737373);
selectedMessagesCountTextView.setOnTouchListener(new View.OnTouchListener() {
@Override
@@ -239,15 +236,9 @@ public class DocumentSelectActivity extends BaseFragment {
File file = item.file;
if (file != null && !file.isDirectory()) {
if (!file.canRead()) {
showErrorBox(LocaleController.getString("AccessError", R.string.AccessError));
showErrorBox(ApplicationLoader.applicationContext.getString(R.string.AccessError));
return false;
}
if (sizeLimit != 0) {
if (file.length() > sizeLimit) {
showErrorBox(LocaleController.formatString("FileUploadLimit", R.string.FileUploadLimit, AndroidUtilities.formatFileSize(sizeLimit)));
return false;
}
}
if (file.length() == 0) {
return false;
}
@@ -312,15 +303,9 @@ public class DocumentSelectActivity extends BaseFragment {
listView.setSelection(0);
} else {
if (!file.canRead()) {
showErrorBox(LocaleController.getString("AccessError", R.string.AccessError));
showErrorBox(ApplicationLoader.applicationContext.getString(R.string.AccessError));
file = new File("/mnt/sdcard");
}
if (sizeLimit != 0) {
if (file.length() > sizeLimit) {
showErrorBox(LocaleController.formatString("FileUploadLimit", R.string.FileUploadLimit, AndroidUtilities.formatFileSize(sizeLimit)));
return;
}
}
if (file.length() == 0) {
return;
}
@@ -432,7 +417,7 @@ public class DocumentSelectActivity extends BaseFragment {
return true;
}
}
showErrorBox(LocaleController.getString("AccessError", R.string.AccessError));
showErrorBox(ApplicationLoader.applicationContext.getString(R.string.AccessError));
return false;
}
emptyView.setText(LocaleController.getString("NoFiles", R.string.NoFiles));
@@ -444,7 +429,7 @@ public class DocumentSelectActivity extends BaseFragment {
return false;
}
if (files == null) {
showErrorBox(LocaleController.getString("UnknownError", R.string.UnknownError));
showErrorBox(ApplicationLoader.applicationContext.getString(R.string.ErrorHint));
return false;
}
currentDir = dir;
@@ -512,10 +497,7 @@ public class DocumentSelectActivity extends BaseFragment {
}
private void showErrorBox(String error) {
if (getParentActivity() == null) {
return;
}
new AlertDialog.Builder(getParentActivity()).setTitle(LocaleController.getString("AppName", R.string.AppName)).setMessage(error).setPositiveButton(LocaleController.getString("OK", R.string.OK), null).show();
AndroidUtilities.showHint(getParentActivity(), error);
}
@SuppressLint("NewApi")
@@ -525,7 +507,6 @@ public class DocumentSelectActivity extends BaseFragment {
HashSet<String> paths = new HashSet<>();
String defaultPath = Environment.getExternalStorageDirectory().getPath();
boolean isDefaultPathRemovable = Environment.isExternalStorageRemovable();
String defaultPathState = Environment.getExternalStorageState();
if (defaultPathState.equals(Environment.MEDIA_MOUNTED) || defaultPathState.equals(Environment.MEDIA_MOUNTED_READ_ONLY)) {
ListItem ext = new ListItem();
@@ -115,7 +115,7 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati
@Override
public View createView(Context context) {
actionBar.setBackButtonImage(R.drawable.ic_ab_back);
actionBar.setBackButtonImage(R.drawable.ic_close_white);
actionBar.setAllowOverlayTitle(true);
actionBar.setTitle(LocaleController.getString("NewGroup", R.string.NewGroup));
actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() {

Some files were not shown because too many files have changed in this diff Show More