Merge remote-tracking branch 'upstream/master' into storyorder

This commit is contained in:
Mark Anderson 2013-05-26 20:48:11 +01:00
commit 3eb8441c2e
64 changed files with 318 additions and 3170 deletions

View file

@ -56,7 +56,11 @@ class MCategory(mongo.Document):
category_groups = groupby(sorted(category_sites, key=lambda c: c.category_title), key=lambda c: c.category_title)
for category_title, sites in category_groups:
category = cls.objects.get(title=category_title)
try:
category = cls.objects.get(title=category_title)
except cls.DoesNotExist, e:
print " ***> Missing category: %s" % category_title
continue
category.feed_ids = [site.feed_id for site in sites]
category.save()
print " ---> Reloaded category: %s" % category

View file

@ -20,13 +20,14 @@ from apps.reader.models import UserSubscription
from apps.rss_feeds.models import Feed, MStory
from apps.rss_feeds.tasks import NewFeeds
from apps.rss_feeds.tasks import SchedulePremiumSetup
from apps.feed_import.models import GoogleReaderImporter
from apps.feed_import.models import GoogleReaderImporter, OPMLExporter
from utils import log as logging
from utils import json_functions as json
from utils.user_functions import generate_secret_token
from vendor.timezones.fields import TimeZoneField
from vendor.paypal.standard.ipn.signals import subscription_signup, payment_was_successful
from vendor.paypal.standard.ipn.models import PayPalIPN
from vendor.paypalapi.interface import PayPalInterface
from zebra.signals import zebra_webhook_customer_subscription_created
from zebra.signals import zebra_webhook_charge_succeeded
@ -246,18 +247,51 @@ class Profile(models.Model):
stripe_customer = stripe.Customer.retrieve(self.stripe_id)
stripe_payments = stripe.Charge.all(customer=stripe_customer.id).data
stripe_payments[0].refund()
logging.user(self.user, "~FRRefunding stripe payment: $%s" % (stripe_payments[0].amount/100))
self.cancel_premium()
refunded = stripe_payments[0].amount/100
logging.user(self.user, "~FRRefunding stripe payment: $%s" % refunded)
self.cancel_premium()
else:
paypal_opts = {
'API_ENVIRONMENT': 'PRODUCTION',
'API_USERNAME': settings.PAYPAL_API_USERNAME,
'API_PASSWORD': settings.PAYPAL_API_PASSWORD,
'API_SIGNATURE': settings.PAYPAL_API_SIGNATURE,
}
paypal = PayPalInterface(**paypal_opts)
transaction = PayPalIPN.objects.filter(custom=self.user.username,
txn_type='subscr_payment')[0]
refund = paypal.refund_transaction(transaction.txn_id)
refunded = int(float(refund['raw']['TOTALREFUNDEDAMOUNT'][0]))
logging.user(self.user, "~FRRefunding paypal payment: $%s" % refunded)
self.cancel_premium()
return refunded
def cancel_premium(self):
self.cancel_premium_paypal()
return self.cancel_premium_stripe()
paypal_cancel = self.cancel_premium_paypal()
stripe_cancel = self.cancel_premium_stripe()
return paypal_cancel or stripe_cancel
def cancel_premium_paypal(self):
pass
transactions = PayPalIPN.objects.filter(custom=self.user.username,
txn_type='subscr_signup')
if not transactions:
return
paypal_opts = {
'API_ENVIRONMENT': 'PRODUCTION',
'API_USERNAME': settings.PAYPAL_API_USERNAME,
'API_PASSWORD': settings.PAYPAL_API_PASSWORD,
'API_SIGNATURE': settings.PAYPAL_API_SIGNATURE,
}
paypal = PayPalInterface(**paypal_opts)
transaction = transactions[0]
profileid = transaction.subscr_id
paypal.manage_recurring_payments_profile_status(profileid=profileid, action='Cancel')
logging.user(self.user, "~FRCanceling Paypal subscription")
return True
def cancel_premium_stripe(self):
if not self.stripe_id:
@ -270,7 +304,7 @@ class Profile(models.Model):
logging.user(self.user, "~FRCanceling Stripe subscription")
return True
def queue_new_feeds(self, new_feeds=None):
if not new_feeds:
new_feeds = UserSubscription.objects.filter(user=self.user,
@ -319,7 +353,34 @@ class Profile(models.Model):
msg.send(fail_silently=True)
logging.user(self.user, "~BB~FM~SBSending email for new user: %s" % self.user.email)
def send_opml_export_email(self):
if not self.user.email:
return
MSentEmail.objects.get_or_create(receiver_user_id=self.user.pk,
email_type='opml_export')
exporter = OPMLExporter(self.user)
opml = exporter.process()
params = {
'feed_count': UserSubscription.objects.filter(user=self.user).count(),
}
user = self.user
text = render_to_string('mail/email_opml_export.txt', params)
html = render_to_string('mail/email_opml_export.xhtml', params)
subject = "Backup OPML file of your NewsBlur sites"
filename= 'NewsBlur Subscriptions - %s.xml' % datetime.datetime.now().strftime('%Y-%m-%d')
msg = EmailMultiAlternatives(subject, text,
from_email='NewsBlur <%s>' % settings.HELLO_EMAIL,
to=['%s <%s>' % (user, user.email)])
msg.attach_alternative(html, "text/html")
msg.attach(filename, opml, 'text/xml')
msg.send(fail_silently=True)
logging.user(self.user, "~BB~FM~SBSending OPML backup email to: %s" % self.user.email)
def send_first_share_to_blurblog_email(self, force=False):
from apps.social.models import MSocialProfile, MSharedStory

View file

@ -21,4 +21,5 @@ urlpatterns = patterns('',
url(r'^delete_account/?', views.delete_account, name='profile-delete-account'),
url(r'^forgot_password_return/?', views.forgot_password_return, name='profile-forgot-password-return'),
url(r'^forgot_password/?', views.forgot_password, name='profile-forgot-password'),
url(r'^delete_all_sites/?', views.delete_all_sites, name='profile-delete-all-sites'),
)

View file

@ -13,7 +13,7 @@ from django.shortcuts import render_to_response
from django.core.mail import mail_admins
from django.conf import settings
from apps.profile.models import Profile, PaymentHistory, RNewUserQueue
from apps.reader.models import UserSubscription
from apps.reader.models import UserSubscription, UserSubscriptionFolders
from apps.profile.forms import StripePlusPaymentForm, PLANS, DeleteAccountForm
from apps.profile.forms import ForgotPasswordForm, ForgotPasswordReturnForm, AccountSettingsForm
from apps.social.models import MSocialServices, MActivity, MSocialProfile
@ -217,6 +217,7 @@ def stripe_form(request):
stripe.api_key = settings.STRIPE_SECRET
plan = int(request.GET.get('plan', 2))
plan = PLANS[plan-1][0]
error = None
if request.method == 'POST':
zebra_form = StripePlusPaymentForm(request.POST, email=user.email)
@ -224,19 +225,22 @@ def stripe_form(request):
user.email = zebra_form.cleaned_data['email']
user.save()
customer = stripe.Customer.create(**{
'card': zebra_form.cleaned_data['stripe_token'],
'plan': zebra_form.cleaned_data['plan'],
'email': user.email,
'description': user.username,
})
user.profile.strip_4_digits = zebra_form.cleaned_data['last_4_digits']
user.profile.stripe_id = customer.id
user.profile.save()
user.profile.activate_premium() # TODO: Remove, because webhooks are slow
try:
customer = stripe.Customer.create(**{
'card': zebra_form.cleaned_data['stripe_token'],
'plan': zebra_form.cleaned_data['plan'],
'email': user.email,
'description': user.username,
})
except stripe.CardError:
error = "This card was declined."
else:
user.profile.strip_4_digits = zebra_form.cleaned_data['last_4_digits']
user.profile.stripe_id = customer.id
user.profile.save()
user.profile.activate_premium() # TODO: Remove, because webhooks are slow
success_updating = True
success_updating = True
else:
zebra_form = StripePlusPaymentForm(email=user.email, plan=plan)
@ -262,6 +266,7 @@ def stripe_form(request):
'new_user_queue_count': new_user_queue_count - 1,
'new_user_queue_position': new_user_queue_position,
'new_user_queue_behind': new_user_queue_behind,
'error': error,
},
context_instance=RequestContext(request)
)
@ -389,4 +394,21 @@ def forgot_password_return(request):
return {
'forgot_password_return_form': form,
}
}
@ajax_login_required
@json.json_view
def delete_all_sites(request):
request.user.profile.send_opml_export_email()
subs = UserSubscription.objects.filter(user=request.user)
sub_count = subs.count()
subs.delete()
usf = UserSubscriptionFolders.objects.get(user=request.user)
usf.folders = '[]'
usf.save()
logging.user(request.user, "~BC~FRDeleting %s sites" % sub_count)
return dict(code=1)

