Merge remote-tracking branch 'upstream/master'

This commit is contained in:
ojiikun 2013-11-15 21:44:46 +00:00
commit f85f355a26
55 changed files with 695 additions and 141 deletions

View file

@ -187,6 +187,7 @@ class UserAgentBanMiddleware:
if 'profile' in request.path: return
if 'haproxy' in request.path: return
if getattr(settings, 'TEST_DEBUG'): return
if any(ua in user_agent for ua in BANNED_USER_AGENTS):
data = {

View file

@ -17,7 +17,7 @@
"pk": 1,
"model": "reader.usersubscriptionfolders",
"fields": {
"folders": "[1, {\"Tech\": [4, 5, {\"Deep Tech\": [6, 7]}]}, 2, 3, 8, 9, {\"Blogs\": [8, 9]}]",
"folders": "[{\"Tech\": [1, 4, 5, {\"Deep Tech\": [6, 7]}]}, 2, 3, 8, 9, {\"Blogs\": [8, 9]}, 1]",
"user": 1
}
},

View file

@ -917,7 +917,25 @@ class UserSubscriptionFolders(models.Model):
user_sub_folders = add_object_to_folder(obj, parent_folder, user_sub_folders)
self.folders = json.encode(user_sub_folders)
self.save()
def arranged_folders(self):
user_sub_folders = json.decode(self.folders)
def _arrange_folder(folder):
folder_feeds = []
folder_folders = []
for item in folder:
if isinstance(item, int):
folder_feeds.append(item)
elif isinstance(item, dict):
for f_k, f_v in item.items():
arranged_folder = _arrange_folder(f_v)
folder_folders.append({f_k: arranged_folder})
arranged_folder = folder_feeds + folder_folders
return arranged_folder
return _arrange_folder(user_sub_folders)
def delete_feed(self, feed_id, in_folder, commit_delete=True):
def _find_feed_in_folders(old_folders, folder_name='', multiples_found=False, deleted=False):
new_folders = []
@ -944,7 +962,7 @@ class UserSubscriptionFolders(models.Model):
return new_folders, multiples_found, deleted
user_sub_folders = json.decode(self.folders)
user_sub_folders = self.arranged_folders()
user_sub_folders, multiples_found, deleted = _find_feed_in_folders(user_sub_folders)
self.folders = json.encode(user_sub_folders)
self.save()

View file

@ -6,7 +6,9 @@ from django.conf import settings
from mongoengine.connection import connect, disconnect
class ReaderTest(TestCase):
fixtures = ['subscriptions.json', 'stories.json', '../../rss_feeds/fixtures/gawker1.json']
fixtures = ['../../rss_feeds/fixtures/rss_feeds.json',
'subscriptions.json', 'stories.json',
'../../rss_feeds/fixtures/gawker1.json']
def setUp(self):
@ -23,16 +25,16 @@ class ReaderTest(TestCase):
response = self.client.get(reverse('load-feeds'))
content = json.decode(response.content)
self.assertEquals(len(content['feeds']), 1)
self.assertEquals(len(content['feeds']), 10)
self.assertEquals(content['feeds']['1']['feed_title'], 'Gawker')
self.assertEquals(content['folders'], [1, {'Tech': [4, 5, {'Deep Tech': [6, 7]}]}, 2, 3, 8, 9, {'Blogs': [8, 9]}])
self.assertEquals(content['folders'], [{'Tech': [1, 4, 5, {'Deep Tech': [6, 7]}]}, 2, 3, 8, 9, {'Blogs': [8, 9]}, 1])
def test_delete_feed(self):
self.client.login(username='conesus', password='test')
response = self.client.get(reverse('load-feeds'))
feeds = json.decode(response.content)
self.assertEquals(feeds['folders'], [1, {'Tech': [4, 5, {'Deep Tech': [6, 7]}]}, 2, 3, 8, 9, {'Blogs': [8, 9]}])
self.assertEquals(feeds['folders'], [{'Tech': [1, 4, 5, {'Deep Tech': [6, 7]}]}, 2, 3, 8, 9, {'Blogs': [8, 9]}, 1])
# Delete feed
response = self.client.post(reverse('delete-feed'), {'feed_id': 1, 'in_folder': ''})
@ -41,7 +43,7 @@ class ReaderTest(TestCase):
response = self.client.get(reverse('load-feeds'))
feeds = json.decode(response.content)
self.assertEquals(feeds['folders'], [{'Tech': [4, 5, {'Deep Tech': [6, 7]}]}, 2, 3, 8, 9, {'Blogs': [8, 9]}])
self.assertEquals(feeds['folders'], [2, 3, 8, 9, {'Tech': [1, 4, 5, {'Deep Tech': [6, 7]}]}, {'Blogs': [8, 9]}])
# Delete feed
response = self.client.post(reverse('delete-feed'), {'feed_id': 9, 'in_folder': 'Blogs'})
@ -50,7 +52,7 @@ class ReaderTest(TestCase):
response = self.client.get(reverse('load-feeds'))
feeds = json.decode(response.content)
self.assertEquals(feeds['folders'], [{'Tech': [4, 5, {'Deep Tech': [6, 7]}]}, 2, 3, 8, 9, {'Blogs': [8]}])
self.assertEquals(feeds['folders'], [2, 3, 8, 9, {'Tech': [1, 4, 5, {'Deep Tech': [6, 7]}]}, {'Blogs': [8]}])
# Delete feed
response = self.client.post(reverse('delete-feed'), {'feed_id': 5, 'in_folder': 'Tech'})
@ -59,7 +61,7 @@ class ReaderTest(TestCase):
response = self.client.get(reverse('load-feeds'))
feeds = json.decode(response.content)
self.assertEquals(feeds['folders'], [{'Tech': [4, {'Deep Tech': [6, 7]}]}, 2, 3, 8, 9, {'Blogs': [8]}])
self.assertEquals(feeds['folders'], [2, 3, 8, 9, {'Tech': [1, 4, {'Deep Tech': [6, 7]}]}, {'Blogs': [8]}])
# Delete feed
response = self.client.post(reverse('delete-feed'), {'feed_id': 4, 'in_folder': 'Tech'})
@ -68,7 +70,7 @@ class ReaderTest(TestCase):
response = self.client.get(reverse('load-feeds'))
feeds = json.decode(response.content)
self.assertEquals(feeds['folders'], [{'Tech': [{'Deep Tech': [6, 7]}]}, 2, 3, 8, 9, {'Blogs': [8]}])
self.assertEquals(feeds['folders'], [2, 3, 8, 9, {'Tech': [1, {'Deep Tech': [6, 7]}]}, {'Blogs': [8]}])
# Delete feed
response = self.client.post(reverse('delete-feed'), {'feed_id': 8, 'in_folder': ''})
@ -77,7 +79,23 @@ class ReaderTest(TestCase):
response = self.client.get(reverse('load-feeds'))
feeds = json.decode(response.content)
self.assertEquals(feeds['folders'], [{'Tech': [{'Deep Tech': [6, 7]}]}, 2, 3, 9, {'Blogs': [8]}])
self.assertEquals(feeds['folders'], [2, 3, 9, {'Tech': [1, {'Deep Tech': [6, 7]}]}, {'Blogs': [8]}])
def test_delete_feed__multiple_folders(self):
self.client.login(username='conesus', password='test')
response = self.client.get(reverse('load-feeds'))
feeds = json.decode(response.content)
self.assertEquals(feeds['folders'], [{'Tech': [1, 4, 5, {'Deep Tech': [6, 7]}]}, 2, 3, 8, 9, {'Blogs': [8, 9]}, 1])
# Delete feed
response = self.client.post(reverse('delete-feed'), {'feed_id': 1})
response = json.decode(response.content)
self.assertEquals(response['code'], 1)
response = self.client.get(reverse('load-feeds'))
feeds = json.decode(response.content)
self.assertEquals(feeds['folders'], [2, 3, 8, 9, {'Tech': [1, 4, 5, {'Deep Tech': [6, 7]}]}, {'Blogs': [8, 9]}])
def test_load_single_feed(self):
# from django.conf import settings

