├── libs ├── crashlytics.jar ├── gson-2.2.2.jar ├── jsoup-1.7.3.jar ├── databaseutils.jar ├── android-support-v4.jar └── commons-lang3-3.1.jar ├── assets └── fonts │ ├── Roboto-Bold.ttf │ ├── Roboto-Italic.ttf │ ├── Roboto-Light.ttf │ ├── Roboto-Thin.ttf │ ├── Roboto-Regular.ttf │ ├── Roboto-BoldItalic.ttf │ ├── Roboto-LightItalic.ttf │ ├── Roboto-ThinItalic.ttf │ ├── RobotoCondensed-Bold.ttf │ ├── RobotoCondensed-Italic.ttf │ ├── RobotoCondensed-Regular.ttf │ └── RobotoCondensed-BoldItalic.ttf ├── res ├── drawable-xhdpi │ ├── img_matt.jpg │ ├── ic_btn_email.png │ ├── ic_ctrl_user.png │ ├── ic_ctrl_web.png │ ├── ic_day_mode.png │ ├── ic_launcher.png │ ├── ic_side_user.png │ ├── ic_action_send.png │ ├── ic_action_web.png │ ├── ic_btn_github.png │ ├── ic_btn_website.png │ ├── ic_ctrl_reply.png │ ├── ic_ctrl_share.png │ ├── ic_ctrl_upvote.png │ ├── ic_night_mode.png │ ├── ic_side_about.png │ ├── ic_side_login.png │ ├── ic_side_submit.png │ ├── ic_text_bigger.png │ ├── bg_dark_precomp.png │ ├── bg_light_precomp.png │ ├── chkbox_chkd_dark.png │ ├── ic_action_article.png │ ├── ic_action_cancel.png │ ├── ic_action_comment.png │ ├── ic_action_login.png │ ├── ic_action_refresh.png │ ├── ic_action_search.png │ ├── ic_action_share.png │ ├── ic_actionup_back.png │ ├── ic_actionup_list.png │ ├── ic_btn_play_store.png │ ├── ic_comment_small.png │ ├── ic_ctrl_comment.png │ ├── ic_side_settings.png │ ├── ic_text_smaller.png │ ├── ic_upvote_comment.png │ ├── ic_upvote_story.png │ ├── img_saturn_light.png │ ├── logo_about_black.png │ ├── logo_about_white.png │ ├── chkbox_default_dark.png │ ├── ic_action_download.png │ ├── ic_action_overflow.png │ ├── btn_radio_on_holo_dark.png │ ├── ic_commentheader_reply.png │ ├── ic_commentheader_share.png │ ├── ic_commentheader_user.png │ ├── spinner_default_dark.9.png │ ├── spinner_focused_dark.9.png │ ├── spinner_pressed_dark.9.png │ ├── bg_textbox_about_dark.9.png │ ├── bg_textbox_about_light.9.png │ ├── btn_radio_off_holo_dark.png │ ├── btn_radio_off_holo_light.png │ ├── btn_radio_on_holo_light.png │ ├── ic_action_refresh_error.png │ ├── spinner_default_light.9.png │ ├── spinner_disabled_dark.9.png │ ├── spinner_disabled_light.9.png │ ├── spinner_focused_light.9.png │ ├── spinner_pressed_light.9.png │ ├── bg_story_upvote_indicator.9.png │ ├── spinner_default_holo_dark.9.png │ ├── spinner_focused_holo_dark.9.png │ ├── spinner_pressed_holo_dark.9.png │ ├── fastscroll_thumb_default_holo.png │ ├── fastscroll_thumb_pressed_holo.png │ ├── spinner_disabled_holo_dark.9.png │ ├── btn_radio_off_disabled_holo_dark.png │ ├── btn_radio_off_focused_holo_dark.png │ ├── btn_radio_off_focused_holo_light.png │ ├── btn_radio_off_pressed_holo_dark.png │ ├── btn_radio_off_pressed_holo_light.png │ ├── btn_radio_on_disabled_holo_dark.png │ ├── btn_radio_on_disabled_holo_light.png │ ├── btn_radio_on_focused_holo_dark.png │ ├── btn_radio_on_focused_holo_light.png │ ├── btn_radio_on_pressed_holo_dark.png │ ├── btn_radio_on_pressed_holo_light.png │ ├── btn_radio_off_disabled_holo_light.png │ ├── btn_radio_on_disabled_focused_holo_dark.png │ ├── btn_radio_off_disabled_focused_holo_dark.png │ ├── btn_radio_off_disabled_focused_holo_light.png │ └── btn_radio_on_disabled_focused_holo_light.png ├── drawable-hdpi │ ├── ic_actionbar.png │ ├── ic_launcher.png │ ├── ic_action_search.png │ ├── logo_embossed_dark.png │ ├── ic_actionbar_pressed.png │ ├── logo_embossed_light.png │ ├── btn_radio_off_holo_dark.png │ ├── btn_radio_on_holo_dark.png │ ├── btn_radio_on_holo_light.png │ ├── spinner_default_dark.9.png │ ├── spinner_default_light.9.png │ ├── spinner_disabled_dark.9.png │ ├── spinner_focused_dark.9.png │ ├── spinner_focused_light.9.png │ ├── spinner_pressed_dark.9.png │ ├── spinner_pressed_light.9.png │ ├── btn_radio_off_holo_light.png │ ├── spinner_disabled_light.9.png │ ├── textfield_default_dark.9.png │ ├── textfield_default_light.9.png │ ├── textfield_disabled_dark.9.png │ ├── textfield_focused_dark.9.png │ ├── textfield_focused_light.9.png │ ├── bg_story_upvote_indicator.9.png │ ├── spinner_default_holo_dark.9.png │ ├── spinner_disabled_holo_dark.9.png │ ├── spinner_focused_holo_dark.9.png │ ├── spinner_pressed_holo_dark.9.png │ ├── textfield_activated_dark.9.png │ ├── textfield_activated_light.9.png │ ├── textfield_disabled_light.9.png │ ├── btn_radio_on_focused_holo_dark.png │ ├── btn_radio_on_pressed_holo_dark.png │ ├── fastscroll_thumb_default_holo.png │ ├── fastscroll_thumb_pressed_holo.png │ ├── btn_radio_off_disabled_holo_dark.png │ ├── btn_radio_off_disabled_holo_light.png │ ├── btn_radio_off_focused_holo_dark.png │ ├── btn_radio_off_focused_holo_light.png │ ├── btn_radio_off_pressed_holo_dark.png │ ├── btn_radio_off_pressed_holo_light.png │ ├── btn_radio_on_disabled_holo_dark.png │ ├── btn_radio_on_disabled_holo_light.png │ ├── btn_radio_on_focused_holo_light.png │ ├── btn_radio_on_pressed_holo_light.png │ ├── textfield_disabled_focused_dark.9.png │ ├── textfield_disabled_focused_light.9.png │ ├── btn_radio_off_disabled_focused_holo_dark.png │ ├── btn_radio_on_disabled_focused_holo_dark.png │ ├── btn_radio_on_disabled_focused_holo_light.png │ └── btn_radio_off_disabled_focused_holo_light.png ├── drawable-large-xhdpi │ ├── img_matt.jpg │ ├── logo_about_black.png │ └── logo_about_white.png ├── drawable-mdpi │ ├── btn_radio_off_holo_dark.png │ ├── btn_radio_on_holo_dark.png │ ├── btn_radio_on_holo_light.png │ ├── spinner_default_dark.9.png │ ├── spinner_default_light.9.png │ ├── spinner_disabled_dark.9.png │ ├── spinner_focused_dark.9.png │ ├── spinner_focused_light.9.png │ ├── spinner_pressed_dark.9.png │ ├── spinner_pressed_light.9.png │ ├── btn_radio_off_holo_light.png │ ├── spinner_disabled_light.9.png │ ├── bg_story_upvote_indicator.9.png │ ├── spinner_default_holo_dark.9.png │ ├── spinner_disabled_holo_dark.9.png │ ├── spinner_focused_holo_dark.9.png │ ├── spinner_pressed_holo_dark.9.png │ ├── btn_radio_on_focused_holo_dark.png │ ├── btn_radio_on_pressed_holo_dark.png │ ├── fastscroll_thumb_default_holo.png │ ├── fastscroll_thumb_pressed_holo.png │ ├── btn_radio_off_disabled_holo_dark.png │ ├── btn_radio_off_disabled_holo_light.png │ ├── btn_radio_off_focused_holo_dark.png │ ├── btn_radio_off_focused_holo_light.png │ ├── btn_radio_off_pressed_holo_dark.png │ ├── btn_radio_off_pressed_holo_light.png │ ├── btn_radio_on_disabled_holo_dark.png │ ├── btn_radio_on_disabled_holo_light.png │ ├── btn_radio_on_focused_holo_light.png │ ├── btn_radio_on_pressed_holo_light.png │ ├── btn_radio_off_disabled_focused_holo_dark.png │ ├── btn_radio_on_disabled_focused_holo_dark.png │ ├── btn_radio_on_disabled_focused_holo_light.png │ └── btn_radio_off_disabled_focused_holo_light.png ├── drawable │ ├── bg_story_upvote_indicator.9.png │ ├── bg_dark_opt.xml │ ├── bg_light_opt.xml │ ├── btn_slideout_dark.xml │ ├── btn_slideout_light.xml │ ├── btn_bright_accent.xml │ ├── btn_actionbar_overflow_custom.xml │ ├── state_color_btn_storylist_item.xml │ ├── grad_slideout_shadow.xml │ ├── state_color_link.xml │ ├── st_color_txt_disableable_dark.xml │ ├── st_color_txt_disableable_light.xml │ ├── btn_opac_10_dark.xml │ ├── btn_opac_10_light.xml │ ├── btn_story_light_simple.xml │ ├── btn_story_dark.xml │ ├── btn_story_light.xml │ ├── st_color_ic_actionbar_dark.xml │ ├── st_color_txt_slideout_dark.xml │ ├── st_color_txt_slideout_light.xml │ ├── st_ic_action_up.xml │ ├── bg_window_loading.xml │ ├── state_color_tab_text.xml │ ├── bg_slideout_header_dark.xml │ ├── bg_slideout_header_light.xml │ ├── bg_dark.xml │ ├── bg_light.xml │ ├── lyr_frg_webview_progress.xml │ ├── bg_actionbar_dark.xml │ ├── bg_actionbar_light.xml │ ├── bg_storylist_tablet_dark.xml │ ├── bg_storylist_tablet_light.xml │ ├── btn_actionbar_dark.xml │ ├── btn_actionbar_light.xml │ ├── fastscroll_thumb_holo.xml │ ├── bg_sharepopup_dark.xml │ ├── bg_sharepopup_light.xml │ ├── bg_actionbar_overflow_dark.xml │ ├── bg_actionbar_overflow_light.xml │ ├── btn_tab_light.xml │ ├── btn_tab_dark.xml │ ├── spinner_background_dark.xml │ ├── spinner_background_light.xml │ ├── btn_share_popup_dark.xml │ ├── btn_share_popup_light.xml │ ├── edit_text_dark.xml │ ├── edit_text_light.xml │ ├── btn_actionbar_tab_dark.xml │ ├── btn_actionbar_tab_light.xml │ ├── btn_radio_holo_dark.xml │ └── btn_radio_holo_light.xml ├── drawable-large-hdpi │ ├── logo_embossed_dark.png │ └── logo_embossed_light.png ├── values │ ├── ids.xml │ ├── dimens.xml │ ├── arrays.xml │ ├── colors.xml │ └── attrs.xml ├── layout │ ├── act_storylist.xml │ ├── act_comments.xml │ ├── act_sharelist.xml │ ├── stub_loading_error.xml │ ├── vw_actionbar_webfragment_title.xml │ ├── frg_webview.xml │ ├── vw_loadinglist_loading.xml │ ├── act_settings.xml │ ├── vw_tab.xml │ ├── vw_actionbar_search.xml │ ├── vw_search_noresults.xml │ ├── vw_loadinglist_empty.xml │ ├── vw_btn_sharepopup.xml │ ├── frg_comments.xml │ ├── act_search.xml │ ├── vw_invalid_story.xml │ ├── stub_loading.xml │ ├── frg_stories.xml │ ├── frg_loadinglist.xml │ ├── act_tablet.xml │ ├── vw_more_link.xml │ ├── vw_overflow_searchbox.xml │ ├── vw_loadinglist_error.xml │ ├── act_donate.xml │ ├── vw_actionbar_tabs_comments.xml │ ├── vw_comment_search.xml │ ├── vw_share_popup.xml │ ├── vw_search_header.xml │ ├── act_reply.xml │ ├── act_user.xml │ ├── act_contribute.xml │ ├── act_submit.xml │ └── vw_overflow_textsettings.xml ├── anim │ ├── ctrl_slide_down.xml │ ├── ctrl_slide_up.xml │ ├── ctrl_scale_down.xml │ └── ctrl_scale_up.xml └── layout-large │ └── act_settings.xml ├── src └── com │ ├── airlocksoftware │ └── hackernews │ │ ├── model │ │ ├── Page.java │ │ ├── ShareItem.java │ │ ├── Result.java │ │ ├── User.java │ │ ├── CommentThread.java │ │ ├── Request.java │ │ ├── NewStoryResult.java │ │ ├── Vote.java │ │ ├── StoryTimestamp.java │ │ ├── SearchItem.java │ │ └── CommentsTimestamp.java │ │ ├── interfaces │ │ ├── TabletLayout.java │ │ ├── RestartableActivity.java │ │ └── SharePopupInterface.java │ │ ├── exception │ │ ├── page │ │ │ └── NoPageException.java │ │ ├── HackerNewsException.java │ │ └── user │ │ │ └── NoUsernameException.java │ │ ├── application │ │ └── MainApplication.java │ │ ├── loader │ │ ├── AboutUserLoader.java │ │ ├── AsyncLoginUpdater.java │ │ ├── LoginLoader.java │ │ ├── ThreadsLoader.java │ │ ├── ReplyLoader.java │ │ └── AsyncVotingService.java │ │ ├── data │ │ ├── AppData.java │ │ ├── LoginManager.java │ │ └── ConnectionManager.java │ │ ├── activity │ │ ├── BackActivity.java │ │ ├── AboutActivity.java │ │ └── SettingsActivity.java │ │ ├── adapter │ │ └── ThreadsAdapter.java │ │ ├── parser │ │ └── UserParser.java │ │ ├── cache │ │ └── DbHelperSingleton.java │ │ └── view │ │ └── SearchOverflow.java │ └── android │ └── vending │ └── billing │ └── IMarketBillingService.aidl ├── project.properties ├── .gitignore ├── proguard-project.txt ├── out └── production │ └── HackerNews │ └── com │ └── android │ └── vending │ └── billing │ └── IMarketBillingService.aidl ├── AndroidManifest.xml └── README.md /libs/crashlytics.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/libs/crashlytics.jar -------------------------------------------------------------------------------- /libs/gson-2.2.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/libs/gson-2.2.2.jar -------------------------------------------------------------------------------- /libs/jsoup-1.7.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/libs/jsoup-1.7.3.jar -------------------------------------------------------------------------------- /libs/databaseutils.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/libs/databaseutils.jar -------------------------------------------------------------------------------- /libs/android-support-v4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/libs/android-support-v4.jar -------------------------------------------------------------------------------- /libs/commons-lang3-3.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/libs/commons-lang3-3.1.jar -------------------------------------------------------------------------------- /assets/fonts/Roboto-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/assets/fonts/Roboto-Bold.ttf -------------------------------------------------------------------------------- /assets/fonts/Roboto-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/assets/fonts/Roboto-Italic.ttf -------------------------------------------------------------------------------- /assets/fonts/Roboto-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/assets/fonts/Roboto-Light.ttf -------------------------------------------------------------------------------- /assets/fonts/Roboto-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/assets/fonts/Roboto-Thin.ttf -------------------------------------------------------------------------------- /assets/fonts/Roboto-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/assets/fonts/Roboto-Regular.ttf -------------------------------------------------------------------------------- /res/drawable-xhdpi/img_matt.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/img_matt.jpg -------------------------------------------------------------------------------- /assets/fonts/Roboto-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/assets/fonts/Roboto-BoldItalic.ttf -------------------------------------------------------------------------------- /assets/fonts/Roboto-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/assets/fonts/Roboto-LightItalic.ttf -------------------------------------------------------------------------------- /assets/fonts/Roboto-ThinItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/assets/fonts/Roboto-ThinItalic.ttf -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_actionbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/ic_actionbar.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_btn_email.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_btn_email.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_ctrl_user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_ctrl_user.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_ctrl_web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_ctrl_web.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_day_mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_day_mode.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_side_user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_side_user.png -------------------------------------------------------------------------------- /assets/fonts/RobotoCondensed-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/assets/fonts/RobotoCondensed-Bold.ttf -------------------------------------------------------------------------------- /res/drawable-large-xhdpi/img_matt.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-large-xhdpi/img_matt.jpg -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_action_send.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_action_send.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_action_web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_action_web.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_btn_github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_btn_github.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_btn_website.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_btn_website.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_ctrl_reply.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_ctrl_reply.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_ctrl_share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_ctrl_share.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_ctrl_upvote.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_ctrl_upvote.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_night_mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_night_mode.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_side_about.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_side_about.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_side_login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_side_login.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_side_submit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_side_submit.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_text_bigger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_text_bigger.png -------------------------------------------------------------------------------- /assets/fonts/RobotoCondensed-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/assets/fonts/RobotoCondensed-Italic.ttf -------------------------------------------------------------------------------- /assets/fonts/RobotoCondensed-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/assets/fonts/RobotoCondensed-Regular.ttf -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_action_search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/ic_action_search.png -------------------------------------------------------------------------------- /res/drawable-hdpi/logo_embossed_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/logo_embossed_dark.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/bg_dark_precomp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/bg_dark_precomp.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/bg_light_precomp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/bg_light_precomp.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/chkbox_chkd_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/chkbox_chkd_dark.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_action_article.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_action_article.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_action_cancel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_action_cancel.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_action_comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_action_comment.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_action_login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_action_login.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_action_refresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_action_refresh.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_action_search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_action_search.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_action_share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_action_share.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_actionup_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_actionup_back.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_actionup_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_actionup_list.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_btn_play_store.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_btn_play_store.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_comment_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_comment_small.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_ctrl_comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_ctrl_comment.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_side_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_side_settings.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_text_smaller.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_text_smaller.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_upvote_comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_upvote_comment.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_upvote_story.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_upvote_story.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/img_saturn_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/img_saturn_light.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/logo_about_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/logo_about_black.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/logo_about_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/logo_about_white.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_actionbar_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/ic_actionbar_pressed.png -------------------------------------------------------------------------------- /res/drawable-hdpi/logo_embossed_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/logo_embossed_light.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/chkbox_default_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/chkbox_default_dark.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_action_download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_action_download.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_action_overflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_action_overflow.png -------------------------------------------------------------------------------- /assets/fonts/RobotoCondensed-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/assets/fonts/RobotoCondensed-BoldItalic.ttf -------------------------------------------------------------------------------- /res/drawable-hdpi/btn_radio_off_holo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/btn_radio_off_holo_dark.png -------------------------------------------------------------------------------- /res/drawable-hdpi/btn_radio_on_holo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/btn_radio_on_holo_dark.png -------------------------------------------------------------------------------- /res/drawable-hdpi/btn_radio_on_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/btn_radio_on_holo_light.png -------------------------------------------------------------------------------- /res/drawable-hdpi/spinner_default_dark.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/spinner_default_dark.9.png -------------------------------------------------------------------------------- /res/drawable-hdpi/spinner_default_light.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/spinner_default_light.9.png -------------------------------------------------------------------------------- /res/drawable-hdpi/spinner_disabled_dark.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/spinner_disabled_dark.9.png -------------------------------------------------------------------------------- /res/drawable-hdpi/spinner_focused_dark.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/spinner_focused_dark.9.png -------------------------------------------------------------------------------- /res/drawable-hdpi/spinner_focused_light.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/spinner_focused_light.9.png -------------------------------------------------------------------------------- /res/drawable-hdpi/spinner_pressed_dark.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/spinner_pressed_dark.9.png -------------------------------------------------------------------------------- /res/drawable-hdpi/spinner_pressed_light.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/spinner_pressed_light.9.png -------------------------------------------------------------------------------- /res/drawable-large-xhdpi/logo_about_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-large-xhdpi/logo_about_black.png -------------------------------------------------------------------------------- /res/drawable-large-xhdpi/logo_about_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-large-xhdpi/logo_about_white.png -------------------------------------------------------------------------------- /res/drawable-mdpi/btn_radio_off_holo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/btn_radio_off_holo_dark.png -------------------------------------------------------------------------------- /res/drawable-mdpi/btn_radio_on_holo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/btn_radio_on_holo_dark.png -------------------------------------------------------------------------------- /res/drawable-mdpi/btn_radio_on_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/btn_radio_on_holo_light.png -------------------------------------------------------------------------------- /res/drawable-mdpi/spinner_default_dark.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/spinner_default_dark.9.png -------------------------------------------------------------------------------- /res/drawable-mdpi/spinner_default_light.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/spinner_default_light.9.png -------------------------------------------------------------------------------- /res/drawable-mdpi/spinner_disabled_dark.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/spinner_disabled_dark.9.png -------------------------------------------------------------------------------- /res/drawable-mdpi/spinner_focused_dark.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/spinner_focused_dark.9.png -------------------------------------------------------------------------------- /res/drawable-mdpi/spinner_focused_light.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/spinner_focused_light.9.png -------------------------------------------------------------------------------- /res/drawable-mdpi/spinner_pressed_dark.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/spinner_pressed_dark.9.png -------------------------------------------------------------------------------- /res/drawable-mdpi/spinner_pressed_light.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/spinner_pressed_light.9.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/btn_radio_on_holo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/btn_radio_on_holo_dark.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_commentheader_reply.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_commentheader_reply.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_commentheader_share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_commentheader_share.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_commentheader_user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_commentheader_user.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/spinner_default_dark.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/spinner_default_dark.9.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/spinner_focused_dark.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/spinner_focused_dark.9.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/spinner_pressed_dark.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/spinner_pressed_dark.9.png -------------------------------------------------------------------------------- /res/drawable/bg_story_upvote_indicator.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable/bg_story_upvote_indicator.9.png -------------------------------------------------------------------------------- /res/drawable-hdpi/btn_radio_off_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/btn_radio_off_holo_light.png -------------------------------------------------------------------------------- /res/drawable-hdpi/spinner_disabled_light.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/spinner_disabled_light.9.png -------------------------------------------------------------------------------- /res/drawable-hdpi/textfield_default_dark.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/textfield_default_dark.9.png -------------------------------------------------------------------------------- /res/drawable-hdpi/textfield_default_light.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/textfield_default_light.9.png -------------------------------------------------------------------------------- /res/drawable-hdpi/textfield_disabled_dark.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/textfield_disabled_dark.9.png -------------------------------------------------------------------------------- /res/drawable-hdpi/textfield_focused_dark.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/textfield_focused_dark.9.png -------------------------------------------------------------------------------- /res/drawable-hdpi/textfield_focused_light.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/textfield_focused_light.9.png -------------------------------------------------------------------------------- /res/drawable-large-hdpi/logo_embossed_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-large-hdpi/logo_embossed_dark.png -------------------------------------------------------------------------------- /res/drawable-large-hdpi/logo_embossed_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-large-hdpi/logo_embossed_light.png -------------------------------------------------------------------------------- /res/drawable-mdpi/btn_radio_off_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/btn_radio_off_holo_light.png -------------------------------------------------------------------------------- /res/drawable-mdpi/spinner_disabled_light.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/spinner_disabled_light.9.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/bg_textbox_about_dark.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/bg_textbox_about_dark.9.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/bg_textbox_about_light.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/bg_textbox_about_light.9.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/btn_radio_off_holo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/btn_radio_off_holo_dark.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/btn_radio_off_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/btn_radio_off_holo_light.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/btn_radio_on_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/btn_radio_on_holo_light.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_action_refresh_error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/ic_action_refresh_error.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/spinner_default_light.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/spinner_default_light.9.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/spinner_disabled_dark.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/spinner_disabled_dark.9.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/spinner_disabled_light.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/spinner_disabled_light.9.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/spinner_focused_light.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/spinner_focused_light.9.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/spinner_pressed_light.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/spinner_pressed_light.9.png -------------------------------------------------------------------------------- /res/drawable-hdpi/bg_story_upvote_indicator.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/bg_story_upvote_indicator.9.png -------------------------------------------------------------------------------- /res/drawable-hdpi/spinner_default_holo_dark.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/spinner_default_holo_dark.9.png -------------------------------------------------------------------------------- /res/drawable-hdpi/spinner_disabled_holo_dark.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/spinner_disabled_holo_dark.9.png -------------------------------------------------------------------------------- /res/drawable-hdpi/spinner_focused_holo_dark.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/spinner_focused_holo_dark.9.png -------------------------------------------------------------------------------- /res/drawable-hdpi/spinner_pressed_holo_dark.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/spinner_pressed_holo_dark.9.png -------------------------------------------------------------------------------- /res/drawable-hdpi/textfield_activated_dark.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/textfield_activated_dark.9.png -------------------------------------------------------------------------------- /res/drawable-hdpi/textfield_activated_light.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/textfield_activated_light.9.png -------------------------------------------------------------------------------- /res/drawable-hdpi/textfield_disabled_light.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/textfield_disabled_light.9.png -------------------------------------------------------------------------------- /res/drawable-mdpi/bg_story_upvote_indicator.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/bg_story_upvote_indicator.9.png -------------------------------------------------------------------------------- /res/drawable-mdpi/spinner_default_holo_dark.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/spinner_default_holo_dark.9.png -------------------------------------------------------------------------------- /res/drawable-mdpi/spinner_disabled_holo_dark.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/spinner_disabled_holo_dark.9.png -------------------------------------------------------------------------------- /res/drawable-mdpi/spinner_focused_holo_dark.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/spinner_focused_holo_dark.9.png -------------------------------------------------------------------------------- /res/drawable-mdpi/spinner_pressed_holo_dark.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/spinner_pressed_holo_dark.9.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/bg_story_upvote_indicator.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/bg_story_upvote_indicator.9.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/spinner_default_holo_dark.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/spinner_default_holo_dark.9.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/spinner_focused_holo_dark.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/spinner_focused_holo_dark.9.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/spinner_pressed_holo_dark.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/spinner_pressed_holo_dark.9.png -------------------------------------------------------------------------------- /res/drawable-hdpi/btn_radio_on_focused_holo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/btn_radio_on_focused_holo_dark.png -------------------------------------------------------------------------------- /res/drawable-hdpi/btn_radio_on_pressed_holo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/btn_radio_on_pressed_holo_dark.png -------------------------------------------------------------------------------- /res/drawable-hdpi/fastscroll_thumb_default_holo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/fastscroll_thumb_default_holo.png -------------------------------------------------------------------------------- /res/drawable-hdpi/fastscroll_thumb_pressed_holo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/fastscroll_thumb_pressed_holo.png -------------------------------------------------------------------------------- /res/drawable-mdpi/btn_radio_on_focused_holo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/btn_radio_on_focused_holo_dark.png -------------------------------------------------------------------------------- /res/drawable-mdpi/btn_radio_on_pressed_holo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/btn_radio_on_pressed_holo_dark.png -------------------------------------------------------------------------------- /res/drawable-mdpi/fastscroll_thumb_default_holo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/fastscroll_thumb_default_holo.png -------------------------------------------------------------------------------- /res/drawable-mdpi/fastscroll_thumb_pressed_holo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/fastscroll_thumb_pressed_holo.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/fastscroll_thumb_default_holo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/fastscroll_thumb_default_holo.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/fastscroll_thumb_pressed_holo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/fastscroll_thumb_pressed_holo.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/spinner_disabled_holo_dark.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/spinner_disabled_holo_dark.9.png -------------------------------------------------------------------------------- /res/drawable-hdpi/btn_radio_off_disabled_holo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/btn_radio_off_disabled_holo_dark.png -------------------------------------------------------------------------------- /res/drawable-hdpi/btn_radio_off_disabled_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/btn_radio_off_disabled_holo_light.png -------------------------------------------------------------------------------- /res/drawable-hdpi/btn_radio_off_focused_holo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/btn_radio_off_focused_holo_dark.png -------------------------------------------------------------------------------- /res/drawable-hdpi/btn_radio_off_focused_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/btn_radio_off_focused_holo_light.png -------------------------------------------------------------------------------- /res/drawable-hdpi/btn_radio_off_pressed_holo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/btn_radio_off_pressed_holo_dark.png -------------------------------------------------------------------------------- /res/drawable-hdpi/btn_radio_off_pressed_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/btn_radio_off_pressed_holo_light.png -------------------------------------------------------------------------------- /res/drawable-hdpi/btn_radio_on_disabled_holo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/btn_radio_on_disabled_holo_dark.png -------------------------------------------------------------------------------- /res/drawable-hdpi/btn_radio_on_disabled_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/btn_radio_on_disabled_holo_light.png -------------------------------------------------------------------------------- /res/drawable-hdpi/btn_radio_on_focused_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/btn_radio_on_focused_holo_light.png -------------------------------------------------------------------------------- /res/drawable-hdpi/btn_radio_on_pressed_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/btn_radio_on_pressed_holo_light.png -------------------------------------------------------------------------------- /res/drawable-hdpi/textfield_disabled_focused_dark.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/textfield_disabled_focused_dark.9.png -------------------------------------------------------------------------------- /res/drawable-mdpi/btn_radio_off_disabled_holo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/btn_radio_off_disabled_holo_dark.png -------------------------------------------------------------------------------- /res/drawable-mdpi/btn_radio_off_disabled_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/btn_radio_off_disabled_holo_light.png -------------------------------------------------------------------------------- /res/drawable-mdpi/btn_radio_off_focused_holo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/btn_radio_off_focused_holo_dark.png -------------------------------------------------------------------------------- /res/drawable-mdpi/btn_radio_off_focused_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/btn_radio_off_focused_holo_light.png -------------------------------------------------------------------------------- /res/drawable-mdpi/btn_radio_off_pressed_holo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/btn_radio_off_pressed_holo_dark.png -------------------------------------------------------------------------------- /res/drawable-mdpi/btn_radio_off_pressed_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/btn_radio_off_pressed_holo_light.png -------------------------------------------------------------------------------- /res/drawable-mdpi/btn_radio_on_disabled_holo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/btn_radio_on_disabled_holo_dark.png -------------------------------------------------------------------------------- /res/drawable-mdpi/btn_radio_on_disabled_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/btn_radio_on_disabled_holo_light.png -------------------------------------------------------------------------------- /res/drawable-mdpi/btn_radio_on_focused_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/btn_radio_on_focused_holo_light.png -------------------------------------------------------------------------------- /res/drawable-mdpi/btn_radio_on_pressed_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/btn_radio_on_pressed_holo_light.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/btn_radio_off_disabled_holo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/btn_radio_off_disabled_holo_dark.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/btn_radio_off_focused_holo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/btn_radio_off_focused_holo_dark.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/btn_radio_off_focused_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/btn_radio_off_focused_holo_light.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/btn_radio_off_pressed_holo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/btn_radio_off_pressed_holo_dark.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/btn_radio_off_pressed_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/btn_radio_off_pressed_holo_light.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/btn_radio_on_disabled_holo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/btn_radio_on_disabled_holo_dark.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/btn_radio_on_disabled_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/btn_radio_on_disabled_holo_light.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/btn_radio_on_focused_holo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/btn_radio_on_focused_holo_dark.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/btn_radio_on_focused_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/btn_radio_on_focused_holo_light.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/btn_radio_on_pressed_holo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/btn_radio_on_pressed_holo_dark.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/btn_radio_on_pressed_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/btn_radio_on_pressed_holo_light.png -------------------------------------------------------------------------------- /res/drawable-hdpi/textfield_disabled_focused_light.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/textfield_disabled_focused_light.9.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/btn_radio_off_disabled_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/btn_radio_off_disabled_holo_light.png -------------------------------------------------------------------------------- /res/drawable-hdpi/btn_radio_off_disabled_focused_holo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/btn_radio_off_disabled_focused_holo_dark.png -------------------------------------------------------------------------------- /res/drawable-hdpi/btn_radio_on_disabled_focused_holo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/btn_radio_on_disabled_focused_holo_dark.png -------------------------------------------------------------------------------- /res/drawable-hdpi/btn_radio_on_disabled_focused_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/btn_radio_on_disabled_focused_holo_light.png -------------------------------------------------------------------------------- /res/drawable-mdpi/btn_radio_off_disabled_focused_holo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/btn_radio_off_disabled_focused_holo_dark.png -------------------------------------------------------------------------------- /res/drawable-mdpi/btn_radio_on_disabled_focused_holo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/btn_radio_on_disabled_focused_holo_dark.png -------------------------------------------------------------------------------- /res/drawable-mdpi/btn_radio_on_disabled_focused_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/btn_radio_on_disabled_focused_holo_light.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/btn_radio_on_disabled_focused_holo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/btn_radio_on_disabled_focused_holo_dark.png -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/model/Page.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.model; 2 | 3 | public enum Page { 4 | FRONT, ASK, BEST, ACTIVE, NEW, USER; 5 | } 6 | -------------------------------------------------------------------------------- /res/drawable-hdpi/btn_radio_off_disabled_focused_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-hdpi/btn_radio_off_disabled_focused_holo_light.png -------------------------------------------------------------------------------- /res/drawable-mdpi/btn_radio_off_disabled_focused_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-mdpi/btn_radio_off_disabled_focused_holo_light.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/btn_radio_off_disabled_focused_holo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/btn_radio_off_disabled_focused_holo_dark.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/btn_radio_off_disabled_focused_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/btn_radio_off_disabled_focused_holo_light.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/btn_radio_on_disabled_focused_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xzya/HackerNews/master/res/drawable-xhdpi/btn_radio_on_disabled_focused_holo_light.png -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/model/ShareItem.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.model; 2 | 3 | public class ShareItem { 4 | public String label, subject, extraText; 5 | } -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/interfaces/TabletLayout.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.interfaces; 2 | 3 | public interface TabletLayout { 4 | 5 | public boolean isTabletLayout(); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /res/drawable/bg_dark_opt.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /res/drawable/bg_light_opt.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /res/values/ids.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /res/layout/act_storylist.xml: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /res/drawable/btn_slideout_dark.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /res/drawable/btn_slideout_light.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /res/drawable/btn_bright_accent.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/model/Result.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.model; 2 | 3 | public enum Result { 4 | SUCCESS, MORE, NO_SUCH_USER, FAILURE, 5 | /** empty indicates null data was passed to the loader**/ 6 | EMPTY, 7 | FNID_EXPIRED; 8 | } 9 | -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/interfaces/RestartableActivity.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.interfaces; 2 | 3 | /** An activity that can be restarted -- i.e. if **/ 4 | public interface RestartableActivity { 5 | 6 | public void restartActivity(); 7 | 8 | } 9 | -------------------------------------------------------------------------------- /res/drawable/btn_actionbar_overflow_custom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /res/drawable/state_color_btn_storylist_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/interfaces/SharePopupInterface.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.interfaces; 2 | 3 | import com.airlocksoftware.hackernews.view.SharePopup; 4 | 5 | public interface SharePopupInterface { 6 | 7 | public SharePopup getSharePopup(); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /res/drawable/grad_slideout_shadow.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 9 | -------------------------------------------------------------------------------- /res/layout/act_comments.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | -------------------------------------------------------------------------------- /res/layout/act_sharelist.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | -------------------------------------------------------------------------------- /res/drawable/state_color_link.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /res/drawable/st_color_txt_disableable_dark.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /res/drawable/st_color_txt_disableable_light.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /res/drawable/btn_opac_10_dark.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /res/drawable/btn_opac_10_light.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /res/layout/stub_loading_error.xml: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 60dp 4 | 65dp 5 | 60dp 6 | 7 | 8 | 260dp 9 | 10 | -------------------------------------------------------------------------------- /res/drawable/btn_story_light_simple.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /res/anim/ctrl_slide_down.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | -------------------------------------------------------------------------------- /res/anim/ctrl_slide_up.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/model/User.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.model; 2 | 3 | public class User { 4 | 5 | public String username; 6 | public String created; 7 | public int karma; 8 | public float avg; 9 | public String aboutHtml; 10 | 11 | public User() { 12 | // TODO Auto-generated constructor stub 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/model/CommentThread.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.model; 2 | 3 | import java.util.List; 4 | 5 | /** Represents a thread of comments on a user's Threads page **/ 6 | public class CommentThread { 7 | 8 | public List comments; 9 | public Story story; 10 | 11 | public CommentThread() { 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /res/anim/ctrl_scale_down.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 11 | 12 | -------------------------------------------------------------------------------- /res/drawable/btn_story_dark.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /res/drawable/btn_story_light.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /res/anim/ctrl_scale_up.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | -------------------------------------------------------------------------------- /res/drawable/st_color_ic_actionbar_dark.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /res/drawable/st_color_txt_slideout_dark.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /res/drawable/st_color_txt_slideout_light.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /res/drawable/st_ic_action_up.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /res/layout/vw_actionbar_webfragment_title.xml: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /res/drawable/bg_window_loading.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 10 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/model/Request.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.model; 2 | 3 | public enum Request { 4 | NEW, MORE, REFRESH, EMPTY; 5 | /** 6 | * When you don't have any good data to make a request on, use Request.EMPTY. All of the loaders will then return 7 | * Result.EMPTY 8 | **/ 9 | 10 | public boolean isEmpty() { 11 | return this.equals(Request.EMPTY); 12 | } 13 | 14 | public static boolean isEmpty(Request req) { 15 | return req.isEmpty(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/model/NewStoryResult.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.model; 2 | 3 | public enum NewStoryResult { 4 | SUCCESS, POST_TOO_FAST, POST_DUPLICATE, FAILURE, EMPTY; 5 | 6 | public String toString() { 7 | switch (this) { 8 | case SUCCESS: 9 | return "Success"; 10 | case POST_DUPLICATE: 11 | return "Duplicate Post"; 12 | case POST_TOO_FAST: 13 | return "Posting Too Fast"; 14 | case FAILURE: 15 | return "Failure"; 16 | default: 17 | return "Empty"; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/exception/page/NoPageException.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.exception.page; 2 | 3 | import com.airlocksoftware.hackernews.exception.HackerNewsException; 4 | 5 | /** 6 | * NoPageException :: 7 | * 8 | * Author: pkillian 9 | * Project: HackerNews2 10 | * Date: 1/11/14 11 | */ 12 | public class NoPageException extends HackerNewsException { 13 | public NoPageException() { 14 | super(); 15 | } 16 | 17 | public NoPageException(String message) { 18 | super(message); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /res/drawable/state_color_tab_text.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /res/drawable/bg_slideout_header_dark.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /res/drawable/bg_slideout_header_light.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /res/drawable/bg_dark.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /res/drawable/bg_light.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/exception/HackerNewsException.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.exception; 2 | 3 | /** 4 | * HackerNewsException :: Generic HackerNews exception class to make catching 5 | * errors easier / more concise. 6 | * 7 | * Author: pkillian 8 | * Project: HackerNews2 9 | * Date: 1/11/14 10 | */ 11 | public class HackerNewsException extends RuntimeException { 12 | protected HackerNewsException() { 13 | super(); 14 | } 15 | 16 | protected HackerNewsException(String message) { 17 | super(message); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/exception/user/NoUsernameException.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.exception.user; 2 | 3 | import com.airlocksoftware.hackernews.exception.HackerNewsException; 4 | 5 | /** 6 | * NoUsernameException :: Less crashes, more error handling from Story Loader 7 | * 8 | * Author: pkillian 9 | * Project: HackerNews2 10 | * Date: 1/11/14 11 | */ 12 | public class NoUsernameException extends HackerNewsException { 13 | public NoUsernameException() { 14 | super(); 15 | } 16 | 17 | public NoUsernameException(String message) { 18 | super(message); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /res/layout/frg_webview.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 15 | 16 | -------------------------------------------------------------------------------- /project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | # proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-21 15 | android.library.reference.1=libs/HoloTheme 16 | -------------------------------------------------------------------------------- /res/layout/vw_loadinglist_loading.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 15 | 16 | -------------------------------------------------------------------------------- /res/layout/act_settings.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 11 | 12 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /res/values/arrays.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | @color/depth_orange_light 6 | @color/depth_yellow 7 | @color/depth_orange_dark 8 | @color/depth_red 9 | @color/depth_purple 10 | 11 | 12 | @color/holo_blue_light 13 | @color/holo_blue_dark 14 | @color/holo_purple 15 | @color/holo_red_dark 16 | @color/holo_orange_dark 17 | 18 | 19 | -------------------------------------------------------------------------------- /res/layout/vw_tab.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 15 | 16 | -------------------------------------------------------------------------------- /res/layout/vw_actionbar_search.xml: -------------------------------------------------------------------------------- 1 | 16 | -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/application/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.application; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | 6 | /** 7 | * MainApplication :: Main Application class for interacting 8 | * with application outside of activities; helpful for getting 9 | * shared preferences outside of context scope, i.e. ConnectionManager 10 | */ 11 | public class MainApplication extends Application { 12 | private static MainApplication mInstance; 13 | 14 | @Override 15 | public void onCreate() { 16 | super.onCreate(); 17 | mInstance = this; 18 | } 19 | 20 | public static MainApplication getInstance() { 21 | return mInstance; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/model/Vote.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.model; 2 | 3 | import android.database.sqlite.SQLiteDatabase; 4 | 5 | import com.airlocksoftware.database.SqlObject; 6 | 7 | /** 8 | * When the user upvotes something, the Vote is added to the Votes table and AsyncVotingService runs (which attempts to 9 | * make and uncompleted votes). 10 | **/ 11 | public class Vote extends SqlObject { 12 | 13 | public long itemId; 14 | public String username; 15 | public String auth; 16 | public String whence; 17 | 18 | public boolean success; 19 | 20 | public Vote() { 21 | } 22 | 23 | public boolean create(SQLiteDatabase db) { 24 | return super.createAndGenerateId(db); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /res/layout/vw_search_noresults.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 17 | 18 | -------------------------------------------------------------------------------- /res/drawable/lyr_frg_webview_progress.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /res/layout-large/act_settings.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /res/drawable/bg_actionbar_dark.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /res/drawable/bg_actionbar_light.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # files for the dex VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # generated files 12 | bin/ 13 | gen/ 14 | 15 | # Local configuration file (sdk path, etc) 16 | local.properties 17 | 18 | # Eclipse project files 19 | .classpath 20 | .project 21 | 22 | # Ignore the HoloTheme library 23 | libs/HoloTheme 24 | 25 | # Ignore Mac hidden dir file 26 | *.DS_Store 27 | 28 | # Ignore Android Studio / IntelliJ project files 29 | *.iml 30 | *.ipr 31 | *.iws 32 | .idea/ 33 | build/ 34 | .gradle/ 35 | 36 | # Ignore api keys 37 | res/values/crashlytics_api_key.xml 38 | 39 | # Ignore files generated by Crashlytics 40 | res/values/com_crashlytics_export_strings.xml 41 | crashlytics.properties 42 | crashlytics-build.properties 43 | -------------------------------------------------------------------------------- /res/layout/vw_loadinglist_empty.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 19 | 20 | -------------------------------------------------------------------------------- /res/drawable/bg_storylist_tablet_dark.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /res/drawable/bg_storylist_tablet_light.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /res/layout/vw_btn_sharepopup.xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 17 | 18 | -------------------------------------------------------------------------------- /proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/loader/AboutUserLoader.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.loader; 2 | 3 | import android.content.Context; 4 | import android.support.v4.content.AsyncTaskLoader; 5 | 6 | import com.airlocksoftware.hackernews.model.User; 7 | import com.airlocksoftware.hackernews.parser.UserParser; 8 | 9 | /** Downloads and parses a user's about page in the background via UserParser.parseUser() **/ 10 | public class AboutUserLoader extends AsyncTaskLoader { 11 | 12 | String mUsername; 13 | 14 | public AboutUserLoader(Context context, String username) { 15 | super(context); 16 | mUsername = username; 17 | } 18 | 19 | @Override 20 | public User loadInBackground() { 21 | if (mUsername == null) return null; 22 | return UserParser.parseUser(mUsername); 23 | } 24 | 25 | /** 26 | * Handles a request to start the Loader. 27 | */ 28 | @Override 29 | protected void onStartLoading() { 30 | forceLoad(); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/com/android/vending/billing/IMarketBillingService.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.vending.billing; 18 | 19 | import android.os.Bundle; 20 | 21 | interface IMarketBillingService { 22 | /** Given the arguments in bundle form, returns a bundle for results. */ 23 | Bundle sendBillingRequest(in Bundle bundle); 24 | } 25 | -------------------------------------------------------------------------------- /out/production/HackerNews/com/android/vending/billing/IMarketBillingService.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.vending.billing; 18 | 19 | import android.os.Bundle; 20 | 21 | interface IMarketBillingService { 22 | /** Given the arguments in bundle form, returns a bundle for results. */ 23 | Bundle sendBillingRequest(in Bundle bundle); 24 | } 25 | -------------------------------------------------------------------------------- /res/drawable/btn_actionbar_dark.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /res/drawable/btn_actionbar_light.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /res/layout/frg_comments.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 15 | 16 | 19 | 20 | 23 | 24 | 27 | 28 | -------------------------------------------------------------------------------- /res/layout/act_search.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 15 | 16 | 19 | 20 | 23 | 24 | 27 | 28 | -------------------------------------------------------------------------------- /res/drawable/fastscroll_thumb_holo.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /res/layout/vw_invalid_story.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 11 | 12 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /res/layout/stub_loading.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | 18 | 26 | 27 | -------------------------------------------------------------------------------- /res/drawable/bg_sharepopup_dark.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 21 | 22 | 23 | 28 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /res/drawable/bg_sharepopup_light.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 21 | 22 | 23 | 28 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/data/AppData.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.data; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | 6 | /** 7 | * TODO 8 | * 9 | * @author matthewbbishop 10 | */ 11 | public class AppData { 12 | 13 | // State 14 | private Context mContext; 15 | private SharedPreferences mPrefs; 16 | private SharedPreferences.Editor mEditor; 17 | 18 | // Constants 19 | public static final String PREFS_NAME = AppData.class.getSimpleName() + ".data"; 20 | public static final String STORY_LIST_POSITION = AppData.class.getSimpleName() + ".story_list_position"; 21 | 22 | public AppData(Context context) { 23 | mContext = context; 24 | mPrefs = mContext.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); 25 | mEditor = mPrefs.edit(); 26 | } 27 | 28 | public void saveStoryListPosition(int position) { 29 | mEditor.putInt(STORY_LIST_POSITION, position); 30 | mEditor.commit(); 31 | } 32 | 33 | public int getStoryListPosition() { 34 | int position = mPrefs.getInt(STORY_LIST_POSITION, 0); 35 | return position; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /res/drawable/bg_actionbar_overflow_dark.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 21 | 22 | 23 | 28 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /res/drawable/bg_actionbar_overflow_light.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 21 | 22 | 23 | 28 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /res/drawable/btn_tab_light.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /res/drawable/btn_tab_dark.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /res/layout/frg_stories.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 15 | 16 | 22 | 23 | 29 | 30 | -------------------------------------------------------------------------------- /res/layout/frg_loadinglist.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 15 | 16 | 22 | 23 | 29 | 30 | -------------------------------------------------------------------------------- /res/layout/act_tablet.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 12 | 13 | 19 | 20 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /res/layout/vw_more_link.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 21 | 22 | 29 | 30 | -------------------------------------------------------------------------------- /res/drawable/spinner_background_dark.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 20 | 22 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /res/drawable/spinner_background_light.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 20 | 22 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /res/layout/vw_overflow_searchbox.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 15 | 16 | 28 | 29 | -------------------------------------------------------------------------------- /res/drawable/btn_share_popup_dark.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /res/drawable/btn_share_popup_light.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /res/layout/vw_loadinglist_error.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 18 | 19 | 32 | 33 | -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/activity/BackActivity.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.activity; 2 | 3 | import android.os.Bundle; 4 | import android.view.View; 5 | 6 | import com.airlocksoftware.hackernews.R; 7 | import com.airlocksoftware.holo.actionbar.ActionBarView; 8 | import com.slidingmenu.lib.SlidingMenu; 9 | 10 | /** 11 | * Extends the SlideoutMenu activity to: 12 | * - finish the activity when the ActionBar "up" button is pressed 13 | * - display the SlidingMenu on long press 14 | **/ 15 | public class BackActivity extends SlideoutMenuActivity { 16 | 17 | @Override 18 | public void onCreate(Bundle savedInstanceState) { 19 | super.onCreate(savedInstanceState); 20 | 21 | SlidingMenu menu = super.getSlidingMenu(); 22 | menu.setTouchModeAbove(SlidingMenu.TOUCHMODE_MARGIN); 23 | super.removeMenuCheckState(); 24 | 25 | ActionBarView ab = getActionBarView(); 26 | View upButton = ab.getUpButton(); 27 | 28 | ab.getUpIndicator() 29 | .iconSource(R.drawable.ic_actionup_back); 30 | 31 | upButton.setOnClickListener(new View.OnClickListener() { 32 | @Override 33 | public void onClick(View v) { 34 | BackActivity.this.finish(); 35 | } 36 | }); 37 | 38 | upButton.setOnLongClickListener(new View.OnLongClickListener() { 39 | @Override 40 | public boolean onLongClick(View v) { 41 | toggle(); 42 | return true; 43 | } 44 | }); 45 | 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/data/LoginManager.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.data; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | import org.jsoup.Connection.Method; 5 | import org.jsoup.Connection.Response; 6 | 7 | public class LoginManager { 8 | 9 | private static final String LOGIN_URL_EXTENSION = "/login?go_to=news"; 10 | 11 | /** 12 | * Attempts to log the user into http://news.ycombinator.com. If successful, returns a user authentication cookie. 13 | * Else it returns null. 14 | */ 15 | public static String login(String username, String password) { 16 | try { 17 | // Response loginResponse = ConnectionManager.anonConnect(LOGIN_URL_EXTENSION) 18 | // .method(Method.GET) 19 | // .execute(); 20 | // Document loginPage = loginResponse.parse(); 21 | // String fnid = loginPage.select("input[name=fnid]") 22 | // .attr("value"); 23 | 24 | Response response = ConnectionManager.anonConnect("/login") 25 | .data("go_to", "news") 26 | .data("acct", username) 27 | .data("pw", password) 28 | .header("Origin", ConnectionManager.BASE_URL) 29 | .followRedirects(true) 30 | .referrer(ConnectionManager.BASE_URL + LOGIN_URL_EXTENSION) 31 | .method(Method.POST) 32 | .execute(); 33 | 34 | String cookie = response.cookie("user"); 35 | if (StringUtils.isNotBlank(cookie)) { 36 | return cookie; 37 | } 38 | } catch (Exception e) { 39 | // connection error 40 | } 41 | return null; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /res/drawable/edit_text_dark.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /res/drawable/edit_text_light.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /res/layout/act_donate.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 11 | 12 | 17 | 18 | 24 | 25 | 31 | 32 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | @color/black 5 | @color/gray_15 6 | 7 | 8 | #FCA306 9 | #F2DB06 10 | #E54C11 11 | #CE1054 12 | #9900F1 13 | 14 | 15 | #652207 16 | #A5370C 17 | #E54C11 18 | #F25012 19 | #CB430F 20 | @color/orange_3 21 | 22 | #2B2B2B 23 | #E0E0E0 24 | #F2F2F2 25 | #EBEBEB 26 | #D9D9D9 27 | #19FFFFFF 28 | #19000000 29 | #0CFFFFFF 30 | #0C000000 31 | 32 | #eeeeee 33 | #313131 34 | #0d0d0d 35 | #121212 36 | #FAFAFA 37 | 38 | @color/gray_19 39 | @color/gray_93 40 | 41 | -------------------------------------------------------------------------------- /res/drawable/btn_actionbar_tab_dark.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /res/drawable/btn_actionbar_tab_light.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/loader/AsyncLoginUpdater.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.loader; 2 | 3 | import java.util.Calendar; 4 | 5 | import org.apache.commons.lang3.StringUtils; 6 | 7 | import android.content.Context; 8 | import android.os.AsyncTask; 9 | 10 | import com.airlocksoftware.hackernews.data.LoginManager; 11 | import com.airlocksoftware.hackernews.data.UserPrefs; 12 | 13 | /** 14 | * Responsible for updating the user cookie in the background. It gets started by the MainActivity, and should run once 15 | * a week. 16 | **/ 17 | public class AsyncLoginUpdater extends AsyncTask { 18 | 19 | Context mApplicationContext; 20 | public static final long COOKIE_EXPIRATION = 1000 * 60 * 60 * 24 * 7; // one weeks 21 | 22 | /** Be sure to use an Application context in case of rotation happening while this is running **/ 23 | public AsyncLoginUpdater(Context applicationContext) { 24 | mApplicationContext = applicationContext; 25 | } 26 | 27 | @Override 28 | protected Void doInBackground(Void... arg0) { 29 | UserPrefs prefs = new UserPrefs(mApplicationContext); 30 | long timestamp = prefs.getCookieTimestamp(); 31 | String username = prefs.getUsername(); 32 | String password = prefs.getPassword(); 33 | long currentTime = Calendar.getInstance() 34 | .getTimeInMillis(); 35 | boolean expired = currentTime - timestamp > COOKIE_EXPIRATION; 36 | if (expired && StringUtils.isNotBlank(username) && StringUtils.isNotBlank(password)) { 37 | String newCookie = LoginManager.login(username, password); 38 | if (newCookie != null) { 39 | // saves new user cookie and updates the timestamp 40 | prefs.saveUserCookie(newCookie); 41 | } 42 | } 43 | return null; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/adapter/ThreadsAdapter.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.adapter; 2 | 3 | import java.util.Collection; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | import android.content.Context; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.widget.ListView; 11 | 12 | import com.airlocksoftware.hackernews.model.Comment; 13 | import com.airlocksoftware.hackernews.model.CommentThread; 14 | import com.airlocksoftware.hackernews.model.Story; 15 | import com.airlocksoftware.hackernews.view.SharePopup; 16 | 17 | /** 18 | * Adapter for ThreadsFragment. Extends CommentsAdapter to support Threads (which is just a List + a Story 19 | * they're children of. 20 | **/ 21 | public class ThreadsAdapter extends CommentsAdapter { 22 | 23 | // map from comment to story 24 | Map mStories = new HashMap(); 25 | 26 | public ThreadsAdapter(Context context, ListView list, SharePopup share) { 27 | super(context, list, share); 28 | // no implementation neccessary 29 | } 30 | 31 | @Override 32 | public View getView(Comment comment, View convertView, ViewGroup parent) { 33 | return super.getCommentView(mStories.get(comment), comment, convertView, parent); 34 | } 35 | 36 | public void addThreads(Collection threads) { 37 | for (CommentThread thread : threads) { 38 | addThread(thread); 39 | } 40 | } 41 | 42 | public void addThread(CommentThread thread) { 43 | if (thread.comments != null && thread.comments.size() > 0 && thread.story != null) { 44 | mStories.put(thread.comments.get(0), thread.story); 45 | } 46 | super.addAll(thread.comments); 47 | } 48 | 49 | public void clear() { 50 | super.clear(); 51 | mStories.clear(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /res/layout/vw_actionbar_tabs_comments.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 15 | 16 | 22 | 23 | 24 | 30 | 31 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/parser/UserParser.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.parser; 2 | 3 | import java.io.IOException; 4 | 5 | import org.jsoup.nodes.Document; 6 | import org.jsoup.select.Elements; 7 | 8 | import android.util.Log; 9 | 10 | import com.airlocksoftware.hackernews.data.ConnectionManager; 11 | import com.airlocksoftware.hackernews.model.User; 12 | 13 | public class UserParser { 14 | 15 | private static final String TAG = "UserParser"; 16 | 17 | public static User parseUser(String username) { 18 | try { 19 | 20 | User user = new User(); 21 | user.username = username; 22 | 23 | // don't use user cookie so that "about" text appears correctly 24 | Document page = ConnectionManager.anonConnect("/user?id=" + username) 25 | .get(); 26 | Elements trs = page.select("form > table > tbody > tr"); 27 | 28 | user.created = trs.select("td:containsOwn(created:) + td") 29 | .first() 30 | .text(); 31 | user.karma = Integer.parseInt(trs.select("td:containsOwn(karma:) + td") 32 | .first() 33 | .text()); 34 | try { 35 | user.avg = Float.parseFloat(trs.select("td:containsOwn(avg:) + td") 36 | .first() 37 | .text()); 38 | } catch (Exception e) { 39 | user.avg = -1.0f; 40 | } 41 | 42 | user.aboutHtml = trs.select("td:containsOwn(about:) + td") 43 | .first() 44 | .html(); 45 | 46 | return user; 47 | } catch (IOException e) { 48 | e.printStackTrace(); 49 | Log.d(TAG, "IOException parsing UserModel for: " + username); 50 | return null; 51 | } catch (NumberFormatException e) { 52 | e.printStackTrace(); 53 | Log.d(TAG, "NumberFormatException parsing UserModel for: " + username); 54 | return null; 55 | } catch (NullPointerException e) { 56 | e.printStackTrace(); 57 | Log.d(TAG, "NullPointerException parsing UserModel for: " + username); 58 | return null; 59 | } 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/model/StoryTimestamp.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.model; 2 | 3 | import android.database.Cursor; 4 | import android.database.sqlite.SQLiteDatabase; 5 | 6 | import com.airlocksoftware.database.SqlObject; 7 | 8 | /** Used to store the timestamp of when pages were last downloaded. **/ 9 | public class StoryTimestamp extends SqlObject { 10 | 11 | public long time; 12 | public String fnid; 13 | public String primaryId; 14 | public String secondaryId; 15 | 16 | public static final String TIME = "time"; 17 | public static final String FNID = "fnid"; 18 | public static final String PRIMARY_ID = "primaryId"; 19 | public static final String SECONDARY_ID = "secondaryId"; 20 | 21 | public StoryTimestamp() { 22 | } 23 | 24 | public boolean create(SQLiteDatabase db) { 25 | return super.createAndGenerateId(db); 26 | } 27 | 28 | public static StoryTimestamp cachedByPrimaryId(SQLiteDatabase db, String id) { 29 | StoryTimestamp timestamp = new StoryTimestamp(); 30 | Cursor c = db.query(timestamp.getTableName(), timestamp.getColNames(), PRIMARY_ID + "=?", new String[] { id }, 31 | null, null, null); 32 | 33 | if (c.moveToFirst()) { 34 | timestamp.readFromCursor(c); 35 | c.close(); 36 | return timestamp; 37 | } else { 38 | c.close(); 39 | return null; 40 | } 41 | } 42 | 43 | public static StoryTimestamp cachedByBothIds(SQLiteDatabase db, String pId, String sId) { 44 | StoryTimestamp stamp = new StoryTimestamp(); 45 | Cursor c = db.query(stamp.getTableName(), stamp.getColNames(), PRIMARY_ID + "=? AND " + SECONDARY_ID + "=?", 46 | new String[] { pId, sId }, null, null, null); 47 | 48 | if (c.moveToFirst()) { 49 | stamp.readFromCursor(c); 50 | } 51 | 52 | c.close(); 53 | return (stamp.primaryId != null) ? stamp : null; 54 | } 55 | 56 | public static void clearCache(SQLiteDatabase db, String pId, String sId) { 57 | StoryTimestamp timestamp = new StoryTimestamp(); 58 | db.delete(timestamp.getTableName(), PRIMARY_ID + "=? AND " + SECONDARY_ID + "=?", new String[] { pId, sId }); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/model/SearchItem.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.model; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | 5 | public class SearchItem { 6 | 7 | // public String _id; 8 | // public boolean _noindex; 9 | // public long _update_ts; 10 | // public String cache_ts; 11 | // public String create_ts; 12 | // public String domain; 13 | // public int id; 14 | // public int num_comments; 15 | // public int parent_id; 16 | // public String parent_sigid; 17 | // public int points; 18 | // public String text; 19 | // public String title; 20 | // public String type; 21 | // public String url; 22 | // public String username; 23 | // public Discussion discussion; 24 | 25 | public String objectID; 26 | public String title; 27 | public String author; 28 | public String created_at; 29 | public long created_at_i; 30 | public long points; 31 | public long num_comments; 32 | 33 | public String url; 34 | public String story_text; 35 | 36 | public String story_id; 37 | public String parent_id; 38 | public String comment_text; 39 | 40 | public String story_title; 41 | public String story_url; 42 | 43 | @Override 44 | public String toString() { 45 | return "SearchItem [points=" + points 46 | + ", story_text=" + story_text 47 | + ", title=" + title 48 | + ", isTextPost=" + isTextPost() 49 | + ", url=" + url 50 | + ", story_title=" + url 51 | + ", story_url=" + url 52 | + ", author=" + author + "]"; 53 | } 54 | 55 | public SearchItem() { 56 | } 57 | 58 | public boolean isArticlePost() { 59 | // It's an article post if it has a URL 60 | return StringUtils.isNotBlank(url); 61 | } 62 | 63 | public boolean isTextPost() { 64 | // It's a text post if it doesn't have a URL or comment_text 65 | return StringUtils.isNotBlank(story_text); 66 | } 67 | 68 | public boolean isComment() { 69 | // It's a comment if it has comment_text 70 | return StringUtils.isNotBlank(comment_text); 71 | } 72 | 73 | public String domain() { 74 | if (url != null) { 75 | return url.replaceAll("https?://(www.)?", "").replaceAll("/.*", ""); 76 | } else { 77 | return ""; 78 | } 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/loader/LoginLoader.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.loader; 2 | 3 | import android.content.Context; 4 | import android.database.sqlite.SQLiteDatabase; 5 | import android.support.v4.content.AsyncTaskLoader; 6 | 7 | import com.airlocksoftware.hackernews.cache.DbHelperSingleton; 8 | import com.airlocksoftware.hackernews.data.LoginManager; 9 | import com.airlocksoftware.hackernews.data.UserPrefs; 10 | import com.airlocksoftware.hackernews.model.*; 11 | import com.airlocksoftware.hackernews.model.StoryTimestamp; 12 | 13 | /** 14 | * Uses static method LoginManager.login() to perform the login. Notifies LoginActivity whether or not it was 15 | * successful. 16 | **/ 17 | public class LoginLoader extends AsyncTaskLoader { 18 | 19 | String mUsername; 20 | String mPassword; 21 | 22 | public LoginLoader(Context context, String username, String password) { 23 | super(context); 24 | mUsername = username; 25 | mPassword = password; 26 | } 27 | 28 | @Override 29 | public Result loadInBackground() { 30 | if (mUsername == null || mPassword == null) return Result.EMPTY; 31 | 32 | String newCookie = LoginManager.login(mUsername, mPassword); 33 | boolean isSuccess = newCookie != null; 34 | if (isSuccess) { 35 | // saves new user cookie and updates the timestamp 36 | UserPrefs prefs = new UserPrefs(getContext()); 37 | prefs.saveUserCookie(newCookie); 38 | prefs.saveUsername(mUsername); 39 | prefs.savePassword(mPassword); 40 | 41 | // delete all caches after logging in 42 | SQLiteDatabase db = DbHelperSingleton.getInstance(getContext()) 43 | .getWritableDatabase(); 44 | 45 | db.delete(new Story().getTableName(), null, null); 46 | db.delete(new Comment().getTableName(), null, null); 47 | db.delete(new StoryTimestamp().getTableName(), null, null); 48 | db.delete(new Vote().getTableName(), null, null); 49 | 50 | db.close(); 51 | } 52 | 53 | return isSuccess ? Result.SUCCESS : Result.FAILURE; 54 | } 55 | 56 | /** 57 | * Handles a request to start the Loader. 58 | */ 59 | @Override 60 | protected void onStartLoading() { 61 | forceLoad(); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/model/CommentsTimestamp.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.model; 2 | 3 | import android.database.Cursor; 4 | import android.database.sqlite.SQLiteDatabase; 5 | 6 | import com.airlocksoftware.database.SqlObject; 7 | 8 | /** Used to store the timestamp of when pages were last downloaded. **/ 9 | public class CommentsTimestamp extends SqlObject { 10 | 11 | public long time; 12 | public String primaryId; 13 | public String secondaryId; 14 | 15 | // Form data for the reply field 16 | public String go_to; 17 | public String parent; 18 | public String hmac; 19 | 20 | public static final String TIME = "time"; 21 | public static final String FNID = "fnid"; 22 | public static final String PRIMARY_ID = "primaryId"; 23 | public static final String SECONDARY_ID = "secondaryId"; 24 | 25 | public CommentsTimestamp() { 26 | } 27 | 28 | public boolean create(SQLiteDatabase db) { 29 | return super.createAndGenerateId(db); 30 | } 31 | 32 | public static CommentsTimestamp cachedByPrimaryId(SQLiteDatabase db, String id) { 33 | CommentsTimestamp timestamp = new CommentsTimestamp(); 34 | Cursor c = db.query(timestamp.getTableName(), timestamp.getColNames(), PRIMARY_ID + "=?", new String[] { id }, 35 | null, null, null); 36 | 37 | if (c.moveToFirst()) { 38 | timestamp.readFromCursor(c); 39 | c.close(); 40 | return timestamp; 41 | } else { 42 | c.close(); 43 | return null; 44 | } 45 | } 46 | 47 | public static CommentsTimestamp cachedByBothIds(SQLiteDatabase db, String pId, String sId) { 48 | CommentsTimestamp stamp = new CommentsTimestamp(); 49 | Cursor c = db.query(stamp.getTableName(), stamp.getColNames(), PRIMARY_ID + "=? AND " + SECONDARY_ID + "=?", 50 | new String[] { pId, sId }, null, null, null); 51 | 52 | if (c.moveToFirst()) { 53 | stamp.readFromCursor(c); 54 | } 55 | 56 | c.close(); 57 | return (stamp.primaryId != null) ? stamp : null; 58 | } 59 | 60 | public static void clearCache(SQLiteDatabase db, String pId, String sId) { 61 | StoryTimestamp timestamp = new StoryTimestamp(); 62 | db.delete(timestamp.getTableName(), PRIMARY_ID + "=? AND " + SECONDARY_ID + "=?", new String[] { pId, sId }); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/loader/ThreadsLoader.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.loader; 2 | 3 | import android.content.Context; 4 | import android.database.sqlite.SQLiteDatabase; 5 | import android.support.v4.content.AsyncTaskLoader; 6 | 7 | import com.airlocksoftware.hackernews.cache.DbHelperSingleton; 8 | import com.airlocksoftware.hackernews.model.Request; 9 | import com.airlocksoftware.hackernews.model.Result; 10 | import com.airlocksoftware.hackernews.model.StoryTimestamp; 11 | import com.airlocksoftware.hackernews.parser.CommentsParser; 12 | import com.airlocksoftware.hackernews.parser.CommentsParser.ThreadsResponse; 13 | 14 | public class ThreadsLoader extends AsyncTaskLoader { 15 | 16 | String mUsername; 17 | Request mRequest; 18 | 19 | public ThreadsLoader(Context context, Request request, String username) { 20 | super(context); 21 | mUsername = username; 22 | mRequest = request; 23 | } 24 | 25 | @Override 26 | public ThreadsResponse loadInBackground() { 27 | SQLiteDatabase db = DbHelperSingleton.getInstance(getContext()) 28 | .getWritableDatabase(); 29 | 30 | ThreadsResponse response = null; 31 | 32 | // check for more 33 | StoryTimestamp storyTimestamp = StoryTimestamp.cachedByPrimaryId(db, CommentsParser.THREAD_TIMESTAMP_ID); 34 | if (mRequest == Request.MORE && storyTimestamp != null && storyTimestamp.secondaryId.equals(mUsername)) { 35 | response = CommentsParser.parseThreadsPage(getContext(), mUsername, storyTimestamp.fnid); 36 | } 37 | 38 | // either this is a new request or we have no moreFnid 39 | if (response == null || response.result == Result.FAILURE || response.result == Result.FNID_EXPIRED) { 40 | response = CommentsParser.parseThreadsPage(getContext(), mUsername); 41 | } 42 | 43 | // delete the old one if it exists 44 | if (storyTimestamp != null) storyTimestamp.delete(db); 45 | 46 | // need to cache new moreFnid 47 | if (response.timestamp != null) { 48 | response.timestamp.create(db); 49 | } 50 | 51 | return response; 52 | } 53 | 54 | /** 55 | * Handles a request to start the Loader. 56 | */ 57 | @Override 58 | protected void onStartLoading() { 59 | forceLoad(); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /res/layout/vw_comment_search.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 19 | 20 | 31 | 32 | 38 | 39 | 52 | 53 | -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/cache/DbHelperSingleton.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.cache; 2 | 3 | import android.content.Context; 4 | import android.database.sqlite.SQLiteDatabase; 5 | import android.database.sqlite.SQLiteOpenHelper; 6 | 7 | import com.airlocksoftware.hackernews.model.*; 8 | 9 | /** 10 | * SQLiteOpenHelper singleton. Should be ok that the database is never closed as per: 11 | * http://www.androiddesignpatterns.com/2012/05/correctly-managing-your-sqlite-database.html 12 | */ 13 | public class DbHelperSingleton extends SQLiteOpenHelper { 14 | 15 | private static DbHelperSingleton mInstance = null; 16 | 17 | private static final String DATABASE_NAME = "hacker_news_cache.db"; 18 | private static final int DATABASE_VERSION = 4; 19 | 20 | public static DbHelperSingleton getInstance(Context context) { 21 | /** 22 | * Use the application context as suggested by CommonsWare. 23 | * this will ensure that you don't accidentally leak an Activity's 24 | * context (see this article for more information: 25 | * http://developer.android.com/resources/articles/avoiding-memory-leaks.html) 26 | */ 27 | if (mInstance == null) { 28 | mInstance = new DbHelperSingleton(context.getApplicationContext()); 29 | } 30 | return mInstance; 31 | } 32 | 33 | /** 34 | * constructor should be private to prevent direct instantiation. 35 | * make call to static factory method "getInstance()" instead. 36 | */ 37 | private DbHelperSingleton(Context context) { 38 | super(context, DATABASE_NAME, null, DATABASE_VERSION); 39 | } 40 | 41 | @Override 42 | public void onCreate(SQLiteDatabase db) { 43 | new Story().createTable(db); 44 | new Comment().createTable(db); 45 | new StoryTimestamp().createTable(db); 46 | new CommentsTimestamp().createTable(db); 47 | new Vote().createTable(db); 48 | } 49 | 50 | @Override 51 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 52 | db.execSQL("DROP TABLE IF EXISTS " + new Story().getTableName()); 53 | db.execSQL("DROP TABLE IF EXISTS " + new Comment().getTableName()); 54 | db.execSQL("DROP TABLE IF EXISTS " + new StoryTimestamp().getTableName()); 55 | db.execSQL("DROP TABLE IF EXISTS " + new CommentsTimestamp().getTableName()); 56 | db.execSQL("DROP TABLE IF EXISTS " + new Vote().getTableName()); 57 | 58 | onCreate(db); 59 | } 60 | } -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/data/ConnectionManager.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.data; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | import android.preference.PreferenceManager; 6 | import android.util.Log; 7 | import com.airlocksoftware.hackernews.application.MainApplication; 8 | import com.crashlytics.android.Crashlytics; 9 | import org.jsoup.Connection; 10 | import org.jsoup.Jsoup; 11 | 12 | /** Static methods for connecting to the http://news.ycombinator.com **/ 13 | public class ConnectionManager { 14 | 15 | public static final String TAG = ConnectionManager.class.getSimpleName(); 16 | public static final String BASE_URL = "https://news.ycombinator.com"; 17 | public static final String ITEMS_URL = "/item?id="; 18 | public static final String THREADS_URL = "/threads?id="; 19 | public static final String SUBMISSIONS_URL = "/submitted?id="; 20 | public static final String SUBMIT_URL = "/submit"; 21 | public static final String USER_AGENT = System.getProperty("http.agent"); 22 | public static final int TIMEOUT_MILLIS = 40 * 1000; 23 | 24 | /** Connects to news.ycombinator.com using the cookie you've provided **/ 25 | public static Connection authConnect(String baseUrlExtension, String userCookie) { 26 | return anonConnect(baseUrlExtension).cookie("user", userCookie); 27 | } 28 | 29 | /** Connects to news.ycombinator.com with no user cookie authentication **/ 30 | public static Connection anonConnect(String baseUrlExtension) { 31 | Connection conn = Jsoup.connect(ConnectionManager.BASE_URL + baseUrlExtension) 32 | .timeout(TIMEOUT_MILLIS) 33 | .userAgent(ConnectionManager.USER_AGENT); 34 | 35 | UserPrefs prefs = new UserPrefs(MainApplication.getInstance().getApplicationContext()); 36 | 37 | boolean compress = prefs.getCompressData(); 38 | Crashlytics.setBool("ConnectionManager :: GZip Responses", compress); 39 | 40 | if (compress) { 41 | conn.header("Accept-Encoding", "gzip"); 42 | } 43 | 44 | return conn; 45 | } 46 | 47 | /** Converts an id into a string containing the extension (everything that goes after .com) of the URL **/ 48 | public static String itemIdToUrlExtension(long id) { 49 | return ITEMS_URL + Long.toString(id); 50 | } 51 | 52 | /** Converts an id into a string the full URL for that id. **/ 53 | public static String itemIdToUrl(long id) { 54 | return BASE_URL + itemIdToUrlExtension(id); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /res/layout/vw_share_popup.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 13 | 14 | 24 | 25 | 36 | 37 | 44 | 45 | 46 | 55 | 56 | -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/activity/AboutActivity.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.activity; 2 | 3 | import android.content.Intent; 4 | import android.net.Uri; 5 | import android.os.Bundle; 6 | import android.view.View; 7 | 8 | import com.airlocksoftware.hackernews.R; 9 | 10 | public class AboutActivity extends SlideoutMenuActivity { 11 | 12 | private static final Uri WEBSITE = Uri.parse("http://www.airlocksoftware.com"); 13 | private static final Uri GITHUB = Uri.parse("http://github.com/bishopmatthew/HackerNews"); 14 | private static final Uri MARKET_URL = Uri.parse("market://details?id=com.airlocksoftware.hackernews"); 15 | 16 | @Override 17 | public void onCreate(Bundle savedState) { 18 | super.onCreate(savedState); 19 | 20 | setContentView(R.layout.act_about); 21 | 22 | getActionBarView().getController() 23 | .setTitleText(getString(R.string.about)); 24 | setActiveMenuItem(R.id.about_button); 25 | 26 | findViewById(R.id.btn_email).setOnClickListener(new View.OnClickListener() { 27 | @Override 28 | public void onClick(View v) { 29 | Intent i = new Intent(Intent.ACTION_SEND); 30 | i.setType("message/rfc822"); 31 | i.putExtra(Intent.EXTRA_EMAIL , new String[]{"hn@airlocksoftware.com"}); 32 | i.putExtra(Intent.EXTRA_SUBJECT, "Hacker News 2"); 33 | i.putExtra(Intent.EXTRA_TEXT , "Put your message here..."); 34 | 35 | startActivity(Intent.createChooser(i, "Send mail...")); 36 | } 37 | }); 38 | 39 | findViewById(R.id.btn_website).setOnClickListener(new View.OnClickListener() { 40 | @Override 41 | public void onClick(View v) { 42 | Intent intent = new Intent(Intent.ACTION_VIEW).setData(WEBSITE); 43 | startActivity(intent); 44 | } 45 | }); 46 | 47 | findViewById(R.id.btn_github).setOnClickListener(new View.OnClickListener() { 48 | @Override 49 | public void onClick(View v) { 50 | Intent intent = new Intent(Intent.ACTION_VIEW).setData(GITHUB); 51 | startActivity(intent); 52 | } 53 | }); 54 | 55 | findViewById(R.id.btn_store).setOnClickListener(new View.OnClickListener() { 56 | @Override 57 | public void onClick(View v) { 58 | Intent marketIntent = new Intent(Intent.ACTION_VIEW, MARKET_URL); 59 | marketIntent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 60 | startActivity(marketIntent); 61 | } 62 | }); 63 | } 64 | 65 | @Override 66 | public void onSaveInstanceState(Bundle outState) { 67 | super.onSaveInstanceState(outState); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /res/layout/vw_search_header.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 14 | 15 | 23 | 24 | 32 | 33 | 34 | 40 | 41 | 49 | 50 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/loader/ReplyLoader.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.loader; 2 | 3 | import java.io.IOException; 4 | 5 | import org.apache.commons.lang3.StringUtils; 6 | import org.jsoup.Connection.Method; 7 | import org.jsoup.nodes.Element; 8 | 9 | import android.content.Context; 10 | import android.support.v4.content.AsyncTaskLoader; 11 | 12 | import com.airlocksoftware.hackernews.data.ConnectionManager; 13 | import com.airlocksoftware.hackernews.data.UserPrefs; 14 | import com.airlocksoftware.hackernews.model.Result; 15 | 16 | /** Handles sending replies to Comments and Stories. **/ 17 | public class ReplyLoader extends AsyncTaskLoader { 18 | 19 | String mText; 20 | long mId = -1; 21 | 22 | private static final String REPLY_EXTENSION = "/r"; 23 | 24 | /** no data passed, not ready to send **/ 25 | public ReplyLoader(Context context) { 26 | super(context); 27 | } 28 | 29 | public ReplyLoader(Context context, long id, String text) { 30 | super(context); 31 | mId = id; 32 | mText = text; 33 | } 34 | 35 | @Override 36 | public Result loadInBackground() { 37 | // no data passed, not ready to send 38 | if (mId == -1 || StringUtils.isBlank(mText)) return Result.EMPTY; 39 | 40 | Result result = Result.FAILURE; // default 41 | 42 | try { 43 | UserPrefs data = new UserPrefs(getContext()); 44 | Element replyInput = getReplyInput(data); 45 | String replyFnid = replyInput.attr("value"); 46 | String response = sendReply(data, replyFnid); 47 | if (StringUtils.isNotBlank(response)) result = Result.SUCCESS; 48 | 49 | } catch (Exception e) { 50 | // any exception here probably means we have NO_CONNECTION or there's an error with the website. 51 | e.printStackTrace(); 52 | } 53 | 54 | return result; 55 | } 56 | 57 | /** POSTS the reply**/ 58 | private String sendReply(UserPrefs data, String replyFnid) throws IOException { 59 | return ConnectionManager.authConnect(REPLY_EXTENSION, data.getUserCookie()) 60 | .data("fnid", replyFnid) 61 | .data("text", mText) 62 | .method(Method.POST) 63 | .execute() 64 | .parse() 65 | .text(); 66 | } 67 | 68 | private Element getReplyInput(UserPrefs data) throws IOException { 69 | return ConnectionManager.authConnect(ConnectionManager.itemIdToUrlExtension(mId), data.getUserCookie()) 70 | .get() 71 | .select("input[name=fnid]") 72 | .first(); 73 | } 74 | 75 | /** 76 | * Handles a request to start the Loader. 77 | */ 78 | @Override 79 | protected void onStartLoading() { 80 | forceLoad(); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /res/layout/act_reply.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 13 | 14 | 19 | 20 | 26 | 27 | 33 | 34 | 40 | 41 | 47 | 48 | 56 | 57 | 58 | 59 | 60 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/view/SearchOverflow.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.view; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.view.KeyEvent; 7 | import android.view.View; 8 | import android.view.inputmethod.EditorInfo; 9 | import android.view.inputmethod.InputMethodManager; 10 | import android.widget.RelativeLayout; 11 | import android.widget.TextView; 12 | import android.widget.TextView.OnEditorActionListener; 13 | 14 | import com.airlocksoftware.hackernews.R; 15 | import com.airlocksoftware.hackernews.activity.SearchActivity; 16 | import com.airlocksoftware.hackernews.interfaces.RestartableActivity; 17 | import com.airlocksoftware.holo.image.IconView; 18 | import com.airlocksoftware.holo.type.FontEdit; 19 | 20 | /** Displays search box in the Overflow menu, and starts SearchActivity whenever a search is performed. **/ 21 | public class SearchOverflow extends RelativeLayout { 22 | 23 | Activity mActivity; 24 | FontEdit mSearchBox; 25 | IconView mSearchBtn; 26 | 27 | private static final int LAYOUT = R.layout.vw_overflow_searchbox; 28 | 29 | private OnClickListener mSearchBtnListener = new OnClickListener() { 30 | @Override 31 | public void onClick(View v) { 32 | performSearch(); 33 | } 34 | }; 35 | 36 | private OnEditorActionListener mSearchKeyboardListener = new OnEditorActionListener() { 37 | @Override 38 | public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { 39 | if (actionId == EditorInfo.IME_ACTION_SEARCH) { 40 | performSearch(); 41 | return true; 42 | } else return false; 43 | } 44 | }; 45 | 46 | public SearchOverflow(Activity activity, RestartableActivity restart) { 47 | super(activity, null); 48 | mActivity = activity; 49 | 50 | // inflate layout 51 | activity.getLayoutInflater() 52 | .inflate(LAYOUT, this); 53 | 54 | // set layout params 55 | LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); 56 | setLayoutParams(params); 57 | 58 | // find views 59 | mSearchBox = (FontEdit) findViewById(R.id.edit_search); 60 | mSearchBox.setOnEditorActionListener(mSearchKeyboardListener); 61 | mSearchBtn = (IconView) findViewById(R.id.icv_search); 62 | mSearchBtn.setOnClickListener(mSearchBtnListener); 63 | 64 | } 65 | 66 | private void performSearch() { 67 | // hide keyboard 68 | InputMethodManager inputManager = (InputMethodManager) mActivity.getSystemService(Context.INPUT_METHOD_SERVICE); 69 | inputManager.hideSoftInputFromWindow(this.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); 70 | 71 | Intent intent = new Intent(mActivity, SearchActivity.class); 72 | intent.putExtra(SearchActivity.QUERY, mSearchBox.getText() 73 | .toString()); 74 | mActivity.startActivity(intent); 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /res/layout/act_user.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 12 | 13 | 14 | 19 | 20 | 26 | 27 | 33 | 34 | 35 | 41 | 42 | 48 | 49 | 50 | 51 | 57 | 58 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /res/layout/act_contribute.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 13 | 14 | 20 | 21 | 27 | 28 | 34 | 35 | 41 | 42 | 50 | 51 | 59 | 60 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/loader/AsyncVotingService.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.loader; 2 | 3 | import java.io.IOException; 4 | 5 | import org.jsoup.Connection; 6 | import org.jsoup.Connection.Method; 7 | import org.jsoup.nodes.Document; 8 | 9 | import android.content.Context; 10 | import android.database.Cursor; 11 | import android.database.sqlite.SQLiteDatabase; 12 | import android.os.AsyncTask; 13 | 14 | import com.airlocksoftware.hackernews.cache.DbHelperSingleton; 15 | import com.airlocksoftware.hackernews.data.ConnectionManager; 16 | import com.airlocksoftware.hackernews.data.UserPrefs; 17 | import com.airlocksoftware.hackernews.model.Vote; 18 | 19 | /** 20 | * When the user performs a vote, it gets added to the Votes table and this service attempts to run. If successful, it 21 | * removes the vote from the queue. Otherwise it leaves it there to run in the future. 22 | **/ 23 | public class AsyncVotingService extends AsyncTask { 24 | 25 | private static final String BAD_UPVOTE_RESPONSE = "Can't make that vote."; 26 | private Context mApplicationContext; 27 | 28 | public AsyncVotingService(Context applicationContext) { 29 | mApplicationContext = applicationContext; 30 | } 31 | 32 | @Override 33 | protected Void doInBackground(Void... empty) { 34 | UserPrefs prefs = new UserPrefs(mApplicationContext); 35 | SQLiteDatabase db = DbHelperSingleton.getInstance(mApplicationContext) 36 | .getWritableDatabase(); 37 | Cursor c = db.rawQuery("SELECT * FROM " + new Vote().getTableName(), null); 38 | 39 | if (c.moveToFirst()) { 40 | for (int i = 0; i < c.getCount(); i++) { 41 | Vote vote = new Vote(); 42 | vote.readFromCursor(c); 43 | if (upvote(vote, prefs.getUserCookie())) { 44 | // if successful, remove vote from queue 45 | vote.delete(db); 46 | 47 | // TODO if a vote has already happened, response is the same 48 | } 49 | c.moveToNext(); 50 | } 51 | } 52 | c.close(); 53 | return null; 54 | } 55 | 56 | @Override 57 | protected void onCancelled(Void empty) { 58 | 59 | } 60 | 61 | private boolean upvote(Vote vote, String cookie) { 62 | String voteUrl = getVoteUrl(vote); 63 | Connection connection = ConnectionManager.authConnect(voteUrl, cookie); 64 | try { 65 | Connection.Response response = getResponse(connection); 66 | if (response.statusCode() == 200) { 67 | if (response.body() != null) return true; 68 | Document doc = response.parse(); 69 | String text = doc.text(); 70 | return !text.equals(BAD_UPVOTE_RESPONSE); 71 | } 72 | } catch (IOException e) { 73 | e.printStackTrace(); 74 | } 75 | return false; 76 | } 77 | 78 | private Connection.Response getResponse(Connection connection) throws IOException { 79 | return connection.method(Method.GET) 80 | .timeout(ConnectionManager.TIMEOUT_MILLIS) 81 | .execute(); 82 | } 83 | 84 | private String getVoteUrl(Vote vote) { 85 | return "/vote?for=" + Long.toString(vote.itemId) + "&dir=up&by=" + vote.username + "&auth=" + vote.auth 86 | + "&go_to=" + vote.whence; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 11 | 12 | 13 | 14 | 15 | 16 | 23 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 36 | 37 | 38 | 39 | 40 | 41 | 44 | 47 | 51 | 54 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /res/drawable/btn_radio_holo_dark.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 21 | 24 | 25 | 28 | 31 | 32 | 35 | 38 | 39 | 41 | 43 | 44 | 45 | 46 | 48 | 50 | 51 | 53 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /res/drawable/btn_radio_holo_light.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 21 | 24 | 25 | 28 | 31 | 32 | 35 | 38 | 39 | 41 | 43 | 44 | 45 | 46 | 48 | 50 | 51 | 53 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /res/layout/act_submit.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 13 | 14 | 21 | 22 | 30 | 31 | 37 | 38 | 45 | 46 | 55 | 56 | 64 | 65 | 72 | 73 | 80 | 81 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /res/layout/vw_overflow_textsettings.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 15 | 16 | 24 | 25 | 35 | 36 | 47 | 48 | 59 | 60 | 71 | 72 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /src/com/airlocksoftware/hackernews/activity/SettingsActivity.java: -------------------------------------------------------------------------------- 1 | package com.airlocksoftware.hackernews.activity; 2 | 3 | import android.os.Bundle; 4 | import android.view.View; 5 | import android.view.View.OnClickListener; 6 | import android.widget.ImageView; 7 | 8 | import com.airlocksoftware.hackernews.R; 9 | import com.airlocksoftware.hackernews.data.UserPrefs; 10 | import com.airlocksoftware.holo.utils.ViewUtils; 11 | 12 | public class SettingsActivity extends SlideoutMenuActivity { 13 | 14 | private boolean mOpenInBrowser; 15 | private boolean mSubmitBugReports; 16 | private boolean mCompressData; 17 | 18 | private View mBrowserButton; 19 | private View mBugReportsButton; 20 | private View mCompressDataButton; 21 | 22 | private UserPrefs mUserPrefs; 23 | 24 | private OnClickListener mBrowserListener = new OnClickListener() { 25 | @Override 26 | public void onClick(View v) { 27 | mOpenInBrowser = !mOpenInBrowser; 28 | mUserPrefs.saveOpenInBrowser(mOpenInBrowser); 29 | notifyDataSetChanged(); 30 | } 31 | }; 32 | 33 | private OnClickListener mBugReportsListener = new OnClickListener() { 34 | 35 | @Override 36 | public void onClick(View v) { 37 | mSubmitBugReports = !mSubmitBugReports; 38 | mUserPrefs.saveBugsenseEnabled(mSubmitBugReports); 39 | notifyDataSetChanged(); 40 | } 41 | }; 42 | 43 | private OnClickListener mCompressDataListener = new OnClickListener() { 44 | 45 | @Override 46 | public void onClick(View v) { 47 | mCompressData = !mCompressData; 48 | mUserPrefs.saveCompressData(mCompressData); 49 | notifyDataSetChanged(); 50 | } 51 | }; 52 | 53 | @Override 54 | public void onCreate(Bundle savedState) { 55 | super.onCreate(savedState); 56 | setContentView(R.layout.act_settings); 57 | ViewUtils.fixBackgroundRepeat(findViewById(R.id.scrollview)); 58 | findAndBindViews(); 59 | retrieveUserPrefs(); 60 | notifyDataSetChanged(); 61 | setupActionBar(); 62 | } 63 | 64 | private void setupActionBar() { 65 | getActionBarView().getController().setTitleText(getString(R.string.settings)); 66 | setActiveMenuItem(R.id.settings_button); 67 | } 68 | 69 | private void retrieveUserPrefs() { 70 | mUserPrefs = new UserPrefs(this); 71 | mOpenInBrowser = mUserPrefs.getOpenInBrowser(); 72 | mSubmitBugReports = mUserPrefs.getBugsenseEnabled(); 73 | mCompressData = mUserPrefs.getCompressData(); 74 | } 75 | 76 | private void findAndBindViews() { 77 | mBrowserButton = findViewById(R.id.btn_browser); 78 | mBugReportsButton = findViewById(R.id.btn_bug_reports); 79 | mCompressDataButton = findViewById(R.id.btn_compress_data); 80 | 81 | mBrowserButton.setOnClickListener(mBrowserListener); 82 | mBugReportsButton.setOnClickListener(mBugReportsListener); 83 | mCompressDataButton.setOnClickListener(mCompressDataListener); 84 | } 85 | 86 | @Override 87 | public void onSaveInstanceState(Bundle outState) { 88 | super.onSaveInstanceState(outState); 89 | } 90 | 91 | private void notifyDataSetChanged() { 92 | ImageView browserCheckbox = (ImageView) mBrowserButton.findViewById(R.id.img_checkbox_browser); 93 | if (mOpenInBrowser) browserCheckbox.setImageResource(R.drawable.chkbox_chkd_dark); 94 | else browserCheckbox.setImageResource(R.drawable.chkbox_default_dark); 95 | 96 | ImageView bugReportCheckbox = (ImageView) mBugReportsButton.findViewById(R.id.img_checkbox_bug_reports); 97 | if (mSubmitBugReports) bugReportCheckbox.setImageResource(R.drawable.chkbox_chkd_dark); 98 | else bugReportCheckbox.setImageResource(R.drawable.chkbox_default_dark); 99 | 100 | ImageView compressDataCheckbox = (ImageView) mCompressDataButton.findViewById(R.id.img_checkbox_compress_data); 101 | if (mCompressData) compressDataCheckbox.setImageResource(R.drawable.chkbox_chkd_dark); 102 | else compressDataCheckbox.setImageResource(R.drawable.chkbox_default_dark); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Hacker News 2 | ========== 3 | 4 | Come chat with us on [Gitter.im](https://gitter.im/bishopmatthew/HackerNews)! 5 | 6 | [![Come chat with us!](https://badges.gitter.im/bishopmatthew/HackerNews.png)](https://gitter.im/bishopmatthew/HackerNews) 7 | 8 | ![Screenshot of the app](http://i.imgur.com/XxS04KP.png) 9 | 10 | An open source Hacker News client for Android phones & tablets. 11 | 12 | ![Get it on Google Play!](https://developer.android.com/images/brand/en_generic_rgb_wo_60.png) 13 | 14 | [Available on the Google Play Store](https://play.google.com/store/apps/details?id=com.airlocksoftware.hackernews) 15 | 16 | # How to build 17 | 18 | The basic outline is this: there are 6 jars in the libs folder that the project depends on. Additionally you need one of my library projects, HoloTheme. It's basically a collection of utility classes & method's I've built up over time. HoloTheme also has a dependency on android-support-v4.jar (as does HackerNews). 19 | 20 | To get what you need, run these commands from a shell: 21 | ``` 22 | git clone https://github.com/bishopmatthew/HackerNews.git 23 | cd HackerNews/libs 24 | git clone https://github.com/bishopmatthew/HoloTheme.git 25 | ``` 26 | ##### IntelliJ 27 | In IntelliJ, add HoloTheme as a module and create a module dependency from HackerNews on HoloTheme. Then create a library out of the 6 jars, and add it as a compile dependency to HackerNews and a provided dependency to HoloTheme. 28 | 29 | ##### Eclipse 30 | I haven't used Eclipse in a while, but you should be able to add HoloTheme as a library project. Then add the 6 jars to the build path of HackerNews if it doesn't happen automatically. You may also have to copy android-support-v4 from HackerNews/libs into HackerNews/libs/HoloTheme/libs. 31 | 32 | ##### Android Studio 33 | If you're using Android Studio: 34 | - Go into `File > Project Structure...` and add the HoloTheme repository you cloned earlier as Android Library modules (`Modules > New Module > Library Module` under the Android section in the `New Module` dialog). 35 | - Under the `HoloTheme` module, add all the jars in the `./libs/` folder as "provided" dependencies. 36 | - Under the `HackerNews` module, add all of the jars in the `./libs/` folder as "compile" dependencies. 37 | - Under the `HackerNews` module, add the `HoloTheme`module as dependencies (Using the `Module Dependency` option when adding them). 38 | 39 | # Design Overview 40 | 41 | I've outlined the design in in [this wiki article](https://github.com/bishopmatthew/HackerNews/wiki/Design-Overview). This might also be helpful if you're interested in writing Android apps. 42 | 43 | # How to help 44 | 45 | If you tackle any of the issues on the tracker, that would be great! I've added a few enhancements there with a pretty detailed description of what needs to be done. 46 | 47 | # License 48 | 49 | The MIT License (MIT) 50 | Copyright (c) 2013 Matthew Bishop 51 | 52 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 53 | 54 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 55 | 56 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 57 | 58 | 59 | The code will be here later today, for now you can use issues for bug reports or feature requests. 60 | --------------------------------------------------------------------------------