View file

@ -44,6 +44,7 @@ def load_recommended_feed(request):
'has_previous_page' : page != 0,
'unmoderated' : unmoderated,
'today' : datetime.datetime.now(),
'page' : page,
}, context_instance=RequestContext(request))
else:
return HttpResponse("")

View file

@ -52,7 +52,7 @@ class TaskFeeds(Task):
cp2 = time.time()
# Mistakenly inactive feeds
hours_ago = (now - datetime.timedelta(hours=1)).strftime('%s')
hours_ago = (now - datetime.timedelta(minutes=10)).strftime('%s')
old_tasked_feeds = r.zrangebyscore('tasked_feeds', 0, hours_ago)
inactive_count = len(old_tasked_feeds)
if inactive_count:

View file

@ -2014,7 +2014,7 @@ class MSocialServices(mongo.Document):
},
'gravatar': {
'gravatar_picture_url': "https://www.gravatar.com/avatar/" + \
hashlib.md5(user.email).hexdigest()
hashlib.md5(user.email.lower()).hexdigest()
},
'upload': {
'upload_picture_url': self.upload_picture_url

View file

@ -61,7 +61,7 @@ listen_addresses = '*' # what IP address(es) to listen on;
# defaults to 'localhost', '*' = all
# (change requires restart)
port = 5432 # (change requires restart)
max_connections = 200 # (change requires restart)
max_connections = 1000 # (change requires restart)
# Note: Increasing max_connections costs ~400 bytes of shared memory per
# connection slot, plus lock space (see max_locks_per_transaction).
#superuser_reserved_connections = 3 # (change requires restart)
@ -115,8 +115,8 @@ shared_buffers = 512MB # min 128kB
# per transaction slot, plus lock space (see max_locks_per_transaction).
# It is not advisable to set max_prepared_transactions nonzero unless you
# actively intend to use prepared transactions.
work_mem = 64MB # min 64kB
maintenance_work_mem = 2GB # min 1MB
work_mem = 5MB # min 64kB
maintenance_work_mem = 512MB # min 1MB
#max_stack_depth = 2MB # min 100kB
# - Kernel Resource Usage -
@ -411,7 +411,7 @@ log_line_prefix = '%t %h' # special values:
# AUTOVACUUM PARAMETERS
#------------------------------------------------------------------------------
#autovacuum = on # Enable autovacuum subprocess? 'on'
autovacuum = on # Enable autovacuum subprocess? 'on'
# requires track_counts to also be on.
#log_autovacuum_min_duration = -1 # -1 disables, 0 logs all actions and
# their durations, > 0 logs only

1
fabfile.py vendored
View file

@ -1064,6 +1064,7 @@ def setup_do(name, size=2):
env.host_string = host
time.sleep(10)
add_user_to_do()
do()
def do_name(name):
if re.search(r"[0-9]", name):

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 720 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 715 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

View file

@ -1,8 +0,0 @@
<?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/white" />
</shape>
</item>
</layer-list>

View file

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<size android:height="1dp"/>
<solid android:color="#ff0000" />
</shape>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

View file

@ -0,0 +1,8 @@
<?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>

View file

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

View file

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

View file

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<gradient
android:angle="270"
android:endColor="#1e78c1"
android:startColor="#42aaff" />
<corners
android:bottomLeftRadius="5dp"
android:bottomRightRadius="5dp"
android:topLeftRadius="5dp"
android:topRightRadius="5dp" />
</shape>

View file

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<gradient
android:angle="270"
android:endColor="#2379bf"
android:startColor="#1e78c1" />
<corners
android:bottomLeftRadius="5dp"
android:bottomRightRadius="5dp"
android:topLeftRadius="5dp"
android:topRightRadius="5dp" />
</shape>

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/list_background_pressed" />
<item android:state_pressed="true" android:drawable="@drawable/gradient_activation_highlight" />
<item android:drawable="@drawable/feed_background_default" />
</selector>
</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/list_background_pressed" />
<item android:state_pressed="true" android:drawable="@drawable/gradient_activation_highlight" />
<item android:drawable="@drawable/gradient_background_default" />
</selector>

View file

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<gradient
android:angle="270"
android:endColor="#1e78c1"
android:startColor="#42aaff" />
<corners
android:bottomLeftRadius="5dp"
android:bottomRightRadius="5dp"
android:topLeftRadius="5dp"
android:topRightRadius="5dp" />
</shape>

View file

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<gradient
android:angle="270"
android:endColor="#2379bf"
android:startColor="#1e78c1" />
<corners
android:bottomLeftRadius="5dp"
android:bottomRightRadius="5dp"
android:topLeftRadius="5dp"
android:topRightRadius="5dp" />
</shape>

View file

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<gradient
android:angle="270"
android:endColor="#0000"
android:centerColor="#10ffffff"
android:startColor="#88ffffff" />
<corners android:radius="2dp" />
<padding
android:top="3dp"
android:left="4dp"
android:right="4dp" />
</shape>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 303 B

View file

@ -1,24 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<Button
android:id="@+id/share_story_button"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:padding="10dp"
android:text="@string/share_this" />
<Button
android:id="@+id/save_story_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:padding="10dp"
android:text="@string/save_this" />
android:orientation="horizontal"
android:layout_marginTop="15dp" >
<Button
android:id="@+id/share_story_button"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:padding="10dp"
android:text="@string/share_this" />
<Button
android:id="@+id/save_story_button"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:padding="10dp"
android:text="@string/save_this" />
</LinearLayout>
<RelativeLayout
android:id="@+id/reading_shared_container"

View file

@ -2,17 +2,16 @@
<resources>
<color name="white">#FFF</color>
<color name="black">#000</color>
<color name="darkgray">#434343</color>
<color name="hintgray">#66bbbbbb</color>
<color name="midgray">#bbbbbb</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_text">#4C4C4C</color>
<color name="feed_background">#F7F8F5</color>
<color name="feed_title_text_background">#606060</color>
<color name="story_title_unread">#606060</color>
<color name="story_title_read">#C0C0C0</color>
@ -26,36 +25,26 @@
<color name="twitter_blue">#4099FF</color>
<color name="facebook_blue">#3B5998</color>
<color name="comment_background">#f5f9fb</color>
<color name="lightgreen">#3b8207</color>
<color name="darkgreen">#134c00</color>
<color name="item_background">#f5f5f5</color>
<color name="half_black">#7000</color>
<color name="nearblack">#2b2b2b</color>
<color name="transparent">#0000</color>
<color name="half_darkgray">#77434343</color>
<color name="half_lightgray">#77dddddd</color>
<color name="positive">#6EA74A</color>
<color name="positive_drop_shadow">#417E53</color>
<color name="positive_read">#A8CA92</color>
<color name="highlight">#fef7ab</color>
<color name="darkneutral">#C59A00</color>
<color name="neutral">#B3B6AD</color>
<color name="neutral_drop_shadow">#93968D</color>
<color name="neutral_read">#CACCC6</color>
<color name="linkblue">#405BA8</color>
<color name="negative">#CC2A2E</color>
<color name="negative_drop_shadow">#A32225</color>
<color name="darknegative">#D65558</color>
<color name="tag_red">#D2A1A1</color>
<color name="tag_green">#BECCA4</color>

View file

@ -6,20 +6,15 @@
<string name="login_password_hint">password</string>
<string name="login_registration_email_hint">email address</string>
<string name="login_button_login">Log In</string>
<string name="login_button_signup">Sign Up</string>
<string name="login_message_error">There was problem connecting to NewsBlur. Check your internet connection.</string>
<string name="login_logging_in">Logging in…</string>
<string name="login_logged_in">Logged in!</string>
<string name="login_retrieving_feeds">Retrieving feeds…</string>
<string name="login_retrieved_feeds">Retrieved feeds!</string>
<string name="login_next">Next</string>
<string name="title_feed_search">Search for feeds</string>
<string name="add_feed_message">Add \"%s\" to your feeds?</string>
<string name="train_on">Train on \"%s\"</string>
<string name="dialog_title">Alert</string>
<string name="loading">Loading…</string>
<string name="edit">Shared</string>
@ -28,7 +23,6 @@
<string name="description_login_button">Press to log in.</string>
<string name="description_login_logo">NewsBlur Logo</string>
<string name="description_signup_button">Press to sign up</string>
<string name="description_favicon">The feed\'s favicon</string>
<string name="description_profile_picture">The user\'s profile picture</string>
<string name="description_row_folder_icon">folder icon</string>
@ -49,7 +43,6 @@
<string name="replied">Reply posted</string>
<string name="error_replying">There was an error replying</string>
<string name="share">\"%1$s\" - %2$s</string>
<string name="shared_title">Share</string>
<string name="share_this">Share this story</string>
<string name="share_comment_hint">Comment (Optional)</string>
<string name="shared">Story shared</string>
@ -69,7 +62,6 @@
<string name="profile_following">FOLLOWING</string>
<string name="profile_followers">FOLLOWERS</string>
<string name="profile_shared">SHARED STORIES</string>
<string name="profile_subscribers">subscribers</string>
<string name="profile_no_bio">No bio included</string>
<string name="profile_no_location">Location not set</string>
<string name="profile_ago">AGO</string>
@ -114,7 +106,6 @@
<string name="menu_mark_all_as_read">Mark all as read</string>
<string name="menu_logout">Log out</string>
<string name="feed_deleted">Feed deleted</string>
<string name="error_deleting_feed">There was an error deleting the feed.</string>
<string name="login_registration_register">Register</string>
<string name="login_google_reader">Google Reader</string>

View file

@ -33,7 +33,7 @@ public class FolderTreeViewBinder implements ViewBinder {
if (TextUtils.equals(cursor.getColumnName(columnIndex), DatabaseConstants.FEED_FAVICON_URL)) {
if (cursor.getString(columnIndex) != null) {
String imageUrl = cursor.getString(columnIndex);
imageLoader.displayImage(imageUrl, (ImageView)view);
imageLoader.displayImage(imageUrl, (ImageView)view, false);
} else {
Bitmap bitmap = BitmapFactory.decodeResource(view.getContext().getResources(), R.drawable.world);
((ImageView) view).setImageBitmap(bitmap);

View file

@ -46,7 +46,7 @@ public class SocialFeedViewBinder implements ViewBinder {
return true;
} else if (TextUtils.equals(cursor.getColumnName(columnIndex), DatabaseConstants.SOCIAL_FEED_ICON)) {
String url = cursor.getString(columnIndex);
imageLoader.displayImage(url, (ImageView) view);
imageLoader.displayImage(url, (ImageView) view, false);
return true;
} else if (TextUtils.equals(cursor.getColumnName(columnIndex), DatabaseConstants.SOCIAL_FEED_NEGATIVE_COUNT)) {
int feedNegative = cursor.getInt(columnIndex);

View file

@ -125,6 +125,7 @@
width: 100%;
margin-left: 150px;
text-transform: none;
color: darkred;
}
.NB-static-form #payment-form > div {

View file

@ -31,6 +31,7 @@ static const CGFloat kButtonWidth = 48.0f;
UIBarButtonItem* forward;
UIBarButtonItem* refresh;
UIBarButtonItem* pageAction;
UIBarButtonItem *switchViewButton;
UILabel *pageTitle;
UITextField *pageUrl;
UIToolbar *toolbar;
@ -43,6 +44,7 @@ static const CGFloat kButtonWidth = 48.0f;
@property (nonatomic) IBOutlet UIBarButtonItem* forward;
@property (nonatomic) IBOutlet UIBarButtonItem* refresh;
@property (nonatomic) IBOutlet UIBarButtonItem* pageAction;
@property (nonatomic) IBOutlet UIBarButtonItem* switchViewButton;
@property (nonatomic) IBOutlet UILabel *pageTitle;
@property (nonatomic) IBOutlet UITextField *pageUrl;
@property (nonatomic) IBOutlet UIToolbar *toolbar;
@ -57,5 +59,6 @@ static const CGFloat kButtonWidth = 48.0f;
- (void)updateTitle:(UIWebView*)aWebView;
- (void)updateAddress:(NSURLRequest*)request;
- (void)updateButtons;
- (IBAction)toggleView:(id)sender;
@end

View file

@ -27,6 +27,7 @@
@synthesize pageTitle;
@synthesize pageUrl;
@synthesize toolbar;
@synthesize switchViewButton;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
@ -108,11 +109,26 @@
[navBar addSubview:tools];
UIImage *switchImage = [UIImage imageNamed:@"nav_story_original.png"];
switchViewButton = [UIBarButtonItem barItemWithImage:switchImage target:self action:@selector(toggleView:)];
switchViewButton.width = switchImage.size.width;
CGRect switchViewFrame = CGRectMake(labelFrame.size.width - switchViewButton.width - kMargin,
kSpacer*2.0 + kLabelHeight - 7.0f,
switchViewButton.width,
44.0);
TransparentToolbar* switchTools = [[TransparentToolbar alloc]
initWithFrame:switchViewFrame];
[switchTools setItems:[NSArray arrayWithObject:switchViewButton] animated:NO];
[switchTools setTintColor:UIColorFromRGB(0x183353)];
[navBar addSubview:switchTools];
CGRect addressFrame = CGRectMake(closeButtonFrame.origin.x +
closeButtonFrame.size.width +
kMargin,
kSpacer*2.0 + kLabelHeight,
labelFrame.size.width - kButtonWidth - kMargin,
labelFrame.size.width - switchViewFrame.size.width
- kButtonWidth - kMargin*2,
kAddressHeight);
UITextField *address = [[UITextField alloc] initWithFrame:addressFrame];
address.autoresizingMask = UIViewAutoresizingFlexibleWidth;
@ -301,10 +317,14 @@
NSString *title = [appDelegate.activeStory
objectForKey:@"story_title"];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
[ShareThis showShareOptionsToShareUrl:url title:title image:nil onViewController:self.appDelegate.masterContainerViewController];
[ShareThis showShareOptionsToShareUrl:url title:title image:nil onViewController:self];
} else {
[ShareThis showShareOptionsToShareUrl:url title:title image:nil onViewController:self];
}
}
- (IBAction)toggleView:(id)sender {
NSLog(@"Toggle");
}
@end

View file

@ -36,7 +36,6 @@
433D24821582EEC000AE9E72 /* LoginViewController~ipad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 43D045241565BC150085F811 /* LoginViewController~ipad.xib */; };
433D24831582EEC300AE9E72 /* MainWindow~ipad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 43D0451F1565BC150085F811 /* MainWindow~ipad.xib */; };
433D24841582EEC500AE9E72 /* MoveSiteViewController~ipad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 43D045281565BC150085F811 /* MoveSiteViewController~ipad.xib */; };
433D24861582EECA00AE9E72 /* OriginalStoryViewController~ipad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 43D045251565BC150085F811 /* OriginalStoryViewController~ipad.xib */; };
433D24871582EECD00AE9E72 /* StoryDetailViewController~ipad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 43D045221565BC150085F811 /* StoryDetailViewController~ipad.xib */; };
436ACA8D15BF1088004E01CC /* NBContainerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 436ACA8C15BF1088004E01CC /* NBContainerViewController.m */; };
43763AD1158F90B100B3DBE2 /* FontSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 43763ACF158F90B100B3DBE2 /* FontSettingsViewController.m */; };
@ -633,7 +632,6 @@
43D0451F1565BC150085F811 /* MainWindow~ipad.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = "MainWindow~ipad.xib"; path = "Resources-iPad/MainWindow~ipad.xib"; sourceTree = "<group>"; };
43D045221565BC150085F811 /* StoryDetailViewController~ipad.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = "StoryDetailViewController~ipad.xib"; path = "Resources-iPad/Classes/StoryDetailViewController~ipad.xib"; sourceTree = "<group>"; };
43D045241565BC150085F811 /* LoginViewController~ipad.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = "LoginViewController~ipad.xib"; path = "Resources-iPad/Classes/LoginViewController~ipad.xib"; sourceTree = "<group>"; };
43D045251565BC150085F811 /* OriginalStoryViewController~ipad.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = "OriginalStoryViewController~ipad.xib"; path = "Resources-iPad/Classes/OriginalStoryViewController~ipad.xib"; sourceTree = "<group>"; };
43D045281565BC150085F811 /* MoveSiteViewController~ipad.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = "MoveSiteViewController~ipad.xib"; path = "Resources-iPad/Classes/MoveSiteViewController~ipad.xib"; sourceTree = "<group>"; };
43D818A115B940C200733444 /* DataUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataUtilities.h; sourceTree = "<group>"; };
43D818A215B940C200733444 /* DataUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DataUtilities.m; sourceTree = "<group>"; };
@ -1645,7 +1643,6 @@
43D0451F1565BC150085F811 /* MainWindow~ipad.xib */,
43D045281565BC150085F811 /* MoveSiteViewController~ipad.xib */,
FF67D3B816897AD80057A7DA /* TrainerViewController~ipad.xib */,
43D045251565BC150085F811 /* OriginalStoryViewController~ipad.xib */,
43D045221565BC150085F811 /* StoryDetailViewController~ipad.xib */,
437AA8C9159394E2005463F5 /* ShareViewController~ipad.xib */,
);
@ -2071,7 +2068,6 @@
433D24821582EEC000AE9E72 /* LoginViewController~ipad.xib in Resources */,
433D24831582EEC300AE9E72 /* MainWindow~ipad.xib in Resources */,
433D24841582EEC500AE9E72 /* MoveSiteViewController~ipad.xib in Resources */,
433D24861582EECA00AE9E72 /* OriginalStoryViewController~ipad.xib in Resources */,
433D24871582EECD00AE9E72 /* StoryDetailViewController~ipad.xib in Resources */,
433323B8158901A40025064D /* fountain_pen.png in Resources */,
433323B9158901A40025064D /* fountain_pen@2x.png in Resources */,
@ -2493,8 +2489,8 @@
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = Entitlements.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer: Samuel Clay (3PN8E5365D)";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Samuel Clay (3PN8E5365D)";
CODE_SIGN_IDENTITY = "iPhone Developer: Samuel Clay (G9HFWP68T7)";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Samuel Clay (G9HFWP68T7)";
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
@ -2517,8 +2513,8 @@
"-all_load",
);
PRODUCT_NAME = NewsBlur;
PROVISIONING_PROFILE = "0E4D73FC-DFF6-4E38-BA47-4A3F5AC9C6A2";
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "0E4D73FC-DFF6-4E38-BA47-4A3F5AC9C6A2";
PROVISIONING_PROFILE = "3A91A886-5038-41A3-B9DB-C1A1FF5F519B";
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "3A91A886-5038-41A3-B9DB-C1A1FF5F519B";
TARGETED_DEVICE_FAMILY = "1,2";
VALID_ARCHS = armv7;
"WARNING_CFLAGS[arch=*]" = "-Wall";
@ -2532,8 +2528,8 @@
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = Entitlements.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer: Samuel Clay (3PN8E5365D)";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Samuel Clay (3PN8E5365D)";
CODE_SIGN_IDENTITY = "iPhone Developer: Samuel Clay (G9HFWP68T7)";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Samuel Clay (G9HFWP68T7)";
COPY_PHASE_STRIP = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = NewsBlur_Prefix.pch;
@ -2553,8 +2549,8 @@
"-all_load",
);
PRODUCT_NAME = NewsBlur;
PROVISIONING_PROFILE = "0E4D73FC-DFF6-4E38-BA47-4A3F5AC9C6A2";
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "0E4D73FC-DFF6-4E38-BA47-4A3F5AC9C6A2";
PROVISIONING_PROFILE = "3A91A886-5038-41A3-B9DB-C1A1FF5F519B";
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "3A91A886-5038-41A3-B9DB-C1A1FF5F519B";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VALID_ARCHS = armv7;