View file

@ -607,8 +607,9 @@ def load_single_feed(request, feed_id):
if not include_story_content:
del story['story_content']
story_date = localtime_for_timezone(story['story_date'], user.profile.timezone)
story['short_parsed_date'] = format_story_link_date__short(story_date)
story['long_parsed_date'] = format_story_link_date__long(story_date, now)
nowtz = localtime_for_timezone(now, user.profile.timezone)
story['short_parsed_date'] = format_story_link_date__short(story_date, nowtz)
story['long_parsed_date'] = format_story_link_date__long(story_date, nowtz)
if usersub:
story['read_status'] = 1
if (read_filter == 'all' or query) and usersub:
@ -782,12 +783,13 @@ def load_starred_stories(request):
comments=story.comments))
for story in shared_stories])
nowtz = localtime_for_timezone(now, user.profile.timezone)
for story in stories:
story_date = localtime_for_timezone(story['story_date'], user.profile.timezone)
story['short_parsed_date'] = format_story_link_date__short(story_date)
story['long_parsed_date'] = format_story_link_date__long(story_date, now)
story['short_parsed_date'] = format_story_link_date__short(story_date, nowtz)
story['long_parsed_date'] = format_story_link_date__long(story_date, nowtz)
starred_date = localtime_for_timezone(story['starred_date'], user.profile.timezone)
story['starred_date'] = format_story_link_date__long(starred_date, now)
story['starred_date'] = format_story_link_date__long(starred_date, nowtz)
story['read_status'] = 1
story['starred'] = True
story['intelligence'] = {
@ -939,6 +941,7 @@ def load_river_stories__redis(request):
# Just need to format stories
nowtz = localtime_for_timezone(now, user.profile.timezone)
for story in stories:
story['read_status'] = 0
if read_filter == 'all':
@ -946,8 +949,8 @@ def load_river_stories__redis(request):
story['story_hash'] not in unread_feed_story_hashes):
story['read_status'] = 1
story_date = localtime_for_timezone(story['story_date'], user.profile.timezone)
story['short_parsed_date'] = format_story_link_date__short(story_date)
story['long_parsed_date'] = format_story_link_date__long(story_date, now)
story['short_parsed_date'] = format_story_link_date__short(story_date, nowtz)
story['long_parsed_date'] = format_story_link_date__long(story_date, nowtz)
if story['story_hash'] in starred_stories:
story['starred'] = True
starred_date = localtime_for_timezone(starred_stories[story['story_hash']],
@ -1399,7 +1402,7 @@ def add_folder(request):
def delete_feed(request):
feed_id = int(request.POST['feed_id'])
in_folder = request.POST.get('in_folder', None)
if in_folder == ' ':
if not in_folder or in_folder == ' ':
in_folder = ""
user_sub_folders = get_object_or_404(UserSubscriptionFolders, user=request.user)

View file

@ -136,5 +136,302 @@
"email": "samuel@newsblur.com",
"date_joined": "2009-01-04 17:32:58"
}
},
{
"pk": 2,
"model": "rss_feeds.feed",
"fields": {
"premium_subscribers": -1,
"creation": "2011-08-27",
"exception_code": 0,
"last_load_time": 0,
"active_subscribers": 1,
"feed_address": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker2.xml",
"feed_link": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker2.html",
"hash_address_and_link": "2",
"feed_link_locked": true,
"last_update": "2011-08-27 02:45:21",
"etag": null,
"average_stories_per_month": 0,
"feed_title": "Gawker",
"last_modified": null,
"next_scheduled_update": "2011-08-28 14:33:50",
"favicon_color": null,
"stories_last_month": 0,
"active": true,
"favicon_not_found": false,
"has_page_exception": false,
"fetched_once": false,
"days_to_trim": 90,
"num_subscribers": 1,
"last_story_date": "2011-08-28 00:03:50",
"min_to_decay": 720,
"has_feed_exception": false
}
},
{
"pk": 3,
"model": "rss_feeds.feed",
"fields": {
"premium_subscribers": -1,
"creation": "2011-08-27",
"exception_code": 0,
"last_load_time": 0,
"active_subscribers": 1,
"feed_address": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker3.xml",
"feed_link": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker3.html",
"hash_address_and_link": "3",
"feed_link_locked": true,
"last_update": "2011-08-27 02:45:21",
"etag": null,
"average_stories_per_month": 0,
"feed_title": "Gawker",
"last_modified": null,
"next_scheduled_update": "2011-08-28 14:33:50",
"favicon_color": null,
"stories_last_month": 0,
"active": true,
"favicon_not_found": false,
"has_page_exception": false,
"fetched_once": false,
"days_to_trim": 90,
"num_subscribers": 1,
"last_story_date": "2011-08-28 00:03:50",
"min_to_decay": 720,
"has_feed_exception": false
}
},
{
"pk": 4,
"model": "rss_feeds.feed",
"fields": {
"premium_subscribers": -1,
"creation": "2011-08-27",
"exception_code": 0,
"last_load_time": 0,
"active_subscribers": 1,
"feed_address": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker4.xml",
"feed_link": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker4.html",
"hash_address_and_link": "4",
"feed_link_locked": true,
"last_update": "2011-08-27 02:45:21",
"etag": null,
"average_stories_per_month": 0,
"feed_title": "Gawker",
"last_modified": null,
"next_scheduled_update": "2011-08-28 14:33:50",
"favicon_color": null,
"stories_last_month": 0,
"active": true,
"favicon_not_found": false,
"has_page_exception": false,
"fetched_once": false,
"days_to_trim": 90,
"num_subscribers": 1,
"last_story_date": "2011-08-28 00:03:50",
"min_to_decay": 720,
"has_feed_exception": false
}
},
{
"pk": 5,
"model": "rss_feeds.feed",
"fields": {
"premium_subscribers": -1,
"creation": "2011-08-27",
"exception_code": 0,
"last_load_time": 0,
"active_subscribers": 1,
"feed_address": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker5.xml",
"feed_link": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker5.html",
"hash_address_and_link": "5",
"feed_link_locked": true,
"last_update": "2011-08-27 02:45:21",
"etag": null,
"average_stories_per_month": 0,
"feed_title": "Gawker",
"last_modified": null,
"next_scheduled_update": "2011-08-28 14:33:50",
"favicon_color": null,
"stories_last_month": 0,
"active": true,
"favicon_not_found": false,
"has_page_exception": false,
"fetched_once": false,
"days_to_trim": 90,
"num_subscribers": 1,
"last_story_date": "2011-08-28 00:03:50",
"min_to_decay": 720,
"has_feed_exception": false
}
},
{
"pk": 6,
"model": "rss_feeds.feed",
"fields": {
"premium_subscribers": -1,
"creation": "2011-08-27",
"exception_code": 0,
"last_load_time": 0,
"active_subscribers": 1,
"feed_address": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker6.xml",
"feed_link": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker6.html",
"hash_address_and_link": "6",
"feed_link_locked": true,
"last_update": "2011-08-27 02:45:21",
"etag": null,
"average_stories_per_month": 0,
"feed_title": "Gawker",
"last_modified": null,
"next_scheduled_update": "2011-08-28 14:33:50",
"favicon_color": null,
"stories_last_month": 0,
"active": true,
"favicon_not_found": false,
"has_page_exception": false,
"fetched_once": false,
"days_to_trim": 90,
"num_subscribers": 1,
"last_story_date": "2011-08-28 00:03:50",
"min_to_decay": 720,
"has_feed_exception": false
}
},
{
"pk": 7,
"model": "rss_feeds.feed",
"fields": {
"premium_subscribers": -1,
"creation": "2011-08-27",
"exception_code": 0,
"last_load_time": 0,
"active_subscribers": 1,
"feed_address": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker7.xml",
"feed_link": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker7.html",
"hash_address_and_link": "7",
"feed_link_locked": true,
"last_update": "2011-08-27 02:45:21",
"etag": null,
"average_stories_per_month": 0,
"feed_title": "Gawker",
"last_modified": null,
"next_scheduled_update": "2011-08-28 14:33:50",
"favicon_color": null,
"stories_last_month": 0,
"active": true,
"favicon_not_found": false,
"has_page_exception": false,
"fetched_once": false,
"days_to_trim": 90,
"num_subscribers": 1,
"last_story_date": "2011-08-28 00:03:50",
"min_to_decay": 720,
"has_feed_exception": false
}
},
{
"pk": 8,
"model": "rss_feeds.feed",
"fields": {
"premium_subscribers": -1,
"creation": "2011-08-27",
"exception_code": 0,
"last_load_time": 0,
"active_subscribers": 1,
"feed_address": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker8.xml",
"feed_link": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker8.html",
"hash_address_and_link": "8",
"feed_link_locked": true,
"last_update": "2011-08-27 02:45:21",
"etag": null,
"average_stories_per_month": 0,
"feed_title": "Gawker",
"last_modified": null,
"next_scheduled_update": "2011-08-28 14:33:50",
"favicon_color": null,
"stories_last_month": 0,
"active": true,
"favicon_not_found": false,
"has_page_exception": false,
"fetched_once": false,
"days_to_trim": 90,
"num_subscribers": 1,
"last_story_date": "2011-08-28 00:03:50",
"min_to_decay": 720,
"has_feed_exception": false
}
},
{
"pk": 9,
"model": "rss_feeds.feed",
"fields": {
"premium_subscribers": -1,
"creation": "2011-08-27",
"exception_code": 0,
"last_load_time": 0,
"active_subscribers": 1,
"feed_address": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker9.xml",
"feed_link": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker9.html",
"hash_address_and_link": "9",
"feed_link_locked": true,
"last_update": "2011-08-27 02:45:21",
"etag": null,
"average_stories_per_month": 0,
"feed_title": "Gawker",
"last_modified": null,
"next_scheduled_update": "2011-08-28 14:33:50",
"favicon_color": null,
"stories_last_month": 0,
"active": true,
"favicon_not_found": false,
"has_page_exception": false,
"fetched_once": false,
"days_to_trim": 90,
"num_subscribers": 1,
"last_story_date": "2011-08-28 00:03:50",
"min_to_decay": 720,
"has_feed_exception": false
}
},
{
"pk": 56,
"model": "rss_feeds.feed",
"fields": {
"premium_subscribers": -1,
"creation": "2011-08-27",
"exception_code": 0,
"last_load_time": 0,
"active_subscribers": 1,
"feed_address": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker56.xml",
"feed_link": "%(NEWSBLUR_DIR)s/apps/rss_feeds/fixtures/gawker56.html",
"hash_address_and_link": "56",
"feed_link_locked": true,
"last_update": "2011-08-27 02:45:21",
"etag": null,
"average_stories_per_month": 0,
"feed_title": "Gawker",
"last_modified": null,
"next_scheduled_update": "2011-08-28 14:33:50",
"favicon_color": null,
"stories_last_month": 0,
"active": true,
"favicon_not_found": false,
"has_page_exception": false,
"fetched_once": false,
"days_to_trim": 90,
"num_subscribers": 1,
"last_story_date": "2011-08-28 00:03:50",
"min_to_decay": 720,
"has_feed_exception": false
}
}
]

