mirror of
https://github.com/viq/NewsBlur.git
synced 2025-09-18 21:43:31 +00:00
Adding dashboard date and auto-highlighting new interactions, to be cleared on dashboard view.
This commit is contained in:
parent
1f18f0e8dc
commit
74bb4780ea
8 changed files with 113 additions and 14 deletions
84
apps/profile/migrations/0019_dashboard_date.py
Normal file
84
apps/profile/migrations/0019_dashboard_date.py
Normal file
|
@ -0,0 +1,84 @@
|
|||
# encoding: utf-8
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Adding field 'Profile.dashboard_date'
|
||||
db.add_column('profile_profile', 'dashboard_date', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now), keep_default=False)
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Deleting field 'Profile.dashboard_date'
|
||||
db.delete_column('profile_profile', 'dashboard_date')
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||
},
|
||||
'auth.permission': {
|
||||
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
|
||||
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
'auth.user': {
|
||||
'Meta': {'object_name': 'User'},
|
||||
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||
},
|
||||
'contenttypes.contenttype': {
|
||||
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
},
|
||||
'profile.profile': {
|
||||
'Meta': {'object_name': 'Profile'},
|
||||
'collapsed_folders': ('django.db.models.fields.TextField', [], {'default': "'[]'"}),
|
||||
'dashboard_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'feed_pane_size': ('django.db.models.fields.IntegerField', [], {'default': '240'}),
|
||||
'has_found_friends': ('django.db.models.fields.NullBooleanField', [], {'default': 'False', 'null': 'True', 'blank': 'True'}),
|
||||
'has_setup_feeds': ('django.db.models.fields.NullBooleanField', [], {'default': 'False', 'null': 'True', 'blank': 'True'}),
|
||||
'has_trained_intelligence': ('django.db.models.fields.NullBooleanField', [], {'default': 'False', 'null': 'True', 'blank': 'True'}),
|
||||
'hide_getting_started': ('django.db.models.fields.NullBooleanField', [], {'default': 'False', 'null': 'True', 'blank': 'True'}),
|
||||
'hide_mobile': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'is_premium': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'last_seen_ip': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
|
||||
'last_seen_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'preferences': ('django.db.models.fields.TextField', [], {'default': "'{}'"}),
|
||||
'secret_token': ('django.db.models.fields.CharField', [], {'max_length': '12', 'null': 'True', 'blank': 'True'}),
|
||||
'send_emails': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'stripe_4_digits': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}),
|
||||
'stripe_id': ('django.db.models.fields.CharField', [], {'max_length': '24', 'null': 'True', 'blank': 'True'}),
|
||||
'timezone': ('vendor.timezones.fields.TimeZoneField', [], {'default': "'America/New_York'", 'max_length': '100'}),
|
||||
'tutorial_finished': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'profile'", 'unique': 'True', 'to': "orm['auth.User']"}),
|
||||
'view_settings': ('django.db.models.fields.TextField', [], {'default': "'{}'"})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['profile']
|
|
@ -36,6 +36,7 @@ class Profile(models.Model):
|
|||
hide_mobile = models.BooleanField(default=False)
|
||||
last_seen_on = models.DateTimeField(default=datetime.datetime.now)
|
||||
last_seen_ip = models.CharField(max_length=50, blank=True, null=True)
|
||||
dashboard_date = models.DateTimeField(default=datetime.datetime.now)
|
||||
timezone = TimeZoneField(default="America/New_York")
|
||||
secret_token = models.CharField(max_length=12, blank=True, null=True)
|
||||
stripe_4_digits = models.CharField(max_length=4, blank=True, null=True)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import stripe
|
||||
import datetime
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.views.decorators.http import require_POST
|
||||
from django.http import HttpResponse, HttpResponseRedirect
|
||||
|
@ -22,7 +23,7 @@ from vendor.paypal.standard.forms import PayPalPaymentsForm
|
|||
SINGLE_FIELD_PREFS = ('timezone','feed_pane_size','hide_mobile','send_emails',
|
||||
'hide_getting_started', 'has_setup_feeds', 'has_found_friends',
|
||||
'has_trained_intelligence',)
|
||||
SPECIAL_PREFERENCES = ('old_password', 'new_password', 'autofollow_friends',)
|
||||
SPECIAL_PREFERENCES = ('old_password', 'new_password', 'autofollow_friends', 'dashboard_date',)
|
||||
|
||||
@ajax_login_required
|
||||
@require_POST
|
||||
|
@ -41,8 +42,9 @@ def set_preference(request):
|
|||
if preference_name == 'autofollow_friends':
|
||||
social_services = MSocialServices.objects.get(user_id=request.user.pk)
|
||||
social_services.autofollow = preference_value
|
||||
print social_services.autofollow
|
||||
social_services.save()
|
||||
elif preference_name == 'dashboard_date':
|
||||
request.user.profile.dashboard_date = datetime.datetime.utcnow()
|
||||
else:
|
||||
if preference_value in ["true", "false"]:
|
||||
preference_value = True if preference_value == "true" else False
|
||||
|
|
|
@ -220,6 +220,9 @@ def load_feeds(request):
|
|||
social_feeds = MSocialSubscription.feeds(**social_params)
|
||||
social_profile = MSocialProfile.profile(user.pk)
|
||||
|
||||
user.profile.dashboard_date = datetime.datetime.now()
|
||||
user.profile.save()
|
||||
|
||||
data = {
|
||||
'feeds': feeds,
|
||||
'social_feeds': social_feeds,
|
||||
|
|
|
@ -16,6 +16,7 @@ from apps.reader.models import UserSubscription, MUserStory
|
|||
from apps.analyzer.models import MClassifierFeed, MClassifierAuthor, MClassifierTag, MClassifierTitle
|
||||
from apps.analyzer.models import apply_classifier_titles, apply_classifier_feeds, apply_classifier_authors, apply_classifier_tags
|
||||
from apps.rss_feeds.models import Feed, MStory
|
||||
from apps.profile.models import Profile
|
||||
from vendor import facebook
|
||||
from vendor import tweepy
|
||||
from utils import log as logging
|
||||
|
@ -1176,6 +1177,8 @@ class MInteraction(mongo.Document):
|
|||
|
||||
@classmethod
|
||||
def user(cls, user_id, page=1):
|
||||
user_profile = Profile.objects.get(user=user_id)
|
||||
dashboard_date = user_profile.dashboard_date or user_profile.last_seen_on
|
||||
page = max(1, page)
|
||||
limit = 4 # Also set in template
|
||||
offset = (page-1) * limit
|
||||
|
@ -1190,7 +1193,9 @@ class MInteraction(mongo.Document):
|
|||
if social_profile:
|
||||
interaction['photo_url'] = social_profile.profile_photo_url
|
||||
interaction['with_user'] = social_profiles.get(interaction_db.with_user_id)
|
||||
interaction['date'] = relative_timesince(interaction_db.date)
|
||||
interaction['time_since'] = relative_timesince(interaction_db.date)
|
||||
interaction['date'] = interaction_db.date
|
||||
interaction['is_new'] = interaction_db.date > dashboard_date
|
||||
interactions.append(interaction)
|
||||
|
||||
return interactions
|
||||
|
@ -1255,6 +1260,8 @@ class MActivity(mongo.Document):
|
|||
|
||||
@classmethod
|
||||
def user(cls, user_id, page=1, public=False):
|
||||
user_profile = Profile.objects.get(user=user_id)
|
||||
dashboard_date = user_profile.dashboard_date or user_profile.last_seen_on
|
||||
page = max(1, page)
|
||||
limit = 4 # Also set in template
|
||||
offset = (page-1) * limit
|
||||
|
@ -1268,10 +1275,12 @@ class MActivity(mongo.Document):
|
|||
activities = []
|
||||
for activity_db in activities_db:
|
||||
activity = activity_db.to_json()
|
||||
activity['date'] = relative_timesince(activity_db.date)
|
||||
activity['date'] = activity_db.date
|
||||
activity['time_since'] = relative_timesince(activity_db.date)
|
||||
social_profile = social_profiles.get(activity_db.with_user_id)
|
||||
if social_profile:
|
||||
activity['photo_url'] = social_profile.profile_photo_url
|
||||
activity['is_new'] = activity_db.date > dashboard_date
|
||||
activity['with_user'] = social_profiles.get(activity_db.with_user_id)
|
||||
activities.append(activity)
|
||||
|
||||
|
|
|
@ -395,7 +395,7 @@
|
|||
if (!skip_router) {
|
||||
NEWSBLUR.router.navigate('');
|
||||
}
|
||||
|
||||
this.model.preference('dashboard_date', new Date);
|
||||
},
|
||||
|
||||
iframe_buster_buster: function() {
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
<ul class="NB-interactions">
|
||||
{% for activity in activities|slice:":4" %}
|
||||
<li class="NB-interaction NB-interaction-{{ activity.category }}"
|
||||
<li class="NB-interaction NB-interaction-{{ activity.category }} {% if activity.is_new %}NB-highlighted{% endif %}"
|
||||
{% if activity.content_id %}data-content-id="{{ activity.content_id }}"{% endif %}
|
||||
{% if activity.feed_id %}data-feed-id="{{ activity.feed_id }}"{% endif %}
|
||||
{% if activity.with_user_id %}data-user-id="{{ activity.with_user_id }}"{% endif %}
|
||||
|
@ -25,7 +25,7 @@
|
|||
{% if activity.category == 'follow' %}
|
||||
<img class="NB-interaction-photo" src="{{ activity.photo_url }}" data-user-id="{{ activity.with_user_id }}">
|
||||
<div class="NB-interaction-date">
|
||||
{{ activity.date }} ago
|
||||
{{ activity.time_since }} ago
|
||||
</div>
|
||||
<div class="NB-interaction-title">
|
||||
{{ username }} followed
|
||||
|
@ -36,7 +36,7 @@
|
|||
{% if activity.category == 'comment_reply' %}
|
||||
<img class="NB-interaction-photo" src="/rss_feeds/icon/{{ activity.feed_id }}" data-feed-id="{{ activity.feed_id }}">
|
||||
<div class="NB-interaction-date">
|
||||
{{ activity.date }} ago
|
||||
{{ activity.time_since }} ago
|
||||
</div>
|
||||
<div class="NB-interaction-title">
|
||||
{{ username }} replied to <span class="NB-interaction-username NB-splash-link" data-user-id="{{ activity.with_user_id }}">{{ activity.with_user.username }}</span>:
|
||||
|
@ -49,7 +49,7 @@
|
|||
{% if activity.category == 'sharedstory' %}
|
||||
<img class="NB-interaction-photo" src="/rss_feeds/icon/{{ activity.feed_id }}" data-feed-id="{{ activity.feed_id }}">
|
||||
<div class="NB-interaction-date">
|
||||
{{ activity.date }} ago
|
||||
{{ activity.time_since }} ago
|
||||
</div>
|
||||
<div class="NB-interaction-title">
|
||||
{{ username }} shared <span class="NB-interaction-sharedstory-title NB-splash-link">{{ activity.title|truncatewords:6 }}</span>{% if activity.content %}:{% else %}.{% endif %}
|
||||
|
@ -64,7 +64,7 @@
|
|||
{% if activity.category == 'star' %}
|
||||
<img class="NB-interaction-photo" src="/rss_feeds/icon/{{ activity.feed_id }}">
|
||||
<div class="NB-interaction-date">
|
||||
{{ activity.date }} ago
|
||||
{{ activity.time_since }} ago
|
||||
</div>
|
||||
<div class="NB-interaction-title">
|
||||
You starred "<span class="NB-interaction-starred-story-title NB-splash-link">{{ activity.content|truncatewords:8 }}</span>".
|
||||
|
@ -74,7 +74,7 @@
|
|||
{% if activity.category == 'feedsub' %}
|
||||
<img class="NB-interaction-photo" src="/rss_feeds/icon/{{ activity.feed_id }}">
|
||||
<div class="NB-interaction-date">
|
||||
{{ activity.date }} ago
|
||||
{{ activity.time_since }} ago
|
||||
</div>
|
||||
<div class="NB-interaction-title">
|
||||
You subscribed to <span class="NB-interaction-feed-title NB-splash-link">{{ activity.content|truncatewords:8 }}</span>.
|
||||
|
|
|
@ -13,14 +13,14 @@
|
|||
|
||||
<ul class="NB-interactions">
|
||||
{% for interaction in interactions|slice:":4" %}
|
||||
<li class="NB-interaction NB-interaction-{{ interaction.category }}"
|
||||
<li class="NB-interaction NB-interaction-{{ interaction.category }} {% if interaction.is_new %}NB-highlighted{% endif %}"
|
||||
{% if interaction.content_id %}data-content-id="{{ interaction.content_id }}"{% endif %}
|
||||
{% if interaction.feed_id %}data-user-id="{{ interaction.feed_id }}"{% endif %}
|
||||
{% if interaction.with_user_id %}data-user-id="{{ interaction.with_user_id }}"{% endif %}>
|
||||
{% if interaction.category == 'follow' %}
|
||||
<img class="NB-interaction-photo" src="{{ interaction.photo_url }}" data-user-id="{{ interaction.with_user_id }}">
|
||||
<div class="NB-interaction-date">
|
||||
{{ interaction.date }} ago
|
||||
{{ interaction.time_since }} ago
|
||||
</div>
|
||||
<div class="NB-interaction-title">
|
||||
<span class="NB-interaction-username NB-splash-link" data-user-id="{{ interaction.with_user_id }}">
|
||||
|
@ -32,7 +32,7 @@
|
|||
{% if interaction.category == 'comment_reply' or interaction.category == 'reply_reply' %}
|
||||
<img class="NB-interaction-photo" src="{{ interaction.photo_url }}" data-user-id="{{ interaction.with_user_id }}">
|
||||
<div class="NB-interaction-date">
|
||||
{{ interaction.date }} ago
|
||||
{{ interaction.time_since }} ago
|
||||
</div>
|
||||
<div class="NB-interaction-title">
|
||||
<span class="NB-interaction-username NB-splash-link" data-user-id="{{ interaction.with_user_id }}">
|
||||
|
|
Loading…
Add table
Reference in a new issue