View file

@ -2,10 +2,10 @@
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.10">
<data>
<int key="IBDocument.SystemTarget">1552</int>
<string key="IBDocument.SystemVersion">12C3006</string>
<string key="IBDocument.SystemVersion">12D78</string>
<string key="IBDocument.InterfaceBuilderVersion">3084</string>
<string key="IBDocument.AppKitVersion">1187.34</string>
<string key="IBDocument.HIToolboxVersion">625.00</string>
<string key="IBDocument.AppKitVersion">1187.37</string>
<string key="IBDocument.HIToolboxVersion">626.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">2083</string>
@ -5185,6 +5185,7 @@ AAgAAAAIAAIACAACAAAAAgAAAAEAAQABAAE</bytes>
<string>spacer3BarButton</string>
<string>spacerBarButton</string>
<string>storyTitlesTable</string>
<string>titleImageBarButton</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
@ -5197,6 +5198,7 @@ AAgAAAAIAAIACAACAAAAAgAAAAEAAQABAAE</bytes>
<string>UIBarButtonItem</string>
<string>UIBarButtonItem</string>
<string>UITableView</string>
<string>UIBarButtonItem</string>
</object>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
@ -5212,6 +5214,7 @@ AAgAAAAIAAIACAACAAAAAgAAAAEAAQABAAE</bytes>
<string>spacer3BarButton</string>
<string>spacerBarButton</string>
<string>storyTitlesTable</string>
<string>titleImageBarButton</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
@ -5251,6 +5254,10 @@ AAgAAAAIAAIACAACAAAAAgAAAAEAAQABAAE</bytes>
<string key="name">storyTitlesTable</string>
<string key="candidateClassName">UITableView</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">titleImageBarButton</string>
<string key="candidateClassName">UIBarButtonItem</string>
</object>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
@ -5298,53 +5305,6 @@ AAgAAAAIAAIACAACAAAAAgAAAAEAAQABAAE</bytes>
<string key="minorKey">./Classes/FeedsMenuViewController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">FindSitesViewController</string>
<string key="superclassName">UIViewController</string>
<object class="NSMutableDictionary" key="outlets">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>appDelegate</string>
<string>sitesSearchBar</string>
<string>sitesTable</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>NewsBlurAppDelegate</string>
<string>UISearchBar</string>
<string>UITableView</string>
</object>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>appDelegate</string>
<string>sitesSearchBar</string>
<string>sitesTable</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBToOneOutletInfo">
<string key="name">appDelegate</string>
<string key="candidateClassName">NewsBlurAppDelegate</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">sitesSearchBar</string>
<string key="candidateClassName">UISearchBar</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">sitesTable</string>
<string key="candidateClassName">UITableView</string>
</object>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/FindSitesViewController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">FirstTimeUserAddFriendsViewController</string>
<string key="superclassName">UIViewController</string>
@ -6260,7 +6220,6 @@ AAgAAAAIAAIACAACAAAAAgAAAAEAAQABAAE</bytes>
<string>feedDetailViewController</string>
<string>feedsMenuViewController</string>
<string>feedsViewController</string>
<string>findSitesViewController</string>
<string>firstTimeUserAddFriendsViewController</string>
<string>firstTimeUserAddNewsBlurViewController</string>
<string>firstTimeUserAddSitesViewController</string>
@ -6289,7 +6248,6 @@ AAgAAAAIAAIACAACAAAAAgAAAAEAAQABAAE</bytes>
<string>FeedDetailViewController</string>
<string>FeedsMenuViewController</string>
<string>NewsBlurViewController</string>
<string>FindSitesViewController</string>
<string>FirstTimeUserAddFriendsViewController</string>
<string>FirstTimeUserAddNewsBlurViewController</string>
<string>FirstTimeUserAddSitesViewController</string>
@ -6321,7 +6279,6 @@ AAgAAAAIAAIACAACAAAAAgAAAAEAAQABAAE</bytes>
<string>feedDetailViewController</string>
<string>feedsMenuViewController</string>
<string>feedsViewController</string>
<string>findSitesViewController</string>
<string>firstTimeUserAddFriendsViewController</string>
<string>firstTimeUserAddNewsBlurViewController</string>
<string>firstTimeUserAddSitesViewController</string>
@ -6371,10 +6328,6 @@ AAgAAAAIAAIACAACAAAAAgAAAAEAAQABAAE</bytes>
<string key="name">feedsViewController</string>
<string key="candidateClassName">NewsBlurViewController</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">findSitesViewController</string>
<string key="candidateClassName">FindSitesViewController</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">firstTimeUserAddFriendsViewController</string>
<string key="candidateClassName">FirstTimeUserAddFriendsViewController</string>
@ -7036,13 +6989,14 @@ AAgAAAAIAAIACAACAAAAAgAAAAEAAQABAAE</bytes>
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>activity</string>
<string>appDelegate</string>
<string>bottomPlaceholderToolbar</string>
<string>buttonAction</string>
<string>buttonNext</string>
<string>buttonPrevious</string>
<string>circularProgressView</string>
<string>fontSettingsButton</string>
<string>loadingIndicator</string>
<string>originalStoryButton</string>
<string>pageControl</string>
<string>progressView</string>
@ -7054,20 +7008,21 @@ AAgAAAAIAAIACAACAAAAAgAAAAEAAQABAAE</bytes>
<string>spacer3BarButton</string>
<string>spacerBarButton</string>
<string>subscribeButton</string>
<string>toolbar</string>
<string>traverseView</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>UIBarButtonItem</string>
<string>NewsBlurAppDelegate</string>
<string>UIToolbar</string>
<string>UIBarButtonItem</string>
<string>UIButton</string>
<string>UIButton</string>
<string>THCircularProgressView</string>
<string>UIBarButtonItem</string>
<string>UIBarButtonItem</string>
<string>UIBarButtonItem</string>
<string>UIActivityIndicatorView</string>
<string>UIBarButtonItem</string>
<string>UIPageControl</string>
<string>UIProgressView</string>
<string>UIView</string>
<string>UIView</string>
<string>TransparentToolbar</string>
<string>UIScrollView</string>
@ -7076,20 +7031,21 @@ AAgAAAAIAAIACAACAAAAAgAAAAEAAQABAAE</bytes>
<string>UIBarButtonItem</string>
<string>UIBarButtonItem</string>
<string>UIBarButtonItem</string>
<string>UIToolbar</string>
<string>UIView</string>
</object>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>activity</string>
<string>appDelegate</string>
<string>bottomPlaceholderToolbar</string>
<string>buttonAction</string>
<string>buttonNext</string>
<string>buttonPrevious</string>
<string>circularProgressView</string>
<string>fontSettingsButton</string>
<string>loadingIndicator</string>
<string>originalStoryButton</string>
<string>pageControl</string>
<string>progressView</string>
@ -7101,14 +7057,10 @@ AAgAAAAIAAIACAACAAAAAgAAAAEAAQABAAE</bytes>
<string>spacer3BarButton</string>
<string>spacerBarButton</string>
<string>subscribeButton</string>
<string>toolbar</string>
<string>traverseView</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBToOneOutletInfo">
<string key="name">activity</string>
<string key="candidateClassName">UIBarButtonItem</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">appDelegate</string>
<string key="candidateClassName">NewsBlurAppDelegate</string>
@ -7123,16 +7075,24 @@ AAgAAAAIAAIACAACAAAAAgAAAAEAAQABAAE</bytes>
</object>
<object class="IBToOneOutletInfo">
<string key="name">buttonNext</string>
<string key="candidateClassName">UIBarButtonItem</string>
<string key="candidateClassName">UIButton</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">buttonPrevious</string>
<string key="candidateClassName">UIBarButtonItem</string>
<string key="candidateClassName">UIButton</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">circularProgressView</string>
<string key="candidateClassName">THCircularProgressView</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">fontSettingsButton</string>
<string key="candidateClassName">UIBarButtonItem</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">loadingIndicator</string>
<string key="candidateClassName">UIActivityIndicatorView</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">originalStoryButton</string>
<string key="candidateClassName">UIBarButtonItem</string>
@ -7143,7 +7103,7 @@ AAgAAAAIAAIACAACAAAAAgAAAAEAAQABAAE</bytes>
</object>
<object class="IBToOneOutletInfo">
<string key="name">progressView</string>
<string key="candidateClassName">UIProgressView</string>
<string key="candidateClassName">UIView</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">progressViewContainer</string>
@ -7178,8 +7138,8 @@ AAgAAAAIAAIACAACAAAAAgAAAAEAAQABAAE</bytes>
<string key="candidateClassName">UIBarButtonItem</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">toolbar</string>
<string key="candidateClassName">UIToolbar</string>
<string key="name">traverseView</string>
<string key="candidateClassName">UIView</string>
</object>
</object>
</object>
@ -7188,6 +7148,14 @@ AAgAAAAIAAIACAACAAAAAgAAAAEAAQABAAE</bytes>
<string key="minorKey">./Classes/StoryPageControl.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">THCircularProgressView</string>
<string key="superclassName">UIView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/THCircularProgressView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">TrainerViewController</string>
<string key="superclassName">BaseViewController</string>

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 B