View file

@ -912,6 +912,7 @@ class Feed(models.Model):
story_content = strip_comments(story_content)
story_tags = self.get_tags(story)
story_link = self.get_permalink(story)
replace_story_date = False
try:
existing_story, story_has_changed = _1(story, story_content, existing_stories)
@ -937,11 +938,18 @@ class Feed(models.Model):
try:
s.save()
ret_values['new'] += 1
except (IntegrityError, OperationError), e:
except (IntegrityError), e:
ret_values['error'] += 1
if settings.DEBUG:
logging.info(' ---> [%-30s] ~SN~FRIntegrityError on new story: %s - %s' % (self.feed_title[:30], story.get('guid'), e))
elif existing_story and story_has_changed:
except OperationError, e:
existing_story, _ = MStory.find_story(self.pk,
story.get('guid'),
original_only=True)
story_has_changed = True
replace_story_date = True
if existing_story and story_has_changed:
# update story
original_content = None
try:
@ -993,7 +1001,8 @@ class Feed(models.Model):
existing_story.story_tags = story_tags
# Do not allow publishers to change the story date once a story is published.
# Leads to incorrect unread story counts.
# existing_story.story_date = story.get('published') # No, don't
if replace_story_date:
existing_story.story_date = story.get('published') # Really shouldn't do this.
existing_story.extract_image_urls()
try:

View file

@ -3001,14 +3001,17 @@ class MActivity(mongo.Document):
@classmethod
def remove_shared_story(cls, user_id, story_feed_id, story_id):
params = dict(user_id=user_id,
category='sharedstory',
feed_id="social:%s" % user_id,
story_feed_id=story_feed_id,
content_id=story_id)
try:
a = cls.objects.get(user_id=user_id,
category='sharedstory',
feed_id="social:%s" % user_id,
story_feed_id=story_feed_id,
content_id=story_id)
a = cls.objects.get(**params)
except cls.DoesNotExist:
return
except cls.MultipleObjectsReturned:
a = cls.objects.filter(**params)
a.delete()

View file

@ -119,12 +119,13 @@ def load_social_stories(request, user_id, username=None):
comments=story.comments))
for story in shared_stories])
nowtz = localtime_for_timezone(now, user.profile.timezone)
for story in stories:
story['social_user_id'] = social_user_id
# story_date = localtime_for_timezone(story['story_date'], user.profile.timezone)
shared_date = localtime_for_timezone(story['shared_date'], user.profile.timezone)
story['short_parsed_date'] = format_story_link_date__short(shared_date)
story['long_parsed_date'] = format_story_link_date__long(shared_date)
story['short_parsed_date'] = format_story_link_date__short(shared_date, nowtz)
story['long_parsed_date'] = format_story_link_date__long(shared_date, nowtz)
story['read_status'] = 1
if (read_filter == 'all' or query) and socialsub:
@ -270,13 +271,14 @@ def load_river_blurblog(request):
classifier_tags = []
# Just need to format stories
nowtz = localtime_for_timezone(now, user.profile.timezone)
for story in stories:
story['read_status'] = 0
if story['story_hash'] not in unread_feed_story_hashes:
story['read_status'] = 1
story_date = localtime_for_timezone(story['story_date'], user.profile.timezone)
story['short_parsed_date'] = format_story_link_date__short(story_date)
story['long_parsed_date'] = format_story_link_date__long(story_date, now)
story['short_parsed_date'] = format_story_link_date__short(story_date, nowtz)
story['long_parsed_date'] = format_story_link_date__long(story_date, nowtz)
if story['story_hash'] in starred_stories:
story['starred'] = True
starred_date = localtime_for_timezone(starred_stories[story['story_hash']], user.profile.timezone)
@ -521,7 +523,9 @@ def mark_story_as_shared(request):
source_user_id = request.POST.get('source_user_id')
relative_user_id = request.POST.get('relative_user_id') or request.user.pk
post_to_services = request.POST.getlist('post_to_services')
format = request.REQUEST.get('format', 'json')
format = request.REQUEST.get('format', 'json')
now = datetime.datetime.now()
nowtz = localtime_for_timezone(now, request.user.profile.timezone)
MSocialProfile.get_user(request.user.pk)
@ -576,8 +580,8 @@ def mark_story_as_shared(request):
story['shared_by_user'] = True
story['shared'] = True
shared_date = localtime_for_timezone(shared_story['shared_date'], request.user.profile.timezone)
story['short_parsed_date'] = format_story_link_date__short(shared_date)
story['long_parsed_date'] = format_story_link_date__long(shared_date)
story['short_parsed_date'] = format_story_link_date__short(shared_date, nowtz)
story['long_parsed_date'] = format_story_link_date__long(shared_date, nowtz)
if post_to_services:
for service in post_to_services:

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.newsblur"
android:versionCode="43"
android:versionName="2.5.0" >
android:versionCode="44"
android:versionName="3.0.0" >
<uses-sdk
android:minSdkVersion="8"

View file

@ -10,16 +10,23 @@
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/gen" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/gen" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="jdk" jdkName="Android 4.2.2" jdkType="Android SDK" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="android-support-v4" level="project" />
<orderEntry type="library" name="actionbarsherlock" level="project" />
<orderEntry type="library" name="gson-2.2.3" level="project" />
<orderEntry type="library" name="classes" level="project" />
<orderEntry type="module" module-name="ActionBarSherlock" />
<orderEntry type="library" name="android-support-v4" level="project" />
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/libs/ActionBarSherlock/bin/actionbarsherlock.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
</component>
</module>

View file

@ -11,12 +11,11 @@
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/gen" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/gen" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="jdk" jdkName="Android 4.2.2" jdkType="Android SDK" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="android-support-v4" level="project" />
</component>
</module>

View file

@ -9,4 +9,4 @@
android.library=true
# Project target.
target=android-17
target=android-14

View file

@ -11,5 +11,5 @@
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
target=android-17
target=android-14
android.library.reference.1=libs/ActionBarSherlock

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 820 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 605 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 605 B

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape
android:shape="rectangle">
<solid android:color="@color/feed_background_selected_start"/>
</shape>
</item>
<item
android:top="0.5dp"
android:bottom="0.5dp">
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/feed_background_selected_end"/>
</shape>
</item>
</layer-list>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="90"
android:type="linear"
android:startColor="@color/folder_background_start"
android:endColor="@color/folder_background_end"/>
</shape>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="90"
android:type="linear"
android:startColor="@color/folder_background_selected_start"
android:endColor="@color/folder_background_selected_end"/>
</shape>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" android:drawable="@drawable/gradient_activation_highlight" />
<item android:state_pressed="true" android:drawable="@drawable/feed_background_highlight" />
<item android:drawable="@drawable/feed_background_default" />
</selector>

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" android:drawable="@drawable/gradient_activation_highlight" />
<item android:drawable="@drawable/gradient_background_default" />
<item android:state_pressed="true" android:drawable="@drawable/folder_background_highlight" />
<item android:drawable="@drawable/folder_background_default" />
</selector>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/story_background_highlight"/>
<item android:drawable="@drawable/story_background_default"/>
</selector>

View file

Before

Width:  |  Height:  |  Size: 517 B

After

Width:  |  Height:  |  Size: 517 B

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/story_background"/>
</shape>

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape
android:shape="rectangle">
<solid android:color="@color/story_background_start"/>
</shape>
</item>
<item
android:top="0.5dp"
android:bottom="0.5dp">
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/story_background_end"/>
</shape>
</item>
</layer-list>

View file

@ -19,4 +19,13 @@
android:defaultValue="@string/default_read_filter_value" />
</PreferenceCategory>
<PreferenceCategory
android:title="@string/settings_social">
<CheckBoxPreference
android:defaultValue="true"
android:key="show_public_comments"
android:title="@string/settings_show_public_comments" >
</CheckBoxPreference>
</PreferenceCategory>
</PreferenceScreen>

View file

@ -91,7 +91,7 @@
android:layout_toRightOf="@id/comment_user_image"
android:textColor="@color/newsblur_blue"
android:textSize="14sp" />
<TextView
android:id="@+id/comment_text"
android:layout_width="match_parent"
@ -105,6 +105,18 @@
android:textColor="@color/darkgray"
android:textSize="14dp" />
<TextView
android:id="@+id/comment_location"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/comment_text"
android:layout_marginRight="10dp"
android:layout_marginBottom="4dp"
android:layout_toRightOf="@id/comment_user_image"
android:textColor="@color/lightgray"
android:textSize="12dp"
/>
<com.newsblur.view.FlowLayout
xmlns:newsblur="http://schemas.android.com/apk/res/com.newsblur"
android:id="@+id/comment_favourite_avatars"
@ -121,6 +133,7 @@
<LinearLayout
android:id="@+id/comment_replies_container"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
@ -129,6 +142,6 @@
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginBottom="5dp"
android:background="#A6A6A6" />
android:background="#F0F0F0" />
</LinearLayout>

View file

@ -5,7 +5,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="15dp" >
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp" >
<Button
android:id="@+id/share_story_button"
@ -20,7 +21,7 @@
android:paddingBottom="6dp"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:drawableLeft="@drawable/share_half"
android:drawableLeft="@drawable/share_icon"
android:text="@string/share_this" />
<Button
@ -36,7 +37,7 @@
android:paddingBottom="6dp"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:drawableLeft="@drawable/clock_half"
android:drawableLeft="@drawable/clock"
android:text="@string/save_this" />
</LinearLayout>
@ -45,51 +46,103 @@
android:id="@+id/reading_shared_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="50dp" >
<LinearLayout
android:id="@+id/reading_friend_comment_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:id="@+id/reading_friend_comment_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/darkgray"
android:id="@+id/reading_friend_comment_total"
android:paddingTop="3dp"
android:textStyle="bold"
android:paddingBottom="3dp" />
</LinearLayout>
android:visibility="gone"
android:orientation="vertical">
<View
android:id="@+id/comment_divider"
android:layout_width="match_parent"
android:layout_height="3dp"
android:layout_below="@id/reading_friend_comment_container"
android:background="@drawable/divider_light" />
<View
android:id="@+id/reading_friend_header_top_border"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="12dp"
android:background="@color/lightgray"/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:textColor="@color/darkgray"
android:id="@+id/reading_friend_comment_total"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:textStyle="bold"
android:textSize="10sp"
android:background="@drawable/gradient_background_default"
/>
<View
android:id="@+id/reading_friend_header_bottom_border"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_below="@id/reading_friend_comment_total"
android:background="@color/lightgray"/>
</LinearLayout>
<LinearLayout
android:id="@+id/reading_public_comment_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/comment_divider"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:id="@+id/reading_friend_comment_container"
android:layout_below="@id/reading_friend_comment_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/darkgray"
android:paddingTop="3dp"
android:textStyle="bold"
android:id="@+id/reading_public_comment_total"
android:paddingBottom="3dp" />
</LinearLayout>
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:orientation="vertical">
</LinearLayout>
<LinearLayout
android:id="@+id/reading_public_comment_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/comment_divider"
android:visibility="gone"
android:orientation="vertical">
<View
android:id="@+id/reading_public_header_top_border"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="12dp"
android:background="@color/lightgray"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/darkgray"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:textStyle="bold"
android:textSize="10sp"
android:background="@drawable/gradient_background_default"
android:id="@+id/reading_public_comment_total" />
<View
android:id="@+id/reading_public_header_bottom_border"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_below="@id/reading_public_comment_total"
android:background="@color/lightgray"/>
</LinearLayout>
<LinearLayout
android:id="@+id/reading_public_comment_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:layout_below="@id/reading_public_comment_header"
android:orientation="vertical">
</LinearLayout>
</RelativeLayout>
</merge>