View file

@ -1432,6 +1432,10 @@ NEWSBLUR.AssetModel = Backbone.Router.extend({
}, callback, error_callback);
},
delete_all_sites: function(callback, error_callback) {
this.make_request('/profile/delete_all_sites', {}, callback, error_callback);
},
follow_twitter_account: function(username, callback) {
this.make_request('/oauth/follow_twitter_account', {'username': username}, callback);
},

View file

@ -5468,6 +5468,11 @@
e.preventDefault();
self.toggle_story_titles_pane(true);
});
$document.bind('keydown', 'shift+f', function(e) {
e.preventDefault();
self.toggle_sidebar();
self.toggle_story_titles_pane(true);
});
$document.bind('keydown', 'n', function(e) {
e.preventDefault();
self.open_next_unread_story_across_feeds();

View file

@ -100,10 +100,19 @@ _.extend(NEWSBLUR.ReaderAccount.prototype, {
]),
$.make('div', { className: 'NB-preference NB-preference-delete' }, [
$.make('div', { className: 'NB-preference-options' }, [
$.make('a', { className: 'NB-splash-link', href: NEWSBLUR.URLs['delete-account'] }, 'Delete my account')
$.make('div', { className: 'NB-splash-link NB-account-delete-all-sites' }, 'Delete all of my sites')
]),
$.make('div', { className: 'NB-preference-label'}, [
'Erase yourself',
$.make('div', { className: 'NB-preference-sublabel' }, 'Notice: You will be emailed a backup of your sites')
])
]),
$.make('div', { className: 'NB-preference NB-preference-delete' }, [
$.make('div', { className: 'NB-preference-options' }, [
$.make('a', { className: 'NB-splash-link', href: NEWSBLUR.URLs['delete-account'] }, 'Delete my account')
]),
$.make('div', { className: 'NB-preference-label'}, [
'Erase yourself permanently',
$.make('div', { className: 'NB-preference-sublabel' }, 'Warning: This is actually permanent')
])
])
@ -237,6 +246,19 @@ _.extend(NEWSBLUR.ReaderAccount.prototype, {
}, this));
},
delete_all_sites: function() {
var $link = $(".NB-account-delete-all-sites", this.$modal);
if (window.confirm("Positive you want to delete everything?")) {
NEWSBLUR.assets.delete_all_sites(_.bind(function() {
NEWSBLUR.assets.load_feeds();
$link.replaceWith($.make('div', 'Everything has been deleted.'));
}, this), _.bind(function() {
$link.replaceWith($.make('div', { className: 'NB-error' }, 'There was a problem deleting your sites.'));
}, this));
}
},
handle_cancel: function() {
var $cancel = $('.NB-modal-cancel', this.$modal);
@ -347,6 +369,11 @@ _.extend(NEWSBLUR.ReaderAccount.prototype, {
e.preventDefault();
self.cancel_premium();
});
$.targetIs(e, { tagSelector: '.NB-account-delete-all-sites' }, function($t, $p) {
e.preventDefault();
self.delete_all_sites();
});
$.targetIs(e, { tagSelector: '.NB-modal-cancel' }, function($t, $p) {
e.preventDefault();

View file

@ -263,7 +263,7 @@ _.extend(NEWSBLUR.ReaderKeyboard.prototype, {
]),
$.make('div', { className: 'NB-keyboard-group' }, [
$.make('div', { className: 'NB-keyboard-shortcut' }, [
$.make('div', { className: 'NB-keyboard-shortcut-explanation' }, 'Hide Sites'),
$.make('div', { className: 'NB-keyboard-shortcut-explanation' }, 'Hide sites'),
$.make('div', { className: 'NB-keyboard-shortcut-key' }, [
'shift',
$.make('span', '+'),
@ -271,7 +271,7 @@ _.extend(NEWSBLUR.ReaderKeyboard.prototype, {
])
]),
$.make('div', { className: 'NB-keyboard-shortcut NB-last' }, [
$.make('div', { className: 'NB-keyboard-shortcut-explanation' }, 'Hide Story titles'),
$.make('div', { className: 'NB-keyboard-shortcut-explanation' }, 'Hide story titles'),
$.make('div', { className: 'NB-keyboard-shortcut-key' }, [
'shift',
$.make('span', '+'),
@ -281,7 +281,7 @@ _.extend(NEWSBLUR.ReaderKeyboard.prototype, {
]),
$.make('div', { className: 'NB-keyboard-group' }, [
$.make('div', { className: 'NB-keyboard-shortcut' }, [
$.make('div', { className: 'NB-keyboard-shortcut-explanation' }, 'Change Intelligence'),
$.make('div', { className: 'NB-keyboard-shortcut-explanation' }, 'Switch focus/unread'),
$.make('div', { className: 'NB-keyboard-shortcut-key' }, [
'+'
]),
@ -297,11 +297,19 @@ _.extend(NEWSBLUR.ReaderKeyboard.prototype, {
])
]),
$.make('div', { className: 'NB-keyboard-group' }, [
$.make('div', { className: 'NB-keyboard-shortcut NB-last' }, [
$.make('div', { className: 'NB-keyboard-shortcut-explanation' }, 'Add Site/Folder'),
$.make('div', { className: 'NB-keyboard-shortcut' }, [
$.make('div', { className: 'NB-keyboard-shortcut-explanation' }, 'Add site/folder'),
$.make('div', { className: 'NB-keyboard-shortcut-key' }, [
'a'
])
]),
$.make('div', { className: 'NB-keyboard-shortcut NB-last' }, [
$.make('div', { className: 'NB-keyboard-shortcut-explanation' }, 'Full screen'),
$.make('div', { className: 'NB-keyboard-shortcut-key' }, [
'shift',
$.make('span', '+'),
'f'
])
])
])
]);

View file

@ -0,0 +1,8 @@
{% extends "mail/email_base.txt" %}
{% load utils_tags %}
{% block body %}Here's a backup of your sites on NewsBlur. It contains <b>{{ feed_count }}</b> site{{ feed_count|pluralize }}.
You can re-upload the attached file to NewsBlur and get all of your sites back.
Just go to Manage > Import > Upload OPML.{% endblock body %}

View file

@ -0,0 +1,15 @@
{% extends "mail/email_base.xhtml" %}
{% load utils_tags %}
{% block body %}
<p style="margin-top: 12px;">
Here's a backup of your sites on NewsBlur. It contains <b>{{ feed_count }}</b>
site{{ feed_count|pluralize }}.
</p>
<p style="margin-top: 12px;">
You can re-upload the attached file to NewsBlur and get all of your sites back. <br />
Just go to Manage > Import > Upload OPML.
</p>
{% endblock %}

View file

@ -35,9 +35,9 @@
table {
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#533754), to(#372238));
background: -moz-linear-gradient(center top , #533754 0%, #372238 100%) repeat scroll 0 0 transparent;
/* background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#304332), to(#172018));
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#304332), to(#172018));
background: -moz-linear-gradient(center top , #304332 0%, #172018 100%) repeat scroll 0 0 transparent;
*/ }
}
#container {
width: 500px
}
@ -74,7 +74,7 @@
margin: 0 0 48px;
}
</style>
<title>NewsBlur is upgrading...</title>
<title>NewsBlur is in maintenance mode...</title>
</head>
<body>
<table height="100%" width="100%">
@ -82,10 +82,9 @@
<td align="center" valign="middle">
<div id="container">
<img src="/media/img/logo_512.png" class="logo">
<h1>NewsBlur has been <span class="error404">upgraded</span></h1>
<h1>NewsBlur is in <span class="error404">maintenance mode</span></h1>
<div class="description">
<p>A huge thank you to all of you beta testers. You've made this deployment and redesign as close to painless as it gets.</p>
<p>Now go back to <a href="//www.newsblur.com">www.newsblur.com</a>, I've got new things to test on this server.</p>
<p>PostgreSQL server fell over, fixing...</p>
</div>
</div>
</td>

View file

@ -78,6 +78,9 @@ float: right;">
<div>
{{ zebra_form.card_number.label_tag }}
{{ zebra_form.card_number }}
{% if error %}
<label class="error">{{ error }}</label>
{% endif %}
</div>
<div>
{{ zebra_form.card_cvv.label_tag }}

View file

@ -1,5 +1,5 @@
{% load utils_tags %}
<div class="NB-module-recommended NB-module {% if unmoderated %}NB-recommended-unmoderated{% endif %}">
<div class="NB-module-recommended NB-module {% if unmoderated and not page %}NB-recommended-unmoderated{% endif %}">
<h5 class="NB-module-header">
{% if unmoderated %}
Moderation Queue