View file

@ -2,7 +2,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/item_background"
android:background="@drawable/selector_story_background"
android:orientation="horizontal" >
<RelativeLayout

View file

@ -2,7 +2,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/selector_feed_background"
android:background="@drawable/selector_story_background"
android:orientation="horizontal" >
<RelativeLayout
@ -20,7 +20,6 @@
android:layout_height="match_parent"
android:layout_toRightOf="@id/row_item_favicon_borderbar_1" />
<RelativeLayout
android:id="@+id/row_item_title_container"
android:layout_width="match_parent"

View file

@ -2,7 +2,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/selector_feed_background"
android:background="@drawable/selector_story_background"
android:orientation="horizontal" >
<RelativeLayout

View file

@ -6,16 +6,21 @@
<color name="midgray">#898989</color>
<color name="lightgray">#ccc</color>
<color name="folder_background_end">#E9EBE4</color>
<color name="folder_background_start">#DDE0D7</color>
<color name="folder_background_selected_end">#fdfcca</color>
<color name="folder_background_selected_start">#fbec8c</color>
<color name="folder_background_end">#E9EBE4</color>
<color name="folder_background_start">#DDE0D7</color>
<color name="folder_background_selected_end">#D9DBD4</color>
<color name="folder_background_selected_start">#CDD0C7</color>
<color name="folder_text">#4C4C4C</color>
<color name="folder_border_top">#FDFDFD</color>
<color name="folder_border_bottom">#B7BBAA</color>
<color name="feed_background">#F7F8F5</color>
<color name="feed_background_end">#303030</color>
<color name="feed_background_start">#505050</color>
<color name="feed_background_selected_end">#FFFFD2</color>
<color name="feed_background_selected_start">#E3D0AE</color>
<color name="story_background">#F7F8F5</color>
<color name="story_background_end">#FFFDEF</color>
<color name="story_background_start">#DFDDCF</color>
<color name="story_title_unread">#333333</color>
<color name="story_title_read">#808080</color>

View file

@ -190,4 +190,6 @@
<item>Mark entire folder read</item>
<item>Cancel</item>
</string-array>
<string name="settings_social">Social</string>
<string name="settings_show_public_comments">Show Public Comments</string>
</resources>

View file

@ -11,7 +11,7 @@ public class BlurDatabase extends SQLiteOpenHelper {
private final String TEXT = " text";
private final String INTEGER = " integer";
public final static String DB_NAME = "blur.db";
private final static int VERSION = 1;
private final static int VERSION = 2;
public BlurDatabase(Context context) {
super(context, DB_NAME, null, VERSION);
@ -44,7 +44,8 @@ public class BlurDatabase extends SQLiteOpenHelper {
private final String USER_SQL = "CREATE TABLE " + DatabaseConstants.USER_TABLE + " (" +
DatabaseConstants.USER_PHOTO_URL + TEXT + ", " +
DatabaseConstants.USER_USERID + INTEGER + " PRIMARY KEY, " +
DatabaseConstants.USER_USERNAME + TEXT + ")";
DatabaseConstants.USER_USERNAME + TEXT + ", " +
DatabaseConstants.USER_LOCATION + TEXT + ")";
private final String SOCIAL_FEED_SQL = "CREATE TABLE " + DatabaseConstants.SOCIALFEED_TABLE + " (" +
DatabaseConstants.SOCIAL_FEED_ID + INTEGER + " PRIMARY KEY, " +

View file

@ -66,7 +66,8 @@ public class DatabaseConstants {
public static final String USER_TABLE = "user_table";
public static final String USER_USERID = BaseColumns._ID;
public static final String USER_USERNAME = "username";
public static final String USER_USERNAME = "username";
public static final String USER_LOCATION = "location";
public static final String USER_PHOTO_URL = "photo_url";
public static final String STORY_TABLE = "stories";

View file

@ -15,8 +15,9 @@ public class UserProfile {
@SerializedName("user_id")
public String userId;
public String username;
public String username;
public String location;
public static UserProfile fromCursor(final Cursor c) {
if (c.isBeforeFirst()) {
@ -26,7 +27,8 @@ public class UserProfile {
UserProfile profile = new UserProfile();
profile.userId = c.getString(c.getColumnIndex(DatabaseConstants.USER_USERID));
profile.photoUrl = c.getString(c.getColumnIndex(DatabaseConstants.USER_PHOTO_URL));
profile.username = c.getString(c.getColumnIndex(DatabaseConstants.USER_USERNAME));
profile.username = c.getString(c.getColumnIndex(DatabaseConstants.USER_USERNAME));
profile.location = c.getString(c.getColumnIndex(DatabaseConstants.USER_LOCATION));
return profile;
}
@ -35,7 +37,8 @@ public class UserProfile {
final ContentValues values = new ContentValues();
values.put(DatabaseConstants.USER_PHOTO_URL, photoUrl);
values.put(DatabaseConstants.USER_USERID, userId);
values.put(DatabaseConstants.USER_USERNAME, username);
values.put(DatabaseConstants.USER_USERNAME, username);
values.put(DatabaseConstants.USER_LOCATION, location);
return values;
}

View file

@ -11,11 +11,13 @@ import android.graphics.Color;
import android.graphics.drawable.TransitionDrawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ScaleDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.text.Html;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
@ -170,10 +172,9 @@ public class ReadingItemFragment extends Fragment implements ClassifierDialogFra
}
private void setupSaveButton() {
Button saveButton = (Button) view.findViewById(R.id.save_story_button);
saveButton.setOnClickListener(new OnClickListener() {
saveButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
FeedUtils.saveStory(story, getActivity(), apiManager);
@ -253,7 +254,7 @@ public class ReadingItemFragment extends Fragment implements ClassifierDialogFra
itemFeed.setText(feedTitle);
}
itemTitle.setText(story.title);
itemTitle.setText(Html.fromHtml(story.title));
itemDate.setText(story.longDate);
if (!TextUtils.isEmpty(story.authors)) {
@ -409,11 +410,18 @@ public class ReadingItemFragment extends Fragment implements ClassifierDialogFra
View commentView = inflater.inflate(R.layout.include_comment, null);
commentView.setTag(SetupCommentSectionTask.COMMENT_VIEW_BY + user.id);
TextView commentText = (TextView) commentView.findViewById(R.id.comment_text);
commentText.setTag("commentBy" + user.id);
commentText.setText(sharedText);
TextView commentText = (TextView) commentView.findViewById(R.id.comment_text);
commentText.setTag("commentBy" + user.id);
commentText.setText(sharedText);
if (PrefsUtils.getUserImage(getActivity()) != null) {
TextView commentLocation = (TextView) commentView.findViewById(R.id.comment_location);
if (!TextUtils.isEmpty(user.location)) {
commentLocation.setText(user.location.toUpperCase());
} else {
commentLocation.setVisibility(View.GONE);
}
if (PrefsUtils.getUserImage(getActivity()) != null) {
ImageView commentImage = (ImageView) commentView.findViewById(R.id.comment_user_image);
commentImage.setImageBitmap(UIUtils.roundCorners(PrefsUtils.getUserImage(getActivity()), 10f));
}

View file

@ -8,6 +8,7 @@ import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.text.Editable;
import android.text.Html;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.LayoutInflater;
@ -108,7 +109,7 @@ public class ShareDialogFragment extends DialogFragment {
public void onTextChanged(CharSequence s, int start, int before, int count) { }
});
message.setText(String.format(shareString, story.title));
message.setText(String.format(shareString, Html.fromHtml(story.title)));
if (hasBeenShared) {
shareButton.setText(R.string.edit);

View file

@ -76,6 +76,12 @@ public class SetupCommentSectionTask extends AsyncTask<Void, Void, Void> {
while (commentCursor.moveToNext()) {
final Comment comment = Comment.fromCursor(commentCursor);
// skip public comments if they are disabled
if (!comment.byFriend && !PrefsUtils.showPublicComments(context)) {
continue;
}
View commentView = inflater.inflate(R.layout.include_comment, null);
commentView.setTag(COMMENT_VIEW_BY + comment.userId);
@ -87,7 +93,7 @@ public class SetupCommentSectionTask extends AsyncTask<Void, Void, Void> {
ImageView commentImage = (ImageView) commentView.findViewById(R.id.comment_user_image);
TextView commentSharedDate = (TextView) commentView.findViewById(R.id.comment_shareddate);
commentSharedDate.setText(comment.sharedDate.toUpperCase() + " AGO");
commentSharedDate.setText(comment.sharedDate + " ago");
commentSharedDate.setTag(COMMENT_DATE_BY + comment.userId);
final FlowLayout favouriteContainer = (FlowLayout) commentView.findViewById(R.id.comment_favourite_avatars);
@ -167,7 +173,7 @@ public class SetupCommentSectionTask extends AsyncTask<Void, Void, Void> {
}
TextView replySharedDate = (TextView) replyView.findViewById(R.id.reply_shareddate);
replySharedDate.setText(reply.shortDate.toUpperCase() + " AGO");
replySharedDate.setText(reply.shortDate + " ago");
((LinearLayout) commentView.findViewById(R.id.comment_replies_container)).addView(replyView);
}
@ -179,7 +185,14 @@ public class SetupCommentSectionTask extends AsyncTask<Void, Void, Void> {
commentUsername.setText(commentUser.username);
String userPhoto = commentUser.photoUrl;
if (!TextUtils.isEmpty(comment.sourceUserId)) {
TextView commentLocation = (TextView) commentView.findViewById(R.id.comment_location);
if (!TextUtils.isEmpty(commentUser.location)) {
commentLocation.setText(commentUser.location.toUpperCase());
} else {
commentLocation.setVisibility(View.GONE);
}
if (!TextUtils.isEmpty(comment.sourceUserId)) {
commentImage.setVisibility(View.INVISIBLE);
ImageView usershareImage = (ImageView) commentView.findViewById(R.id.comment_user_reshare_image);
ImageView sourceUserImage = (ImageView) commentView.findViewById(R.id.comment_sharesource_image);
@ -270,7 +283,8 @@ public class SetupCommentSectionTask extends AsyncTask<Void, Void, Void> {
commentCount = commentCount.substring(0, commentCount.length() - 1);
}
publicCommentTotal.setText(String.format(commentCount, publicCommentViews.size()));
}
viewHolder.get().findViewById(R.id.reading_public_comment_header).setVisibility(View.VISIBLE);
}
if (friendCommentViews.size() > 0) {
String commentCount = context.getString(R.string.friends_comments_count);
@ -278,7 +292,8 @@ public class SetupCommentSectionTask extends AsyncTask<Void, Void, Void> {
commentCount = commentCount.substring(0, commentCount.length() - 1);
}
friendCommentTotal.setText(String.format(commentCount, friendCommentViews.size()));
}
viewHolder.get().findViewById(R.id.reading_friend_comment_header).setVisibility(View.VISIBLE);
}
for (int i = 0; i < publicCommentViews.size(); i++) {
if (i == publicCommentViews.size() - 1) {

View file

@ -15,6 +15,7 @@ import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.text.Html;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
@ -260,9 +261,10 @@ public class FeedUtils {
Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.setType("text/plain");
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
intent.putExtra(Intent.EXTRA_SUBJECT, story.title);
intent.putExtra(Intent.EXTRA_SUBJECT, Html.fromHtml(story.title));
final String shareString = context.getResources().getString(R.string.share);
intent.putExtra(Intent.EXTRA_TEXT, String.format(shareString, new Object[] { story.title, story.permalink }));
intent.putExtra(Intent.EXTRA_TEXT, String.format(shareString, new Object[] { Html.fromHtml(story.title),
story.permalink }));
context.startActivity(Intent.createChooser(intent, "Share using"));
}
}

View file

@ -36,4 +36,6 @@ public class PrefConstants {
public static final String DEFAULT_STORY_ORDER = "default_story_order";
public static final String DEFAULT_READ_FILTER = "default_read_filter";
public static final String SHOW_PUBLIC_COMMENTS = "show_public_comments";
}

View file

@ -234,4 +234,9 @@ public class PrefsUtils {
private static ReadFilter getDefaultReadFilter(SharedPreferences prefs) {
return ReadFilter.valueOf(prefs.getString(PrefConstants.DEFAULT_READ_FILTER, ReadFilter.ALL.toString()));
}
public static boolean showPublicComments(Context context) {
SharedPreferences prefs = context.getSharedPreferences(PrefConstants.PREFERENCES, 0);
return prefs.getBoolean(PrefConstants.SHOW_PUBLIC_COMMENTS, true);
}
}

View file

@ -19,7 +19,7 @@ gunicorn==0.17.2
httplib2==0.8
iconv==1.0
kombu==2.5.7
lxml==3.1.0
# lxml==3.1.0
mongoengine==0.8.2
nltk==2.0.4
oauth2==1.5.211

View file

@ -3809,7 +3809,7 @@ background: transparent;
#story_taskbar .NB-tryfeed-add,
#story_taskbar .NB-tryfeed-follow,
#story_taskbar .NB-tryout-signup {
margin: 6px auto 0px;
margin: 2px auto 0px;
width: 80px;
height: 14px;
text-align: center;

View file

@ -35,6 +35,7 @@ NEWSBLUR.Modal.prototype = {
});
setTimeout(function() {
// $(window).resize();
self.resize();
self.flags.modal_loaded = true;
});
});
@ -60,6 +61,7 @@ NEWSBLUR.Modal.prototype = {
resize: function() {
// $(window).trigger('resize.simplemodal');
$.modal.resize();
},
close: function(callback) {

View file

@ -20,6 +20,9 @@ NEWSBLUR.ReaderAccount.prototype.constructor = NEWSBLUR.ReaderAccount;
_.extend(NEWSBLUR.ReaderAccount.prototype, {
runner: function() {
this.options.onOpen = _.bind(function() {
// $(window).resize();
}, this);
this.make_modal();
this.open_modal();

View file

@ -82,6 +82,9 @@
return $.modal.impl.init(data, options);
};
$.modal.resize = function (callback) {
$.modal.impl.resize(callback);
};
/*
* Close the modal dialog.
*/
@ -391,22 +394,24 @@
});
// update window size
$(window).bind('resize.simplemodal', function () {
// redetermine the window width/height
w = s.getDimensions();
$(window).bind('resize.simplemodal', _.bind(this.resize_modal, this));
},
resize_modal: function () {
// redetermine the window width/height
w = this.getDimensions();
// reposition the dialog
s.o.autoResize ? s.setContainerDimensions() : s.o.autoPosition && s.setPosition();
// reposition the dialog
this.o.autoResize ? this.setContainerDimensions() : this.o.autoPosition && this.setPosition();
if (ie6 || ieQuirks) {
s.fixIE();
}
else if (s.o.modal) {
// update the iframe & overlay
s.d.iframe && s.d.iframe.css({height: w[0], width: w[1]});
s.d.overlay.css({height: w[0], width: w[1]});
}
});
if (ie6 || ieQuirks) {
this.fixIE();
}
else if (this.o.modal) {
// update the iframe & overlay
this.d.iframe && this.d.iframe.css({height: w[0], width: w[1]});
this.d.overlay.css({height: w[0], width: w[1]});
}
},
/*
* Unbind events

View file

@ -17,8 +17,10 @@ from vendor import reseekfile
# COMMENTS_RE = re.compile('\<![ \r\n\t]*(--([^\-]|[\r\n]|-[^\-])*--[ \r\n\t]*)\>')
COMMENTS_RE = re.compile('\<!--.*?--\>')
def midnight_today():
return datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
def midnight_today(now=None):
if not now:
now = datetime.datetime.now()
return now.replace(hour=0, minute=0, second=0, microsecond=0, tzinfo=None)
def midnight_yesterday(midnight=None):
if not midnight:
@ -28,9 +30,11 @@ def midnight_yesterday(midnight=None):
def beginning_of_this_month():
return datetime.datetime.now().replace(day=1, hour=0, minute=0, second=0, microsecond=0)
def format_story_link_date__short(date):
def format_story_link_date__short(date, now=None):
if not now:
now = datetime.datetime.now()
date = date.replace(tzinfo=None)
midnight = midnight_today()
midnight = midnight_today(now)
if date > midnight:
return date.strftime('%I:%M%p').lstrip('0').lower()
elif date > midnight_yesterday(midnight):