diff --git a/.gitignore b/.gitignore index 3d7cc77..7c99f0a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,8 @@ -Mac/build/ -Mac/Bungloo.xcodeproj/project.xcworkspace/xcuserdata/jeena.xcuserdatad/UserInterfaceState.xcuserstate +Mac/Bungloo.app +Mac/bungloo dsa_priv.pem *.pyc .DS_Store *~ -Linux/build/ +Linux/dist +Windows/bungloo diff --git a/LICENCE.txt b/LICENSE.txt similarity index 100% rename from LICENCE.txt rename to LICENSE.txt diff --git a/Linux/deploy/Makefile.exmp b/Linux/Makefile.exmp similarity index 93% rename from Linux/deploy/Makefile.exmp rename to Linux/Makefile.exmp index 1e34feb..5c35b0c 100644 --- a/Linux/deploy/Makefile.exmp +++ b/Linux/Makefile.exmp @@ -30,9 +30,11 @@ builddeb: rename -f 's/$(PROJECT)-(.*)\.tar\.gz/$(PROJECT)_$$1\.orig\.tar\.gz/' ../* # build the package dpkg-buildpackage -i -I -rfakeroot + dpkg-buildpackage -i -I -rfakeroot -S clean: $(PYTHON) setup.py clean $(MAKE) -f $(CURDIR)/debian/rules clean rm -rf build/ MANIFEST - find . -name '*.pyc' -delete \ No newline at end of file + find . -name '*.pyc' -delete + diff --git a/Linux/deploy/bungloo.desktop.exmp b/Linux/bungloo.desktop.exmp similarity index 66% rename from Linux/deploy/bungloo.desktop.exmp rename to Linux/bungloo.desktop.exmp index d21b077..84531c6 100644 --- a/Linux/deploy/bungloo.desktop.exmp +++ b/Linux/bungloo.desktop.exmp @@ -1,12 +1,13 @@ [Desktop Entry] Version={VERSION} -Comment=Tent is a distributed social network protocol and Bungloo is one of the clients using it. -Exec=/usr/bin/bungloo +Comment=Tent is a distributed social network protocol and Bungloo is one of the microbloging clients using it. +Exec=bungloo %U GenericName=Tent Client -Icon=/usr/share/pixmaps/bungloo.xpm +Icon=bungloo Name=Bungloo NoDisplay=false StartupNotify=true Terminal=false Type=Application Categories=Network;Qt +MimeType=x-scheme-handler/bungloo; diff --git a/Linux/bungloo.ebuild.exmp b/Linux/bungloo.ebuild.exmp new file mode 100644 index 0000000..4633edf --- /dev/null +++ b/Linux/bungloo.ebuild.exmp @@ -0,0 +1,20 @@ +# Copyright 1999-2012 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +EAPI=5 +PYTHON_COMPAT=(python{2_6,2_7}) + +inherit eutils distutils-r1 + +DESCRIPTION="Qt4/KDE Tent client" +HOMEPAGE="https://jabs.nu/bungloo" + +LICENSE="BSD" +KEYWORDS="~x86 ~amd64" +SLOT="0" +IUSE="" +SRC_URI="http://jabs.nu/bungloo/download/${P}.tar.gz" + +DEPEND=">=dev-python/PyQt4-4.6" + diff --git a/Linux/debian/changelog b/Linux/debian/changelog new file mode 100644 index 0000000..5b66ff6 --- /dev/null +++ b/Linux/debian/changelog @@ -0,0 +1,53 @@ +bungloo (2.0.0) raring; urgency=high + + [Jeena Paradies] + * Nearly complete rewrite to be compatible with Tent 0.3 + + -- Jeena Paradies Tue, 09 Sep 2013 10:25:00 +0100 + +bungloo (1.4.3) raring; urgency=high + + [ Jeena Paradies ] + * bugfix with SingleApplication + + -- Jeena Paradies Tue, 28 Apr 2013 10:10:00 +0100 + +bungloo (1.4.2) raring; urgency=low + + [ Jeena Paradies ] + * Fixes the bug with wrongly showing uread mentions + * Added single application mode + * Added --new-message + * Added close window shortcut + * Bugfixes + + -- Jeena Paradies Tue, 28 Apr 2013 00:50:00 +0100 + +bungloo (1.4.0) quantal; urgency=low + + [ Jeena Paradies ] + * Added scroll to load more posts + * Added doubleclick for conversation in new window + * Added synchronized "read mentions" cursor + * Added "show next view" shortcut + * New possibilities for plugins + * Inverted "from" label position + * Bugfixes + + -- Jeena Paradies Tue, 17 Apr 2013 07:50:00 +0100 + +bungloo (1.3.0) quantal; urgency=low + + [ Jeena Paradies ] + * Changed to one window + * Added search (skate.io) + * Added log out + + -- Jeena Paradies Tue, 26 Mar 2013 21:50:00 +0100 + +bungloo (1.2.0) quantal; urgency=low + + [ Jeena Paradies ] + * Initial release. + + -- Jeena Paradies Tue, 05 Mar 2013 17:57:47 +0100 diff --git a/Linux/deploy/debian/compat b/Linux/debian/compat similarity index 100% rename from Linux/deploy/debian/compat rename to Linux/debian/compat diff --git a/Linux/deploy/debian/control b/Linux/debian/control similarity index 95% rename from Linux/deploy/debian/control rename to Linux/debian/control index 15d7830..4f2e11c 100644 --- a/Linux/deploy/debian/control +++ b/Linux/debian/control @@ -1,5 +1,5 @@ Source: bungloo -Section: Miscellaneous +Section: net Priority: optional Maintainer: Jeena Paradies Build-Depends: debhelper (>=7.0.50~), python-support (>= 0.6), cdbs (>= 0.4.49), python-all-dev diff --git a/Linux/deploy/debian/copyright b/Linux/debian/copyright similarity index 100% rename from Linux/deploy/debian/copyright rename to Linux/debian/copyright diff --git a/Linux/deploy/debian/rules b/Linux/debian/rules similarity index 99% rename from Linux/deploy/debian/rules rename to Linux/debian/rules index f0766df..351bb67 100755 --- a/Linux/deploy/debian/rules +++ b/Linux/debian/rules @@ -15,3 +15,4 @@ install/bungloo:: clean:: rm -rf build build-stamp configure-stamp build/ MANIFEST dh_clean + diff --git a/Linux/deploy/deploy.sh b/Linux/deploy.sh similarity index 58% rename from Linux/deploy/deploy.sh rename to Linux/deploy.sh index 684e274..075e323 100755 --- a/Linux/deploy/deploy.sh +++ b/Linux/deploy.sh @@ -2,9 +2,9 @@ VERSION="2.0.0" DEPLOYPATH="bungloo-${VERSION}" -LINUXPATH=".." -SHAREDPATH="../.." -DISTPATH=dist +QTPATH="../Qt" +SHAREDPATH=".." +DISTPATH="dist" rm -rf $DEPLOYPATH rm -rf $DISTPATH @@ -14,8 +14,8 @@ mkdir -p $DEPLOYPATH/bin mkdir -p $DEPLOYPATH/bungloo touch $DEPLOYPATH/bungloo/__init__.py -cp $LINUXPATH/Bungloo.py $DEPLOYPATH/bin/bungloo -cp $LINUXPATH/Helper.py $LINUXPATH/Windows.py $DEPLOYPATH/bungloo +cp $QTPATH/Bungloo.py $DEPLOYPATH/bin/bungloo +cp $QTPATH/Helper.py $QTPATH/Windows.py $QTPATH/SingleApplication.py $DEPLOYPATH/bungloo cat setup.py.exmp | sed -e "s/{VERSION}/${VERSION}/g" > $DEPLOYPATH/setup.py cat Makefile.exmp | sed -e "s/{VERSION}/${VERSION}/g" > $DEPLOYPATH/Makefile cat bungloo.desktop.exmp | sed -e "s/{VERSION}/${VERSION}/g" > $DEPLOYPATH/bungloo.desktop @@ -24,7 +24,6 @@ cp -r $SHAREDPATH/images $DEPLOYPATH/bungloo/ cp $SHAREDPATH/readme.md $DEPLOYPATH/README cp $SHAREDPATH/LICENCE.txt $DEPLOYPATH/COPYING cp -r debian $DEPLOYPATH/ -cp bungloo.desktop $DEPLOYPATH/ cd $DEPLOYPATH make builddeb @@ -34,16 +33,21 @@ echo "Cleaning up ..." mv $DISTPATH .. cd .. -mv bungloo_${VERSION}_all.deb $DISTPATH -rm bungloo_${VERSION}_amd64.changes -rm bungloo_${VERSION}.diff.gz -rm bungloo_${VERSION}.dsc -rm bungloo_${VERSION}.orig.tar.gz +cp bungloo.ebuild.exmp $DISTPATH/bungloo-${VERSION}.ebuild + +mv bungloo_${VERSION}_all.deb $DISTPATH +mv bungloo_${VERSION}_amd64.changes $DISTPATH +mv bungloo_${VERSION}.diff.gz $DISTPATH +mv bungloo_${VERSION}.dsc $DISTPATH +mv bungloo_${VERSION}.orig.tar.gz $DISTPATH +mv bungloo_${VERSION}_source.changes $DISTPATH + rm -rf $DEPLOYPATH rm $DISTPATH/bungloo-${VERSION}-1.src.rpm +mv $DISTPATH/bungloo-${VERSION}-1.noarch.rpm $DISTPATH/bungloo-${VERSION}.noarch.rpm echo "Done." - +echo "dput ppa:jeena/bungloo $DISTPATH/bungloo_${VERSION}_source.changes" # eof diff --git a/Linux/deploy/debian/changelog b/Linux/deploy/debian/changelog deleted file mode 100644 index 2ed9a7d..0000000 --- a/Linux/deploy/debian/changelog +++ /dev/null @@ -1,15 +0,0 @@ -bungloo (2.0.0) quantal; urgency=low - - [ Jeena Paradies ] - * Changed to one window - * Added search (skate.io) - * Added log out - - -- Jeena Tue, 26 Mar 2013 21:50:00 +0100 - -bungloo (1.2.0) quantal; urgency=low - - [ Jeena Paradies ] - * Initial release. - - -- Jeena Tue, 05 Mar 2013 17:57:47 +0100 diff --git a/Linux/deploy/setup.py.exmp b/Linux/setup.py.exmp similarity index 78% rename from Linux/deploy/setup.py.exmp rename to Linux/setup.py.exmp index 06130f5..c9eaa8a 100644 --- a/Linux/deploy/setup.py.exmp +++ b/Linux/setup.py.exmp @@ -21,5 +21,9 @@ setup( license = "BSD license", packages = ['bungloo'], package_data = {"bungloo": files}, - scripts = ["bin/bungloo"] - ) + scripts = ["bin/bungloo"], + data_files=[ + ('/usr/share/applications', ["bungloo.desktop"]), + ('/usr/share/pixmaps', ["bungloo/images/bungloo.xpm"]) + ] +) diff --git a/Mac/AccessToken.h b/Mac/AccessToken.h deleted file mode 100644 index b9cbcf8..0000000 --- a/Mac/AccessToken.h +++ /dev/null @@ -1,27 +0,0 @@ -// -// AccessToken.h -// bungloo -// -// Created by Jeena Paradies on 19/09/2011. -// Copyright 2011 __MyCompanyName__. All rights reserved. -// - - - -@interface AccessToken : NSObject { - NSUserDefaults *d; -} - -- (void)setString:(NSString *)string forKey:(NSString *)aKey; -- (NSString *)stringForKey:(NSString *)aKey; - -- (void)setAccessToken:(NSString *)_accessToken; -- (NSString *)accessToken; -- (void)setSecret:(NSString *)_secret; -- (NSString *)secret; -- (void)setUserId:(NSString *)_userId; -- (NSString *)userId; -- (void)setScreenName:(NSString *)_screenName; -- (NSString *)screenName; - -@end \ No newline at end of file diff --git a/Mac/AccessToken.m b/Mac/AccessToken.m deleted file mode 100644 index f60e91c..0000000 --- a/Mac/AccessToken.m +++ /dev/null @@ -1,130 +0,0 @@ -// -// AccessToken.m -// bungloo -// -// Created by Jeena Paradies on 19/09/2011. -// Copyright 2011 __MyCompanyName__. All rights reserved. -// - -#import "AccessToken.h" -#include - -@implementation AccessToken - -- (id)init -{ - self = [super init]; - if (self) { - // Initialization code here. - d = [NSUserDefaults standardUserDefaults]; - //[d removeObjectForKey:@"user_access_token"]; - } - - return self; -} - -- (void)setString:(NSString *)string forKey:(NSString *)aKey -{ - [d setObject:string forKey:aKey]; - [d synchronize]; -} - -- (NSString *)stringForKey:(NSString *)aKey -{ - return [d objectForKey:aKey]; -} - -- (void)setAccessToken:(NSString *)_accessToken -{ - [d synchronize]; -} - -- (NSString *)accessToken -{ - return [d objectForKey:@"accessToken"]; -} - -- (void)setSecret:(NSString *)_secret -{ - UInt32 _passwordLength = 0; - char *_password = nil; - SecKeychainItemRef item = nil; - SecKeychainFindGenericPassword(NULL, 6, "Bungloo", 17, "BunglooUserAccount", &_passwordLength, (void **)&_password, &item); - - OSStatus status; - void * passwordData = (void*)[_secret cStringUsingEncoding:NSUTF8StringEncoding]; - UInt32 passwordLength = strlen((char*)passwordData); - if (!item) - { - status = SecKeychainAddGenericPassword( - NULL, // default keychain - 6, // length of service name - "Bungloo", // service name - 17, // length of account name - "BunglooUserAccount", // account name - passwordLength, // length of password - passwordData, // pointer to password data - NULL // the item reference - ); - } - else - { - status = SecKeychainItemModifyContent( - item, - NULL, - passwordLength, - passwordData - ); - } - NSLog(@"%@",(NSString *)SecCopyErrorMessageString (status,NULL)); -} - -- (NSString *)secret -{ - UInt32 passwordLength = 0; - char *password = nil; - SecKeychainItemRef item = nil; - SecKeychainFindGenericPassword(NULL, 6, "Bungloo", 17, "BunglooUserAccount", &passwordLength, (void **)&password, &item); - - if (!item) { - return nil; - } - - //Get password - NSString *passwordString = [[[NSString alloc] initWithData:[NSData dataWithBytes:password length:passwordLength] encoding:NSUTF8StringEncoding] autorelease]; - SecKeychainItemFreeContent(NULL, password); - return passwordString; -} - -- (void)setUserId:(NSString *)_userId -{ - [d setObject:_userId forKey:@"userId"]; - [d synchronize]; -} - -- (NSString *)userId -{ - return [d objectForKey:@"userId"]; -} - -- (void)setScreenName:(NSString *)_screenName -{ - [d setObject:_screenName forKey:@"screenName"]; - [d synchronize]; -} - -- (NSString *)screenName -{ - return [d objectForKey:@"screenName"]; -} - -+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector { - return NO; -} - -+ (BOOL)isKeyExcludedFromWebScript:(const char *)name { - return NO; -} - - -@end diff --git a/Mac/Bungloo-Info.plist b/Mac/Bungloo-Info.plist deleted file mode 100644 index c72ed76..0000000 --- a/Mac/Bungloo-Info.plist +++ /dev/null @@ -1,80 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleDocumentTypes - - - CFBundleTypeExtensions - - ???? - - CFBundleTypeIconFile - - CFBundleTypeName - DocumentType - CFBundleTypeOSTypes - - ???? - - CFBundleTypeRole - Editor - NSDocumentClass - NewMessageWindow - - - CFBundleExecutable - Bungloo - CFBundleHelpBookFolder - Bungloo.help - CFBundleHelpBookName - nu.jabs.apps.bungloo.help - CFBundleIconFile - Icon.icns - CFBundleIdentifier - nu.jabs.apps.bungloo - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - Bungloo - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.2.0 - CFBundleSignature - ???? - CFBundleURLTypes - - - CFBundleURLName - nu.jabs.apps.bungloo.handler - CFBundleURLSchemes - - bungloo - - - - CFBundleVersion - 1.2.0 - LSApplicationCategoryType - public.app-category.social-networking - LSMinimumSystemVersion - ${MACOSX_DEPLOYMENT_TARGET} - NSMainNibFile - MainMenu - NSPrincipalClass - NSApplication - NSServices - - SUFeedURL - http://jabs.nu/bungloo/download/Appcast.xml - SUPublicDSAKeyFile - dsa_pub.pem - UTExportedTypeDeclarations - - UTImportedTypeDeclarations - - - diff --git a/Mac/Bungloo.temp_caseinsensitive_rename_Prefix.pch b/Mac/Bungloo.temp_caseinsensitive_rename_Prefix.pch deleted file mode 100644 index 694af35..0000000 --- a/Mac/Bungloo.temp_caseinsensitive_rename_Prefix.pch +++ /dev/null @@ -1,7 +0,0 @@ -// -// Prefix header for all source files of the 'bungloo' target in the 'bungloo' project -// - -#ifdef __OBJC__ - #import -#endif diff --git a/Mac/Bungloo.xcodeproj/jeena.mode1v3 b/Mac/Bungloo.xcodeproj/jeena.mode1v3 deleted file mode 100644 index 777a537..0000000 --- a/Mac/Bungloo.xcodeproj/jeena.mode1v3 +++ /dev/null @@ -1,1421 +0,0 @@ - - - - - ActivePerspectiveName - Project - AllowedModules - - - BundleLoadPath - - MaxInstances - n - Module - PBXSmartGroupTreeModule - Name - Groups and Files Outline View - - - BundleLoadPath - - MaxInstances - n - Module - PBXNavigatorGroup - Name - Editor - - - BundleLoadPath - - MaxInstances - n - Module - XCTaskListModule - Name - Task List - - - BundleLoadPath - - MaxInstances - n - Module - XCDetailModule - Name - File and Smart Group Detail Viewer - - - BundleLoadPath - - MaxInstances - 1 - Module - PBXBuildResultsModule - Name - Detailed Build Results Viewer - - - BundleLoadPath - - MaxInstances - 1 - Module - PBXProjectFindModule - Name - Project Batch Find Tool - - - BundleLoadPath - - MaxInstances - n - Module - XCProjectFormatConflictsModule - Name - Project Format Conflicts List - - - BundleLoadPath - - MaxInstances - n - Module - PBXBookmarksModule - Name - Bookmarks Tool - - - BundleLoadPath - - MaxInstances - n - Module - PBXClassBrowserModule - Name - Class Browser - - - BundleLoadPath - - MaxInstances - n - Module - PBXCVSModule - Name - Source Code Control Tool - - - BundleLoadPath - - MaxInstances - n - Module - PBXDebugBreakpointsModule - Name - Debug Breakpoints Tool - - - BundleLoadPath - - MaxInstances - n - Module - XCDockableInspector - Name - Inspector - - - BundleLoadPath - - MaxInstances - n - Module - PBXOpenQuicklyModule - Name - Open Quickly Tool - - - BundleLoadPath - - MaxInstances - 1 - Module - PBXDebugSessionModule - Name - Debugger - - - BundleLoadPath - - MaxInstances - 1 - Module - PBXDebugCLIModule - Name - Debug Console - - - BundleLoadPath - - MaxInstances - n - Module - XCSnapshotModule - Name - Snapshots Tool - - - BundlePath - /Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources - Description - DefaultDescriptionKey - DockingSystemVisible - - Extension - mode1v3 - FavBarConfig - - PBXProjectModuleGUID - 1F68211F1249D25900A03CED - XCBarModuleItemNames - - XCBarModuleItems - - - FirstTimeWindowDisplayed - - Identifier - com.apple.perspectives.project.mode1v3 - MajorVersion - 33 - MinorVersion - 0 - Name - Default - Notifications - - OpenEditors - - PerspectiveWidths - - -1 - -1 - - Perspectives - - - ChosenToolbarItems - - active-combo-popup - action - NSToolbarFlexibleSpaceItem - build-and-go - com.apple.ide.PBXToolbarStopButton - get-info - NSToolbarFlexibleSpaceItem - com.apple.pbx.toolbar.searchfield - - ControllerClassBaseName - - IconName - WindowOfProjectWithEditor - Identifier - perspective.project - IsVertical - - Layout - - - ContentConfiguration - - PBXBottomSmartGroupGIDs - - 1C37FBAC04509CD000000102 - 1C37FAAC04509CD000000102 - 1C37FABC05509CD000000102 - 1C37FABC05539CD112110102 - E2644B35053B69B200211256 - 1C37FABC04509CD000100104 - 1CC0EA4004350EF90044410B - 1CC0EA4004350EF90041110B - - PBXProjectModuleGUID - 1CE0B1FE06471DED0097A5F4 - PBXProjectModuleLabel - Files - PBXProjectStructureProvided - yes - PBXSmartGroupTreeModuleColumnData - - PBXSmartGroupTreeModuleColumnWidthsKey - - 287 - - PBXSmartGroupTreeModuleColumnsKey_v4 - - MainColumn - - - PBXSmartGroupTreeModuleOutlineStateKey_v7 - - PBXSmartGroupTreeModuleOutlineStateExpansionKey - - 2A37F4AAFDCFA73011CA2CEA - 2A37F4ABFDCFA73011CA2CEA - 2A37F4B8FDCFA73011CA2CEA - 1FFA36C71177D861006C8562 - 2A37F4C3FDCFA73011CA2CEA - 1058C7A6FEA54F5311CA2CBB - 1C37FAAC04509CD000000102 - 1C37FABC05509CD000000102 - - PBXSmartGroupTreeModuleOutlineStateSelectionKey - - - 37 - 17 - 0 - - - PBXSmartGroupTreeModuleOutlineStateVisibleRectKey - {{0, 0}, {287, 1304}} - - PBXTopSmartGroupGIDs - - XCIncludePerspectivesSwitch - - XCSharingToken - com.apple.Xcode.GFSharingToken - - GeometryConfiguration - - Frame - {{0, 0}, {304, 1322}} - GroupTreeTableConfiguration - - MainColumn - 287 - - RubberWindowFrame - 469 55 1319 1363 0 0 2560 1418 - - Module - PBXSmartGroupTreeModule - Proportion - 304pt - - - Dock - - - BecomeActive - - ContentConfiguration - - PBXProjectModuleGUID - 1CE0B20306471E060097A5F4 - PBXProjectModuleLabel - TwittiaCore.js - PBXSplitModuleInNavigatorKey - - Split0 - - PBXProjectModuleGUID - 1CE0B20406471E060097A5F4 - PBXProjectModuleLabel - TwittiaCore.js - _historyCapacity - 0 - bookmark - 1F8D1E4412DF5A0D00571730 - history - - 1F98DCA9124C691A004289ED - 1F98DCAD124C691A004289ED - 1F17508512A972DF004A0B42 - 1F2F793712BD93A600F073BE - 1F27470412D905CA00339B4F - 1F618EAC12DB5D0700E500D9 - 1F618ED112DB60D100E500D9 - 1F618ED212DB60D100E500D9 - 1F618ED312DB60D100E500D9 - 1F618ED412DB60D100E500D9 - 1F618ED512DB60D100E500D9 - 1F618ED612DB60D100E500D9 - 1F618F0212DB665B00E500D9 - 1F618F0312DB665B00E500D9 - 1F618F0412DB665B00E500D9 - 1F618F0512DB665B00E500D9 - 1F8D1E4212DF5A0D00571730 - 1F8D1E4312DF5A0D00571730 - - - SplitCount - 1 - - StatusBarVisibility - - - GeometryConfiguration - - Frame - {{0, 0}, {1010, 1317}} - RubberWindowFrame - 469 55 1319 1363 0 0 2560 1418 - - Module - PBXNavigatorGroup - Proportion - 1317pt - - - ContentConfiguration - - PBXProjectModuleGUID - 1CE0B20506471E060097A5F4 - PBXProjectModuleLabel - Detail - - GeometryConfiguration - - Frame - {{0, 1322}, {1010, 0}} - RubberWindowFrame - 469 55 1319 1363 0 0 2560 1418 - - Module - XCDetailModule - Proportion - 0pt - - - Proportion - 1010pt - - - Name - Project - ServiceClasses - - XCModuleDock - PBXSmartGroupTreeModule - XCModuleDock - PBXNavigatorGroup - XCDetailModule - - TableOfContents - - 1F8D1E2712DF55D600571730 - 1CE0B1FE06471DED0097A5F4 - 1F8D1E2812DF55D600571730 - 1CE0B20306471E060097A5F4 - 1CE0B20506471E060097A5F4 - - ToolbarConfigUserDefaultsMinorVersion - 2 - ToolbarConfiguration - xcode.toolbar.config.defaultV3 - - - ControllerClassBaseName - - IconName - WindowOfProject - Identifier - perspective.morph - IsVertical - 0 - Layout - - - BecomeActive - 1 - ContentConfiguration - - PBXBottomSmartGroupGIDs - - 1C37FBAC04509CD000000102 - 1C37FAAC04509CD000000102 - 1C08E77C0454961000C914BD - 1C37FABC05509CD000000102 - 1C37FABC05539CD112110102 - E2644B35053B69B200211256 - 1C37FABC04509CD000100104 - 1CC0EA4004350EF90044410B - 1CC0EA4004350EF90041110B - - PBXProjectModuleGUID - 11E0B1FE06471DED0097A5F4 - PBXProjectModuleLabel - Files - PBXProjectStructureProvided - yes - PBXSmartGroupTreeModuleColumnData - - PBXSmartGroupTreeModuleColumnWidthsKey - - 186 - - PBXSmartGroupTreeModuleColumnsKey_v4 - - MainColumn - - - PBXSmartGroupTreeModuleOutlineStateKey_v7 - - PBXSmartGroupTreeModuleOutlineStateExpansionKey - - 29B97314FDCFA39411CA2CEA - 1C37FABC05509CD000000102 - - PBXSmartGroupTreeModuleOutlineStateSelectionKey - - - 0 - - - PBXSmartGroupTreeModuleOutlineStateVisibleRectKey - {{0, 0}, {186, 337}} - - PBXTopSmartGroupGIDs - - XCIncludePerspectivesSwitch - 1 - XCSharingToken - com.apple.Xcode.GFSharingToken - - GeometryConfiguration - - Frame - {{0, 0}, {203, 355}} - GroupTreeTableConfiguration - - MainColumn - 186 - - RubberWindowFrame - 373 269 690 397 0 0 1440 878 - - Module - PBXSmartGroupTreeModule - Proportion - 100% - - - Name - Morph - PreferredWidth - 300 - ServiceClasses - - XCModuleDock - PBXSmartGroupTreeModule - - TableOfContents - - 11E0B1FE06471DED0097A5F4 - - ToolbarConfiguration - xcode.toolbar.config.default.shortV3 - - - PerspectivesBarVisible - - ShelfIsVisible - - SourceDescription - file at '/Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources/XCPerspectivesSpecificationMode1.xcperspec' - StatusbarIsVisible - - TimeStamp - 0.0 - ToolbarConfigUserDefaultsMinorVersion - 2 - ToolbarDisplayMode - 1 - ToolbarIsVisible - - ToolbarSizeMode - 1 - Type - Perspectives - UpdateMessage - The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'? - WindowJustification - 5 - WindowOrderList - - 1F8D1E4612DF5A0D00571730 - 1F8D1E4712DF5A0D00571730 - 1F6821201249D25900A03CED - 1CD10A99069EF8BA00B06720 - 1C78EAAD065D492600B07095 - /Users/jeena/Projects/Twittia/Twittia 2.xcodeproj - - WindowString - 469 55 1319 1363 0 0 2560 1418 - WindowToolsV3 - - - FirstTimeWindowDisplayed - - Identifier - windowTool.build - IsVertical - - Layout - - - Dock - - - ContentConfiguration - - PBXProjectModuleGUID - 1CD0528F0623707200166675 - PBXProjectModuleLabel - - StatusBarVisibility - - - GeometryConfiguration - - Frame - {{0, 0}, {1299, 402}} - RubberWindowFrame - 2771 56 1299 684 2560 0 1920 1200 - - Module - PBXNavigatorGroup - Proportion - 402pt - - - ContentConfiguration - - PBXProjectModuleGUID - XCMainBuildResultsModuleGUID - PBXProjectModuleLabel - Build Results - XCBuildResultsTrigger_Collapse - 1021 - XCBuildResultsTrigger_Open - 1011 - - GeometryConfiguration - - Frame - {{0, 407}, {1299, 236}} - RubberWindowFrame - 2771 56 1299 684 2560 0 1920 1200 - - Module - PBXBuildResultsModule - Proportion - 236pt - - - Proportion - 643pt - - - Name - Build Results - ServiceClasses - - PBXBuildResultsModule - - StatusbarIsVisible - - TableOfContents - - 1F6821201249D25900A03CED - 1F8D1E2912DF55D600571730 - 1CD0528F0623707200166675 - XCMainBuildResultsModuleGUID - - ToolbarConfiguration - xcode.toolbar.config.buildV3 - WindowContentMinSize - 486 300 - WindowString - 2771 56 1299 684 2560 0 1920 1200 - WindowToolGUID - 1F6821201249D25900A03CED - WindowToolIsVisible - - - - FirstTimeWindowDisplayed - - Identifier - windowTool.debugger - IsVertical - - Layout - - - Dock - - - ContentConfiguration - - Debugger - - HorizontalSplitView - - _collapsingFrameDimension - 0.0 - _indexOfCollapsedView - 0 - _percentageOfCollapsedView - 0.0 - isCollapsed - yes - sizes - - {{0, 0}, {316, 203}} - {{316, 0}, {378, 203}} - - - VerticalSplitView - - _collapsingFrameDimension - 0.0 - _indexOfCollapsedView - 0 - _percentageOfCollapsedView - 0.0 - isCollapsed - yes - sizes - - {{0, 0}, {694, 203}} - {{0, 203}, {694, 178}} - - - - LauncherConfigVersion - 8 - PBXProjectModuleGUID - 1C162984064C10D400B95A72 - PBXProjectModuleLabel - Debug - GLUTExamples (Underwater) - - GeometryConfiguration - - DebugConsoleVisible - None - DebugConsoleWindowFrame - {{200, 200}, {500, 300}} - DebugSTDIOWindowFrame - {{200, 200}, {500, 300}} - Frame - {{0, 0}, {694, 381}} - PBXDebugSessionStackFrameViewKey - - DebugVariablesTableConfiguration - - Name - 120 - Value - 85 - Summary - 148 - - Frame - {{316, 0}, {378, 203}} - RubberWindowFrame - 67 996 694 422 0 0 2560 1418 - - RubberWindowFrame - 67 996 694 422 0 0 2560 1418 - - Module - PBXDebugSessionModule - Proportion - 381pt - - - Proportion - 381pt - - - Name - Debugger - ServiceClasses - - PBXDebugSessionModule - - StatusbarIsVisible - - TableOfContents - - 1CD10A99069EF8BA00B06720 - 1F8D1E2A12DF55D600571730 - 1C162984064C10D400B95A72 - 1F8D1E2B12DF55D600571730 - 1F8D1E2C12DF55D600571730 - 1F8D1E2D12DF55D600571730 - 1F8D1E2E12DF55D600571730 - 1F8D1E2F12DF55D600571730 - - ToolbarConfiguration - xcode.toolbar.config.debugV3 - WindowString - 67 996 694 422 0 0 2560 1418 - WindowToolGUID - 1CD10A99069EF8BA00B06720 - WindowToolIsVisible - - - - Identifier - windowTool.find - Layout - - - Dock - - - Dock - - - ContentConfiguration - - PBXProjectModuleGUID - 1CDD528C0622207200134675 - PBXProjectModuleLabel - <No Editor> - PBXSplitModuleInNavigatorKey - - Split0 - - PBXProjectModuleGUID - 1CD0528D0623707200166675 - - SplitCount - 1 - - StatusBarVisibility - 1 - - GeometryConfiguration - - Frame - {{0, 0}, {781, 167}} - RubberWindowFrame - 62 385 781 470 0 0 1440 878 - - Module - PBXNavigatorGroup - Proportion - 781pt - - - Proportion - 50% - - - BecomeActive - 1 - ContentConfiguration - - PBXProjectModuleGUID - 1CD0528E0623707200166675 - PBXProjectModuleLabel - Project Find - - GeometryConfiguration - - Frame - {{8, 0}, {773, 254}} - RubberWindowFrame - 62 385 781 470 0 0 1440 878 - - Module - PBXProjectFindModule - Proportion - 50% - - - Proportion - 428pt - - - Name - Project Find - ServiceClasses - - PBXProjectFindModule - - StatusbarIsVisible - 1 - TableOfContents - - 1C530D57069F1CE1000CFCEE - 1C530D58069F1CE1000CFCEE - 1C530D59069F1CE1000CFCEE - 1CDD528C0622207200134675 - 1C530D5A069F1CE1000CFCEE - 1CE0B1FE06471DED0097A5F4 - 1CD0528E0623707200166675 - - WindowString - 62 385 781 470 0 0 1440 878 - WindowToolGUID - 1C530D57069F1CE1000CFCEE - WindowToolIsVisible - 0 - - - Identifier - MENUSEPARATOR - - - FirstTimeWindowDisplayed - - Identifier - windowTool.debuggerConsole - IsVertical - - Layout - - - Dock - - - BecomeActive - - ContentConfiguration - - PBXProjectModuleGUID - 1C78EAAC065D492600B07095 - PBXProjectModuleLabel - Debugger Console - - GeometryConfiguration - - Frame - {{0, 0}, {968, 946}} - RubberWindowFrame - 2810 187 968 987 2560 0 1920 1200 - - Module - PBXDebugCLIModule - Proportion - 946pt - - - Proportion - 946pt - - - Name - Debugger Console - ServiceClasses - - PBXDebugCLIModule - - StatusbarIsVisible - - TableOfContents - - 1C78EAAD065D492600B07095 - 1F8D1E4512DF5A0D00571730 - 1C78EAAC065D492600B07095 - - ToolbarConfiguration - xcode.toolbar.config.consoleV3 - WindowString - 2810 187 968 987 2560 0 1920 1200 - WindowToolGUID - 1C78EAAD065D492600B07095 - WindowToolIsVisible - - - - Identifier - windowTool.snapshots - Layout - - - Dock - - - Module - XCSnapshotModule - Proportion - 100% - - - Proportion - 100% - - - Name - Snapshots - ServiceClasses - - XCSnapshotModule - - StatusbarIsVisible - Yes - ToolbarConfiguration - xcode.toolbar.config.snapshots - WindowString - 315 824 300 550 0 0 1440 878 - WindowToolIsVisible - Yes - - - Identifier - windowTool.scm - Layout - - - Dock - - - ContentConfiguration - - PBXProjectModuleGUID - 1C78EAB2065D492600B07095 - PBXProjectModuleLabel - <No Editor> - PBXSplitModuleInNavigatorKey - - Split0 - - PBXProjectModuleGUID - 1C78EAB3065D492600B07095 - - SplitCount - 1 - - StatusBarVisibility - 1 - - GeometryConfiguration - - Frame - {{0, 0}, {452, 0}} - RubberWindowFrame - 743 379 452 308 0 0 1280 1002 - - Module - PBXNavigatorGroup - Proportion - 0pt - - - BecomeActive - 1 - ContentConfiguration - - PBXProjectModuleGUID - 1CD052920623707200166675 - PBXProjectModuleLabel - SCM - - GeometryConfiguration - - ConsoleFrame - {{0, 259}, {452, 0}} - Frame - {{0, 7}, {452, 259}} - RubberWindowFrame - 743 379 452 308 0 0 1280 1002 - TableConfiguration - - Status - 30 - FileName - 199 - Path - 197.0950012207031 - - TableFrame - {{0, 0}, {452, 250}} - - Module - PBXCVSModule - Proportion - 262pt - - - Proportion - 266pt - - - Name - SCM - ServiceClasses - - PBXCVSModule - - StatusbarIsVisible - 1 - TableOfContents - - 1C78EAB4065D492600B07095 - 1C78EAB5065D492600B07095 - 1C78EAB2065D492600B07095 - 1CD052920623707200166675 - - ToolbarConfiguration - xcode.toolbar.config.scm - WindowString - 743 379 452 308 0 0 1280 1002 - - - FirstTimeWindowDisplayed - - Identifier - windowTool.breakpoints - IsVertical - - Layout - - - Dock - - - ContentConfiguration - - PBXBottomSmartGroupGIDs - - 1C77FABC04509CD000000102 - - PBXProjectModuleGUID - 1CE0B1FE06471DED0097A5F4 - PBXProjectModuleLabel - Files - PBXProjectStructureProvided - no - PBXSmartGroupTreeModuleColumnData - - PBXSmartGroupTreeModuleColumnWidthsKey - - 168 - - PBXSmartGroupTreeModuleColumnsKey_v4 - - MainColumn - - - PBXSmartGroupTreeModuleOutlineStateKey_v7 - - PBXSmartGroupTreeModuleOutlineStateExpansionKey - - 1C77FABC04509CD000000102 - - PBXSmartGroupTreeModuleOutlineStateSelectionKey - - - 0 - - - PBXSmartGroupTreeModuleOutlineStateVisibleRectKey - {{0, 0}, {168, 350}} - - PBXTopSmartGroupGIDs - - XCIncludePerspectivesSwitch - - - GeometryConfiguration - - Frame - {{0, 0}, {185, 368}} - GroupTreeTableConfiguration - - MainColumn - 168 - - RubberWindowFrame - 836 546 744 409 0 0 2560 1418 - - Module - PBXSmartGroupTreeModule - Proportion - 185pt - - - BecomeActive - - ContentConfiguration - - PBXProjectModuleGUID - 1CA1AED706398EBD00589147 - PBXProjectModuleLabel - Detail - - GeometryConfiguration - - Frame - {{190, 0}, {554, 368}} - RubberWindowFrame - 836 546 744 409 0 0 2560 1418 - - Module - XCDetailModule - Proportion - 554pt - - - Proportion - 368pt - - - MajorVersion - 3 - MinorVersion - 0 - Name - Breakpoints - ServiceClasses - - PBXSmartGroupTreeModule - XCDetailModule - - StatusbarIsVisible - - TableOfContents - - 1F618EB812DB5D0700E500D9 - 1F618EB912DB5D0700E500D9 - 1CE0B1FE06471DED0097A5F4 - 1CA1AED706398EBD00589147 - - ToolbarConfiguration - xcode.toolbar.config.breakpointsV3 - WindowString - 836 546 744 409 0 0 2560 1418 - WindowToolGUID - 1F618EB812DB5D0700E500D9 - WindowToolIsVisible - - - - Identifier - windowTool.debugAnimator - Layout - - - Dock - - - Module - PBXNavigatorGroup - Proportion - 100% - - - Proportion - 100% - - - Name - Debug Visualizer - ServiceClasses - - PBXNavigatorGroup - - StatusbarIsVisible - 1 - ToolbarConfiguration - xcode.toolbar.config.debugAnimatorV3 - WindowString - 100 100 700 500 0 0 1280 1002 - - - Identifier - windowTool.bookmarks - Layout - - - Dock - - - Module - PBXBookmarksModule - Proportion - 100% - - - Proportion - 100% - - - Name - Bookmarks - ServiceClasses - - PBXBookmarksModule - - StatusbarIsVisible - 0 - WindowString - 538 42 401 187 0 0 1280 1002 - - - Identifier - windowTool.projectFormatConflicts - Layout - - - Dock - - - Module - XCProjectFormatConflictsModule - Proportion - 100% - - - Proportion - 100% - - - Name - Project Format Conflicts - ServiceClasses - - XCProjectFormatConflictsModule - - StatusbarIsVisible - 0 - WindowContentMinSize - 450 300 - WindowString - 50 850 472 307 0 0 1440 877 - - - Identifier - windowTool.classBrowser - Layout - - - Dock - - - BecomeActive - 1 - ContentConfiguration - - OptionsSetName - Hierarchy, all classes - PBXProjectModuleGUID - 1CA6456E063B45B4001379D8 - PBXProjectModuleLabel - Class Browser - NSObject - - GeometryConfiguration - - ClassesFrame - {{0, 0}, {374, 96}} - ClassesTreeTableConfiguration - - PBXClassNameColumnIdentifier - 208 - PBXClassBookColumnIdentifier - 22 - - Frame - {{0, 0}, {630, 331}} - MembersFrame - {{0, 105}, {374, 395}} - MembersTreeTableConfiguration - - PBXMemberTypeIconColumnIdentifier - 22 - PBXMemberNameColumnIdentifier - 216 - PBXMemberTypeColumnIdentifier - 97 - PBXMemberBookColumnIdentifier - 22 - - PBXModuleWindowStatusBarHidden2 - 1 - RubberWindowFrame - 385 179 630 352 0 0 1440 878 - - Module - PBXClassBrowserModule - Proportion - 332pt - - - Proportion - 332pt - - - Name - Class Browser - ServiceClasses - - PBXClassBrowserModule - - StatusbarIsVisible - 0 - TableOfContents - - 1C0AD2AF069F1E9B00FABCE6 - 1C0AD2B0069F1E9B00FABCE6 - 1CA6456E063B45B4001379D8 - - ToolbarConfiguration - xcode.toolbar.config.classbrowser - WindowString - 385 179 630 352 0 0 1440 878 - WindowToolGUID - 1C0AD2AF069F1E9B00FABCE6 - WindowToolIsVisible - 0 - - - Identifier - windowTool.refactoring - IncludeInToolsMenu - 0 - Layout - - - Dock - - - BecomeActive - 1 - GeometryConfiguration - - Frame - {0, 0}, {500, 335} - RubberWindowFrame - {0, 0}, {500, 335} - - Module - XCRefactoringModule - Proportion - 100% - - - Proportion - 100% - - - Name - Refactoring - ServiceClasses - - XCRefactoringModule - - WindowString - 200 200 500 356 0 0 1920 1200 - - - - diff --git a/Mac/Bungloo.xcodeproj/jeena.pbxuser b/Mac/Bungloo.xcodeproj/jeena.pbxuser deleted file mode 100644 index 16fe5ce..0000000 --- a/Mac/Bungloo.xcodeproj/jeena.pbxuser +++ /dev/null @@ -1,496 +0,0 @@ -// !$*UTF8*$! -{ - 1F17508512A972DF004A0B42 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 1FFA36CB1177D861006C8562 /* default.css */; - name = "default.css: 80"; - rLen = 0; - rLoc = 1037; - rType = 0; - vrLen = 553; - vrLoc = 411; - }; - 1F198FC7117BC4AB0049BEA7 /* README.markdown */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {949, 1237}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 1498}"; - }; - }; - 1F1990DF117BD2250049BEA7 /* Appcast.xml */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {949, 1237}}"; - sepNavSelRange = "{784, 0}"; - sepNavVisRange = "{0, 954}"; - }; - }; - 1F1990E1117BD2650049BEA7 /* ReleaseNotes.html */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {949, 1285}}"; - sepNavSelRange = "{461, 0}"; - sepNavVisRange = "{0, 1964}"; - }; - }; - 1F27470412D905CA00339B4F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 1FE2FCA6117A8952000504B0 /* dsa_pub.pem */; - name = "dsa_pub.pem: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 1178; - vrLoc = 0; - }; - 1F2F793712BD93A600F073BE /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 1FFA36D51177D879006C8562 /* ViewDelegate.m */; - name = "ViewDelegate.m: 37"; - rLen = 13; - rLoc = 1089; - rType = 0; - vrLen = 1550; - vrLoc = 0; - }; - 1F364396118CBC77008198EF /* OAuth.h */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {949, 1237}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 636}"; - }; - }; - 1F364397118CBC77008198EF /* OAuth.m */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {1034, 2655}}"; - sepNavSelRange = "{4216, 0}"; - sepNavVisRange = "{2668, 3057}"; - }; - }; - 1F4673E61180F654006CC37C /* TwittiaCore.js */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {1013, 5355}}"; - sepNavSelRange = "{1631, 0}"; - sepNavVisRange = "{248, 3030}"; - }; - }; - 1F618EA612DB5D0200E500D9 /* MyDocument.m:108 */ = { - isa = PBXFileBreakpoint; - actions = ( - ); - breakpointStyle = 0; - continueAfterActions = 0; - countType = 0; - delayBeforeContinue = 0; - fileReference = 2A37F4ACFDCFA73011CA2CEA /* MyDocument.m */; - functionName = "-sendTweet:"; - hitCount = 1; - ignoreCount = 0; - lineNumber = 108; - location = Twittia; - modificationTime = 316627463.947617; - originalNumberOfMultipleMatches = 1; - state = 1; - }; - 1F618EAC12DB5D0700E500D9 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 2A37F4AEFDCFA73011CA2CEA /* MyDocument.h */; - name = "MyDocument.h: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 573; - vrLoc = 0; - }; - 1F618EC812DB5E6100E500D9 /* TweetModel.h */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {949, 1262}}"; - sepNavSelRange = "{358, 0}"; - sepNavVisRange = "{0, 366}"; - }; - }; - 1F618EC912DB5E6100E500D9 /* TweetModel.m */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {949, 1262}}"; - sepNavSelRange = "{279, 0}"; - sepNavVisRange = "{0, 316}"; - }; - }; - 1F618ED112DB60D100E500D9 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 2A37F4ACFDCFA73011CA2CEA /* MyDocument.m */; - name = "MyDocument.m: 107"; - rLen = 0; - rLoc = 3758; - rType = 0; - vrLen = 3377; - vrLoc = 537; - }; - 1F618ED212DB60D100E500D9 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 1F618EC812DB5E6100E500D9 /* TweetModel.h */; - name = "TweetModel.h: 18"; - rLen = 0; - rLoc = 358; - rType = 0; - vrLen = 366; - vrLoc = 0; - }; - 1F618ED312DB60D100E500D9 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 1F618EC912DB5E6100E500D9 /* TweetModel.m */; - name = "TweetModel.m: 18"; - rLen = 0; - rLoc = 279; - rType = 0; - vrLen = 316; - vrLoc = 0; - }; - 1F618ED412DB60D100E500D9 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 1FFA36D21177D879006C8562 /* Controller.h */; - name = "Controller.h: 10"; - rLen = 25; - rLoc = 149; - rType = 0; - vrLen = 1539; - vrLoc = 0; - }; - 1F618ED512DB60D100E500D9 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 1F364396118CBC77008198EF /* OAuth.h */; - name = "OAuth.h: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 636; - vrLoc = 0; - }; - 1F618ED612DB60D100E500D9 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 1F364397118CBC77008198EF /* OAuth.m */; - name = "OAuth.m: 135"; - rLen = 0; - rLoc = 4216; - rType = 0; - vrLen = 3057; - vrLoc = 2668; - }; - 1F618F0212DB665B00E500D9 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 1FFA36D31177D879006C8562 /* Controller.m */; - name = "Controller.m: 178"; - rLen = 0; - rLoc = 5952; - rType = 0; - vrLen = 2979; - vrLoc = 4466; - }; - 1F618F0312DB665B00E500D9 /* PlistBookmark */ = { - isa = PlistBookmark; - fRef = 8D15AC360486D014006FF6A4 /* Twittia_2-Info.plist */; - fallbackIsa = PBXBookmark; - isK = 0; - kPath = ( - LSMinimumSystemVersion, - ); - name = "/Users/jeena/Projects/Twittia/Twittia_2-Info.plist"; - rLen = 0; - rLoc = 9223372036854775808; - }; - 1F618F0412DB665B00E500D9 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 1F1990DF117BD2250049BEA7 /* Appcast.xml */; - name = "Appcast.xml: 15"; - rLen = 0; - rLoc = 784; - rType = 0; - vrLen = 954; - vrLoc = 0; - }; - 1F618F0512DB665B00E500D9 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 1F198FC7117BC4AB0049BEA7 /* README.markdown */; - name = "README.markdown: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 1498; - vrLoc = 0; - }; - 1F68210012493A3400A03CED /* Twittia */ = { - isa = PBXExecutable; - activeArgIndices = ( - ); - argumentStrings = ( - ); - autoAttachOnCrash = 1; - breakpointsEnabled = 0; - configStateDict = { - }; - customDataFormattersEnabled = 1; - dataTipCustomDataFormattersEnabled = 1; - dataTipShowTypeColumn = 1; - dataTipSortType = 0; - debuggerPlugin = GDBDebugging; - disassemblyDisplayState = 0; - dylibVariantSuffix = ""; - enableDebugStr = 1; - environmentEntries = ( - ); - executableSystemSymbolLevel = 0; - executableUserSymbolLevel = 0; - libgmallocEnabled = 0; - name = Twittia; - savedGlobals = { - }; - showTypeColumn = 0; - sourceDirectories = ( - ); - variableFormatDictionary = { - }; - }; - 1F68211B12493A5400A03CED /* Source Control */ = { - isa = PBXSourceControlManager; - fallbackIsa = XCSourceControlManager; - isSCMEnabled = 0; - scmConfiguration = { - repositoryNamesForRoots = { - "" = ""; - }; - }; - }; - 1F68211C12493A5400A03CED /* Code sense */ = { - isa = PBXCodeSenseManager; - indexTemplatePath = ""; - }; - 1F77DB46118C5F1C007C7F1E /* Constants.m */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {1115, 3300}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 1114}"; - }; - }; - 1F8D1E4212DF5A0D00571730 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 1F1990E1117BD2650049BEA7 /* ReleaseNotes.html */; - name = "ReleaseNotes.html: 16"; - rLen = 0; - rLoc = 461; - rType = 0; - vrLen = 1964; - vrLoc = 0; - }; - 1F8D1E4312DF5A0D00571730 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 1F4673E61180F654006CC37C /* TwittiaCore.js */; - name = "TwittiaCore.js: 90"; - rLen = 3; - rLoc = 3369; - rType = 0; - vrLen = 3174; - vrLoc = 376; - }; - 1F8D1E4412DF5A0D00571730 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 1F4673E61180F654006CC37C /* TwittiaCore.js */; - name = "TwittiaCore.js: 66"; - rLen = 0; - rLoc = 1631; - rType = 0; - vrLen = 3030; - vrLoc = 248; - }; - 1F98DCA9124C691A004289ED /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 1F77DB46118C5F1C007C7F1E /* Constants.m */; - name = "Constants.m: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 1114; - vrLoc = 0; - }; - 1F98DCAD124C691A004289ED /* PBXBookmark */ = { - isa = PBXBookmark; - fRef = 1F98DC9D124BFFD7004289ED /* pin.png */; - }; - 1FE2FCA6117A8952000504B0 /* dsa_pub.pem */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {949, 865}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 1178}"; - }; - }; - 1FFA36CB1177D861006C8562 /* default.css */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {1115, 3270}}"; - sepNavSelRange = "{1037, 0}"; - sepNavVisRange = "{411, 553}"; - }; - }; - 1FFA36D21177D879006C8562 /* Controller.h */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {949, 1237}}"; - sepNavSelRange = "{149, 25}"; - sepNavVisRange = "{0, 1539}"; - }; - }; - 1FFA36D31177D879006C8562 /* Controller.m */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {1238, 3285}}"; - sepNavSelRange = "{5834, 0}"; - sepNavVisRange = "{5432, 1211}"; - }; - }; - 1FFA36D51177D879006C8562 /* ViewDelegate.m */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {1517, 1237}}"; - sepNavSelRange = "{1089, 13}"; - sepNavVisRange = "{0, 1550}"; - }; - }; - 2A37F4A9FDCFA73011CA2CEA /* Project object */ = { - activeBuildConfigurationName = Release; - activeExecutable = 1F68210012493A3400A03CED /* Twittia */; - activeTarget = 8D15AC270486D014006FF6A4 /* Twittia */; - addToTargets = ( - 8D15AC270486D014006FF6A4 /* Twittia */, - ); - breakpoints = ( - 1F618EA612DB5D0200E500D9 /* MyDocument.m:108 */, - ); - codeSenseManager = 1F68211C12493A5400A03CED /* Code sense */; - executables = ( - 1F68210012493A3400A03CED /* Twittia */, - ); - perUserDictionary = { - "PBXConfiguration.PBXBreakpointsDataSource.v1:1CA1AED706398EBD00589147" = { - PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; - PBXFileTableDataSourceColumnSortingKey = PBXBreakpointsDataSource_BreakpointID; - PBXFileTableDataSourceColumnWidthsKey = ( - 20, - 20, - 198, - 20, - 99, - 99, - 29, - 20, - ); - PBXFileTableDataSourceColumnsKey = ( - PBXBreakpointsDataSource_ActionID, - PBXBreakpointsDataSource_TypeID, - PBXBreakpointsDataSource_BreakpointID, - PBXBreakpointsDataSource_UseID, - PBXBreakpointsDataSource_LocationID, - PBXBreakpointsDataSource_ConditionID, - PBXBreakpointsDataSource_IgnoreCountID, - PBXBreakpointsDataSource_ContinueID, - ); - }; - PBXConfiguration.PBXFileTableDataSource3.PBXBookmarksDataSource = { - PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; - PBXFileTableDataSourceColumnSortingKey = PBXBookmarksDataSource_NameID; - PBXFileTableDataSourceColumnWidthsKey = ( - 200, - 200, - 580.58349609375, - ); - PBXFileTableDataSourceColumnsKey = ( - PBXBookmarksDataSource_LocationID, - PBXBookmarksDataSource_NameID, - PBXBookmarksDataSource_CommentsID, - ); - }; - PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = { - PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; - PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; - PBXFileTableDataSourceColumnWidthsKey = ( - 20, - 771, - 20, - 48, - 43, - 43, - 20, - ); - PBXFileTableDataSourceColumnsKey = ( - PBXFileDataSource_FiletypeID, - PBXFileDataSource_Filename_ColumnID, - PBXFileDataSource_Built_ColumnID, - PBXFileDataSource_ObjectSize_ColumnID, - PBXFileDataSource_Errors_ColumnID, - PBXFileDataSource_Warnings_ColumnID, - PBXFileDataSource_Target_ColumnID, - ); - }; - PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = { - PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; - PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; - PBXFileTableDataSourceColumnWidthsKey = ( - 20, - 731, - 60, - 20, - 48.16259765625, - 43, - 43, - ); - PBXFileTableDataSourceColumnsKey = ( - PBXFileDataSource_FiletypeID, - PBXFileDataSource_Filename_ColumnID, - PBXTargetDataSource_PrimaryAttribute, - PBXFileDataSource_Built_ColumnID, - PBXFileDataSource_ObjectSize_ColumnID, - PBXFileDataSource_Errors_ColumnID, - PBXFileDataSource_Warnings_ColumnID, - ); - }; - PBXPerProjectTemplateStateSaveDate = 316626383; - PBXWorkspaceStateSaveDate = 316626383; - }; - perUserProjectItems = { - 1F17508512A972DF004A0B42 /* PBXTextBookmark */ = 1F17508512A972DF004A0B42 /* PBXTextBookmark */; - 1F27470412D905CA00339B4F /* PBXTextBookmark */ = 1F27470412D905CA00339B4F /* PBXTextBookmark */; - 1F2F793712BD93A600F073BE /* PBXTextBookmark */ = 1F2F793712BD93A600F073BE /* PBXTextBookmark */; - 1F618EAC12DB5D0700E500D9 /* PBXTextBookmark */ = 1F618EAC12DB5D0700E500D9 /* PBXTextBookmark */; - 1F618ED112DB60D100E500D9 /* PBXTextBookmark */ = 1F618ED112DB60D100E500D9 /* PBXTextBookmark */; - 1F618ED212DB60D100E500D9 /* PBXTextBookmark */ = 1F618ED212DB60D100E500D9 /* PBXTextBookmark */; - 1F618ED312DB60D100E500D9 /* PBXTextBookmark */ = 1F618ED312DB60D100E500D9 /* PBXTextBookmark */; - 1F618ED412DB60D100E500D9 /* PBXTextBookmark */ = 1F618ED412DB60D100E500D9 /* PBXTextBookmark */; - 1F618ED512DB60D100E500D9 /* PBXTextBookmark */ = 1F618ED512DB60D100E500D9 /* PBXTextBookmark */; - 1F618ED612DB60D100E500D9 /* PBXTextBookmark */ = 1F618ED612DB60D100E500D9 /* PBXTextBookmark */; - 1F618F0212DB665B00E500D9 /* PBXTextBookmark */ = 1F618F0212DB665B00E500D9 /* PBXTextBookmark */; - 1F618F0312DB665B00E500D9 /* PlistBookmark */ = 1F618F0312DB665B00E500D9 /* PlistBookmark */; - 1F618F0412DB665B00E500D9 /* PBXTextBookmark */ = 1F618F0412DB665B00E500D9 /* PBXTextBookmark */; - 1F618F0512DB665B00E500D9 /* PBXTextBookmark */ = 1F618F0512DB665B00E500D9 /* PBXTextBookmark */; - 1F8D1E4212DF5A0D00571730 /* PBXTextBookmark */ = 1F8D1E4212DF5A0D00571730 /* PBXTextBookmark */; - 1F8D1E4312DF5A0D00571730 /* PBXTextBookmark */ = 1F8D1E4312DF5A0D00571730 /* PBXTextBookmark */; - 1F8D1E4412DF5A0D00571730 /* PBXTextBookmark */ = 1F8D1E4412DF5A0D00571730 /* PBXTextBookmark */; - 1F98DCA9124C691A004289ED /* PBXTextBookmark */ = 1F98DCA9124C691A004289ED /* PBXTextBookmark */; - 1F98DCAD124C691A004289ED /* PBXBookmark */ = 1F98DCAD124C691A004289ED /* PBXBookmark */; - }; - sourceControlManager = 1F68211B12493A5400A03CED /* Source Control */; - userBuildSettings = { - }; - }; - 2A37F4ACFDCFA73011CA2CEA /* MyDocument.m */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {1748, 1755}}"; - sepNavSelRange = "{3758, 0}"; - sepNavVisRange = "{537, 3377}"; - }; - }; - 2A37F4AEFDCFA73011CA2CEA /* MyDocument.h */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {949, 1262}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 573}"; - }; - }; - 8D15AC270486D014006FF6A4 /* Twittia */ = { - activeExec = 0; - executables = ( - 1F68210012493A3400A03CED /* Twittia */, - ); - }; -} diff --git a/Mac/Bungloo.xcodeproj/project.pbxproj b/Mac/Bungloo.xcodeproj/project.pbxproj deleted file mode 100644 index b83b54a..0000000 --- a/Mac/Bungloo.xcodeproj/project.pbxproj +++ /dev/null @@ -1,448 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 1DDD582C0DA1D0D100B32029 /* NewMessageWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1DDD58280DA1D0D100B32029 /* NewMessageWindow.xib */; }; - 1DDD582D0DA1D0D100B32029 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1DDD582A0DA1D0D100B32029 /* MainMenu.xib */; }; - 1F122D49118E1DE100E83B77 /* Icon.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1F122D48118E1DE100E83B77 /* Icon.icns */; }; - 1F132C791666CD9700E4E661 /* TB_SendTemplate.png in Resources */ = {isa = PBXBuildFile; fileRef = 1F132C781666CD9700E4E661 /* TB_SendTemplate.png */; }; - 1F1990C6117BCA960049BEA7 /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F1990C5117BCA960049BEA7 /* ApplicationServices.framework */; }; - 1F1C80F916482A250010B409 /* WebKit in Resources */ = {isa = PBXBuildFile; fileRef = 1F1C80F816482A250010B409 /* WebKit */; }; - 1F2D79BD165E8C6B000E8428 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F2D79BC165E8C6B000E8428 /* CoreLocation.framework */; }; - 1F303BE31660752700891D71 /* QuickLook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F303BE21660752700891D71 /* QuickLook.framework */; }; - 1F3F129E164F202000C7C983 /* dsa_pub.pem in Resources */ = {isa = PBXBuildFile; fileRef = 1F3F129D164F202000C7C983 /* dsa_pub.pem */; }; - 1F618ECA12DB5E6100E500D9 /* PostModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F618EC912DB5E6100E500D9 /* PostModel.m */; }; - 1F70619F1178FBB300C85707 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F70619E1178FBB300C85707 /* Carbon.framework */; }; - 1F77DB47118C5F1C007C7F1E /* Constants.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F77DB46118C5F1C007C7F1E /* Constants.m */; }; - 1F880B6B165EE0F60022A84D /* NSData+Base64.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F880B6A165EE0F60022A84D /* NSData+Base64.m */; }; - 1F880B6E165FE8890022A84D /* MimeType.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F880B6D165FE8890022A84D /* MimeType.m */; }; - 1FA09847144602530079E258 /* libicucore.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1FA09846144602530079E258 /* libicucore.dylib */; }; - 1FC254A01427DFAD0035D84B /* AccessToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FC2549B1427D9930035D84B /* AccessToken.m */; }; - 1FDEF722164EFE9100F927F3 /* Growl.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1FDEF721164EFE9100F927F3 /* Growl.framework */; }; - 1FDEF723164EFF3100F927F3 /* Growl.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1FDEF721164EFE9100F927F3 /* Growl.framework */; }; - 1FDEF726164F094600F927F3 /* Growl Registration Ticket.growlRegDict in Resources */ = {isa = PBXBuildFile; fileRef = 1FDEF724164F079800F927F3 /* Growl Registration Ticket.growlRegDict */; }; - 1FE2FC93117A818D000504B0 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1FE2FC92117A818D000504B0 /* Sparkle.framework */; }; - 1FE2FCA4117A83B1000504B0 /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1FE2FC92117A818D000504B0 /* Sparkle.framework */; }; - 1FFA36D71177D879006C8562 /* Controller.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FFA36D31177D879006C8562 /* Controller.m */; }; - 1FFA36D81177D879006C8562 /* ViewDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FFA36D51177D879006C8562 /* ViewDelegate.m */; }; - 1FFA37071177DAF4006C8562 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1FFA37061177DAF4006C8562 /* WebKit.framework */; }; - 6B68359B166015C4004F4732 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6B68359A166015C4004F4732 /* Security.framework */; }; - 8D15AC2C0486D014006FF6A4 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 2A37F4B9FDCFA73011CA2CEA /* Credits.rtf */; }; - 8D15AC2F0486D014006FF6A4 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165FFE840EACC02AAC07 /* InfoPlist.strings */; }; - 8D15AC310486D014006FF6A4 /* NewMessageWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A37F4ACFDCFA73011CA2CEA /* NewMessageWindow.m */; settings = {ATTRIBUTES = (); }; }; - 8D15AC320486D014006FF6A4 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A37F4B0FDCFA73011CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; - 8D15AC340486D014006FF6A4 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 1FE2FCA1117A82E1000504B0 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 1FE2FCA4117A83B1000504B0 /* Sparkle.framework in CopyFiles */, - 1FDEF723164EFF3100F927F3 /* Growl.framework in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 089C1660FE840EACC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; - 1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; - 13E42FBA07B3F13500E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; - 1DDD58290DA1D0D100B32029 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/NewMessageWindow.xib; sourceTree = ""; }; - 1DDD582B0DA1D0D100B32029 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MainMenu.xib; sourceTree = ""; }; - 1F122D48118E1DE100E83B77 /* Icon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Icon.icns; sourceTree = ""; }; - 1F132C781666CD9700E4E661 /* TB_SendTemplate.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = TB_SendTemplate.png; sourceTree = ""; }; - 1F1990C5117BCA960049BEA7 /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = System/Library/Frameworks/ApplicationServices.framework; sourceTree = SDKROOT; }; - 1F1C80F816482A250010B409 /* WebKit */ = {isa = PBXFileReference; lastKnownFileType = folder; name = WebKit; path = ../WebKit; sourceTree = ""; }; - 1F2D79BC165E8C6B000E8428 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = /System/Library/Frameworks/CoreLocation.framework; sourceTree = ""; }; - 1F303BE21660752700891D71 /* QuickLook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickLook.framework; path = /System/Library/Frameworks/QuickLook.framework; sourceTree = ""; }; - 1F3F129D164F202000C7C983 /* dsa_pub.pem */ = {isa = PBXFileReference; lastKnownFileType = text; name = dsa_pub.pem; path = publish/dsa_pub.pem; sourceTree = ""; }; - 1F55BA1216C852FB009F0306 /* Bungloo_Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Bungloo_Prefix.pch; sourceTree = ""; }; - 1F618EC812DB5E6100E500D9 /* PostModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = PostModel.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - 1F618EC912DB5E6100E500D9 /* PostModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = PostModel.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; - 1F70619E1178FBB300C85707 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; }; - 1F77DB45118C5F1C007C7F1E /* Constants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = Constants.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - 1F77DB46118C5F1C007C7F1E /* Constants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = Constants.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; - 1F880B69165EE0F60022A84D /* NSData+Base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+Base64.h"; sourceTree = ""; }; - 1F880B6A165EE0F60022A84D /* NSData+Base64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+Base64.m"; sourceTree = ""; }; - 1F880B6C165FE8890022A84D /* MimeType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MimeType.h; sourceTree = ""; }; - 1F880B6D165FE8890022A84D /* MimeType.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MimeType.m; sourceTree = ""; }; - 1FA09846144602530079E258 /* libicucore.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libicucore.dylib; path = usr/lib/libicucore.dylib; sourceTree = SDKROOT; }; - 1FC2549A1427D9930035D84B /* AccessToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = AccessToken.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - 1FC2549B1427D9930035D84B /* AccessToken.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = AccessToken.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; - 1FDEF721164EFE9100F927F3 /* Growl.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Growl.framework; sourceTree = ""; }; - 1FDEF724164F079800F927F3 /* Growl Registration Ticket.growlRegDict */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "Growl Registration Ticket.growlRegDict"; sourceTree = ""; }; - 1FE2FC92117A818D000504B0 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Sparkle.framework; sourceTree = ""; }; - 1FFA36D21177D879006C8562 /* Controller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = Controller.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - 1FFA36D31177D879006C8562 /* Controller.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = Controller.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; - 1FFA36D41177D879006C8562 /* ViewDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewDelegate.h; sourceTree = ""; }; - 1FFA36D51177D879006C8562 /* ViewDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewDelegate.m; sourceTree = ""; }; - 1FFA37061177DAF4006C8562 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; - 2A37F4ACFDCFA73011CA2CEA /* NewMessageWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = NewMessageWindow.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; - 2A37F4AEFDCFA73011CA2CEA /* NewMessageWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = NewMessageWindow.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - 2A37F4B0FDCFA73011CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = main.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; - 2A37F4BAFDCFA73011CA2CEA /* English */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = English; path = English.lproj/Credits.rtf; sourceTree = ""; }; - 2A37F4C4FDCFA73011CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; - 2A37F4C5FDCFA73011CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; - 6B68359A166015C4004F4732 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = /System/Library/Frameworks/Security.framework; sourceTree = ""; }; - 8D15AC360486D014006FF6A4 /* Bungloo-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Bungloo-Info.plist"; sourceTree = ""; }; - 8D15AC370486D014006FF6A4 /* Bungloo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Bungloo.app; sourceTree = BUILT_PRODUCTS_DIR; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 8D15AC330486D014006FF6A4 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 1F303BE31660752700891D71 /* QuickLook.framework in Frameworks */, - 6B68359B166015C4004F4732 /* Security.framework in Frameworks */, - 1F2D79BD165E8C6B000E8428 /* CoreLocation.framework in Frameworks */, - 1FDEF722164EFE9100F927F3 /* Growl.framework in Frameworks */, - 1FA09847144602530079E258 /* libicucore.dylib in Frameworks */, - 8D15AC340486D014006FF6A4 /* Cocoa.framework in Frameworks */, - 1FFA37071177DAF4006C8562 /* WebKit.framework in Frameworks */, - 1F70619F1178FBB300C85707 /* Carbon.framework in Frameworks */, - 1FE2FC93117A818D000504B0 /* Sparkle.framework in Frameworks */, - 1F1990C6117BCA960049BEA7 /* ApplicationServices.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 1058C7A6FEA54F5311CA2CBB /* Linked Frameworks */ = { - isa = PBXGroup; - children = ( - 1F303BE21660752700891D71 /* QuickLook.framework */, - 6B68359A166015C4004F4732 /* Security.framework */, - 1F2D79BC165E8C6B000E8428 /* CoreLocation.framework */, - 1FDEF721164EFE9100F927F3 /* Growl.framework */, - 1FE2FC92117A818D000504B0 /* Sparkle.framework */, - 1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */, - 1FFA37061177DAF4006C8562 /* WebKit.framework */, - 1F70619E1178FBB300C85707 /* Carbon.framework */, - 1F1990C5117BCA960049BEA7 /* ApplicationServices.framework */, - ); - name = "Linked Frameworks"; - sourceTree = ""; - }; - 1058C7A8FEA54F5311CA2CBB /* Other Frameworks */ = { - isa = PBXGroup; - children = ( - 2A37F4C4FDCFA73011CA2CEA /* AppKit.framework */, - 13E42FBA07B3F13500E4EEF1 /* CoreData.framework */, - 2A37F4C5FDCFA73011CA2CEA /* Foundation.framework */, - ); - name = "Other Frameworks"; - sourceTree = ""; - }; - 19C28FB0FE9D524F11CA2CBB /* Products */ = { - isa = PBXGroup; - children = ( - 8D15AC370486D014006FF6A4 /* Bungloo.app */, - ); - name = Products; - sourceTree = ""; - }; - 2A37F4AAFDCFA73011CA2CEA /* Twittia 2 */ = { - isa = PBXGroup; - children = ( - 1FA09846144602530079E258 /* libicucore.dylib */, - 2A37F4ABFDCFA73011CA2CEA /* Classes */, - 2A37F4AFFDCFA73011CA2CEA /* Other Sources */, - 2A37F4B8FDCFA73011CA2CEA /* Resources */, - 2A37F4C3FDCFA73011CA2CEA /* Frameworks */, - 19C28FB0FE9D524F11CA2CBB /* Products */, - ); - name = "Twittia 2"; - sourceTree = ""; - }; - 2A37F4ABFDCFA73011CA2CEA /* Classes */ = { - isa = PBXGroup; - children = ( - 1FFA36D21177D879006C8562 /* Controller.h */, - 1FFA36D31177D879006C8562 /* Controller.m */, - 1FFA36D41177D879006C8562 /* ViewDelegate.h */, - 1FFA36D51177D879006C8562 /* ViewDelegate.m */, - 2A37F4AEFDCFA73011CA2CEA /* NewMessageWindow.h */, - 2A37F4ACFDCFA73011CA2CEA /* NewMessageWindow.m */, - 1F77DB45118C5F1C007C7F1E /* Constants.h */, - 1F77DB46118C5F1C007C7F1E /* Constants.m */, - 1F618EC812DB5E6100E500D9 /* PostModel.h */, - 1F618EC912DB5E6100E500D9 /* PostModel.m */, - 1FC2549A1427D9930035D84B /* AccessToken.h */, - 1FC2549B1427D9930035D84B /* AccessToken.m */, - 1F880B69165EE0F60022A84D /* NSData+Base64.h */, - 1F880B6A165EE0F60022A84D /* NSData+Base64.m */, - 1F880B6C165FE8890022A84D /* MimeType.h */, - 1F880B6D165FE8890022A84D /* MimeType.m */, - ); - name = Classes; - sourceTree = ""; - }; - 2A37F4AFFDCFA73011CA2CEA /* Other Sources */ = { - isa = PBXGroup; - children = ( - 1F55BA1216C852FB009F0306 /* Bungloo_Prefix.pch */, - 2A37F4B0FDCFA73011CA2CEA /* main.m */, - ); - name = "Other Sources"; - sourceTree = ""; - }; - 2A37F4B8FDCFA73011CA2CEA /* Resources */ = { - isa = PBXGroup; - children = ( - 1F1C80F816482A250010B409 /* WebKit */, - 1F122D48118E1DE100E83B77 /* Icon.icns */, - 1F3F129D164F202000C7C983 /* dsa_pub.pem */, - 1F132C781666CD9700E4E661 /* TB_SendTemplate.png */, - 2A37F4B9FDCFA73011CA2CEA /* Credits.rtf */, - 8D15AC360486D014006FF6A4 /* Bungloo-Info.plist */, - 089C165FFE840EACC02AAC07 /* InfoPlist.strings */, - 1DDD58280DA1D0D100B32029 /* NewMessageWindow.xib */, - 1DDD582A0DA1D0D100B32029 /* MainMenu.xib */, - 1FDEF724164F079800F927F3 /* Growl Registration Ticket.growlRegDict */, - ); - name = Resources; - sourceTree = ""; - }; - 2A37F4C3FDCFA73011CA2CEA /* Frameworks */ = { - isa = PBXGroup; - children = ( - 1058C7A6FEA54F5311CA2CBB /* Linked Frameworks */, - 1058C7A8FEA54F5311CA2CBB /* Other Frameworks */, - ); - name = Frameworks; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 8D15AC270486D014006FF6A4 /* Bungloo */ = { - isa = PBXNativeTarget; - buildConfigurationList = C05733C708A9546B00998B17 /* Build configuration list for PBXNativeTarget "Bungloo" */; - buildPhases = ( - 8D15AC2B0486D014006FF6A4 /* Resources */, - 8D15AC300486D014006FF6A4 /* Sources */, - 8D15AC330486D014006FF6A4 /* Frameworks */, - 1FE2FCA1117A82E1000504B0 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Bungloo; - productInstallPath = "$(HOME)/Applications"; - productName = "Twittia 2"; - productReference = 8D15AC370486D014006FF6A4 /* Bungloo.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 2A37F4A9FDCFA73011CA2CEA /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0450; - }; - buildConfigurationList = C05733CB08A9546B00998B17 /* Build configuration list for PBXProject "Bungloo" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 1; - knownRegions = ( - English, - Japanese, - French, - German, - ); - mainGroup = 2A37F4AAFDCFA73011CA2CEA /* Twittia 2 */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 8D15AC270486D014006FF6A4 /* Bungloo */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 8D15AC2B0486D014006FF6A4 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 1F3F129E164F202000C7C983 /* dsa_pub.pem in Resources */, - 1FDEF726164F094600F927F3 /* Growl Registration Ticket.growlRegDict in Resources */, - 8D15AC2C0486D014006FF6A4 /* Credits.rtf in Resources */, - 8D15AC2F0486D014006FF6A4 /* InfoPlist.strings in Resources */, - 1DDD582C0DA1D0D100B32029 /* NewMessageWindow.xib in Resources */, - 1DDD582D0DA1D0D100B32029 /* MainMenu.xib in Resources */, - 1F122D49118E1DE100E83B77 /* Icon.icns in Resources */, - 1F1C80F916482A250010B409 /* WebKit in Resources */, - 1F132C791666CD9700E4E661 /* TB_SendTemplate.png in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 8D15AC300486D014006FF6A4 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 1FC254A01427DFAD0035D84B /* AccessToken.m in Sources */, - 8D15AC310486D014006FF6A4 /* NewMessageWindow.m in Sources */, - 8D15AC320486D014006FF6A4 /* main.m in Sources */, - 1FFA36D71177D879006C8562 /* Controller.m in Sources */, - 1FFA36D81177D879006C8562 /* ViewDelegate.m in Sources */, - 1F77DB47118C5F1C007C7F1E /* Constants.m in Sources */, - 1F618ECA12DB5E6100E500D9 /* PostModel.m in Sources */, - 1F880B6B165EE0F60022A84D /* NSData+Base64.m in Sources */, - 1F880B6E165FE8890022A84D /* MimeType.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 089C165FFE840EACC02AAC07 /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - 089C1660FE840EACC02AAC07 /* English */, - ); - name = InfoPlist.strings; - sourceTree = ""; - }; - 1DDD58280DA1D0D100B32029 /* NewMessageWindow.xib */ = { - isa = PBXVariantGroup; - children = ( - 1DDD58290DA1D0D100B32029 /* English */, - ); - name = NewMessageWindow.xib; - sourceTree = ""; - }; - 1DDD582A0DA1D0D100B32029 /* MainMenu.xib */ = { - isa = PBXVariantGroup; - children = ( - 1DDD582B0DA1D0D100B32029 /* English */, - ); - name = MainMenu.xib; - sourceTree = ""; - }; - 2A37F4B9FDCFA73011CA2CEA /* Credits.rtf */ = { - isa = PBXVariantGroup; - children = ( - 2A37F4BAFDCFA73011CA2CEA /* English */, - ); - name = Credits.rtf; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - C05733C808A9546B00998B17 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COMBINE_HIDPI_IMAGES = YES; - COPY_PHASE_STRIP = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)\"", - ); - GCC_DYNAMIC_NO_PIC = NO; - GCC_MODEL_TUNING = G5; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = Bungloo_Prefix.pch; - INFOPLIST_FILE = "Bungloo-Info.plist"; - INSTALL_PATH = "$(HOME)/Applications"; - ONLY_ACTIVE_ARCH = NO; - PRODUCT_NAME = Bungloo; - SDKROOT = ""; - }; - name = Debug; - }; - C05733C908A9546B00998B17 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COMBINE_HIDPI_IMAGES = YES; - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)\"", - ); - GCC_MODEL_TUNING = G5; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = Bungloo_Prefix.pch; - INFOPLIST_FILE = "Bungloo-Info.plist"; - INSTALL_PATH = "$(HOME)/Applications"; - ONLY_ACTIVE_ARCH = NO; - PRODUCT_NAME = Bungloo; - SDKROOT = ""; - }; - name = Release; - }; - C05733CC08A9546B00998B17 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.5; - ONLY_ACTIVE_ARCH = YES; - PRODUCT_NAME = Bungloo; - SDKROOT = ""; - }; - name = Debug; - }; - C05733CD08A9546B00998B17 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.5; - ONLY_ACTIVE_ARCH = NO; - PRODUCT_NAME = Bungloo; - SDKROOT = ""; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - C05733C708A9546B00998B17 /* Build configuration list for PBXNativeTarget "Bungloo" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C05733C808A9546B00998B17 /* Debug */, - C05733C908A9546B00998B17 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; - C05733CB08A9546B00998B17 /* Build configuration list for PBXProject "Bungloo" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C05733CC08A9546B00998B17 /* Debug */, - C05733CD08A9546B00998B17 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; -/* End XCConfigurationList section */ - }; - rootObject = 2A37F4A9FDCFA73011CA2CEA /* Project object */; -} diff --git a/Mac/Bungloo.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Mac/Bungloo.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 0fa3cc5..0000000 --- a/Mac/Bungloo.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/Mac/Bungloo.xcodeproj/project.xcworkspace/xcuserdata/jeena.xcuserdatad/WorkspaceSettings.xcsettings b/Mac/Bungloo.xcodeproj/project.xcworkspace/xcuserdata/jeena.xcuserdatad/WorkspaceSettings.xcsettings deleted file mode 100644 index 659c876..0000000 --- a/Mac/Bungloo.xcodeproj/project.xcworkspace/xcuserdata/jeena.xcuserdatad/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,10 +0,0 @@ - - - - - HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges - - SnapshotAutomaticallyBeforeSignificantChanges - - - diff --git a/Mac/Bungloo.xcodeproj/xcuserdata/jeena.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist b/Mac/Bungloo.xcodeproj/xcuserdata/jeena.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist deleted file mode 100644 index a5446f1..0000000 --- a/Mac/Bungloo.xcodeproj/xcuserdata/jeena.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - diff --git a/Mac/Bungloo.xcodeproj/xcuserdata/jeena.xcuserdatad/xcschemes/Bungloo.xcscheme b/Mac/Bungloo.xcodeproj/xcuserdata/jeena.xcuserdatad/xcschemes/Bungloo.xcscheme deleted file mode 100644 index c8d35d9..0000000 --- a/Mac/Bungloo.xcodeproj/xcuserdata/jeena.xcuserdatad/xcschemes/Bungloo.xcscheme +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Mac/Bungloo.xcodeproj/xcuserdata/jeena.xcuserdatad/xcschemes/xcschememanagement.plist b/Mac/Bungloo.xcodeproj/xcuserdata/jeena.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index 20fd17d..0000000 --- a/Mac/Bungloo.xcodeproj/xcuserdata/jeena.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - SchemeUserState - - Bungloo.xcscheme - - orderHint - 1 - - - SuppressBuildableAutocreation - - 8D15AC270486D014006FF6A4 - - primary - - - - - diff --git a/Mac/Bungloo_Prefix.pch b/Mac/Bungloo_Prefix.pch deleted file mode 100644 index f7b0d9b..0000000 --- a/Mac/Bungloo_Prefix.pch +++ /dev/null @@ -1,7 +0,0 @@ -// -// Prefix header for all source files of the 'Tentia' target in the 'Tentia' project -// - -#ifdef __OBJC__ -#import -#endif diff --git a/Mac/Constants.h b/Mac/Constants.h deleted file mode 100644 index 11a32e2..0000000 --- a/Mac/Constants.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// Constants.h -// bungloo -// -// Created by Jeena on 01.05.10. -// Licence: BSD (see attached LICENCE.txt file). -// - -#import -#import - - -@interface Constants : NSObject { - -} - -#define APP_NAME @"Bungloo" -#define MESSAGE_MAX_LENGTH 256 - -+ (NSString *)stringFromVirtualKeyCode:(NSInteger)code; - -@end diff --git a/Mac/Constants.m b/Mac/Constants.m deleted file mode 100644 index d70242a..0000000 --- a/Mac/Constants.m +++ /dev/null @@ -1,220 +0,0 @@ -// -// Constants.m -// bungloo -// -// Created by Jeena on 01.05.10. -// Licence: BSD (see attached LICENCE.txt file). -// - -#import "Constants.h" - - -@implementation Constants - -+ (NSString *)stringFromVirtualKeyCode:(NSInteger)code { - NSString *string = nil; - switch (code) { - case kVK_ANSI_A: - string = @"A"; - break; - case kVK_ANSI_S: - string = @"S"; - break; - case kVK_ANSI_D: - string = @"D"; - break; - case kVK_ANSI_F: - string = @"F"; - break; - case kVK_ANSI_H: - string = @"H"; - break; - case kVK_ANSI_G: - string = @"G"; - break; - case kVK_ANSI_Z: - string = @"Z"; - break; - case kVK_ANSI_X: - string = @"X"; - break; - case kVK_ANSI_C: - string = @"C"; - break; - case kVK_ANSI_V: - string = @"V"; - break; - case kVK_ANSI_B: - string = @"B"; - break; - case kVK_ANSI_Q: - string = @"Q"; - break; - case kVK_ANSI_W: - string = @"W"; - break; - case kVK_ANSI_E: - string = @"E"; - break; - case kVK_ANSI_R: - string = @"R"; - break; - case kVK_ANSI_Y: - string = @"Y"; - break; - case kVK_ANSI_T: - string = @"T"; - break; - case kVK_ANSI_1: - string = @"1"; - break; - case kVK_ANSI_2: - string = @"2"; - break; - case kVK_ANSI_3: - string = @"3"; - break; - case kVK_ANSI_4: - string = @"4"; - break; - case kVK_ANSI_6: - string = @"6"; - break; - case kVK_ANSI_5: - string = @"5"; - break; - case kVK_ANSI_Equal: - string = @"="; - break; - case kVK_ANSI_9: - string = @"9"; - break; - case kVK_ANSI_7: - string = @"7"; - break; - case kVK_ANSI_Minus: - string = @"-"; - break; - case kVK_ANSI_8: - string = @"8"; - break; - case kVK_ANSI_0: - string = @"0"; - break; - case kVK_ANSI_RightBracket: - string = @")"; - break; - case kVK_ANSI_O: - string = @"0"; - break; - case kVK_ANSI_U: - string = @"U"; - break; - case kVK_ANSI_LeftBracket: - string = @"("; - break; - case kVK_ANSI_I: - string = @"I"; - break; - case kVK_ANSI_P: - string = @"P"; - break; - case kVK_ANSI_L: - string = @"L"; - break; - case kVK_ANSI_J: - string = @"J"; - break; - case kVK_ANSI_Quote: - string = @"\""; - break; - case kVK_ANSI_K: - string = @"K"; - break; - case kVK_ANSI_Semicolon: - string = @";"; - break; - case kVK_ANSI_Backslash: - string = @"\\"; - break; - case kVK_ANSI_Comma: - string = @","; - break; - case kVK_ANSI_Slash: - string = @"/"; - break; - case kVK_ANSI_N: - string = @"N"; - break; - case kVK_ANSI_M: - string = @"M"; - break; - case kVK_ANSI_Period: - string = @"."; - break; - case kVK_ANSI_Grave: - string = @"`"; - break; - case kVK_ANSI_KeypadDecimal: - string = @"."; - break; - case kVK_ANSI_KeypadMultiply: - string = @"*"; - break; - case kVK_ANSI_KeypadPlus: - string = @"+"; - break; - case kVK_ANSI_KeypadClear: - string = @""; - break; - case kVK_ANSI_KeypadDivide: - string = @"/"; - break; - case kVK_ANSI_KeypadEnter: - string = @"⎆"; - break; - case kVK_ANSI_KeypadMinus: - string = @"-"; - break; - case kVK_ANSI_KeypadEquals: - string = @"="; - break; - case kVK_ANSI_Keypad0: - string = @"0"; - break; - case kVK_ANSI_Keypad1: - string = @"1"; - break; - case kVK_ANSI_Keypad2: - string = @"2"; - break; - case kVK_ANSI_Keypad3: - string = @"3"; - break; - case kVK_ANSI_Keypad4: - string = @"4"; - break; - case kVK_ANSI_Keypad5: - string = @"5"; - break; - case kVK_ANSI_Keypad6: - string = @"6"; - break; - case kVK_ANSI_Keypad7: - string = @"7"; - break; - case kVK_ANSI_Keypad8: - string = @"8"; - break; - case kVK_ANSI_Keypad9: - string = @"9"; - break; - default: - string = nil; - break; - } - - return string; -} - -@end diff --git a/Mac/Controller.h b/Mac/Controller.h deleted file mode 100644 index 08fc2e2..0000000 --- a/Mac/Controller.h +++ /dev/null @@ -1,95 +0,0 @@ -// -// Controller.h -// bungloo -// -// Created by Jeena on 15.04.10. -// Licence: BSD (see attached LICENCE.txt file). -// - -#import -#import -#import "ViewDelegate.h" -#import -#import "Constants.h" -#import "AccessToken.h" -#import -#import "NSData+Base64.h" -#import "MimeType.h" - -@interface Controller : NSObject { - IBOutlet WebView *timelineView; - IBOutlet NSWindow *timelineViewWindow; - IBOutlet WebView *mentionsView; - IBOutlet NSWindow *mentionsViewWindow; - IBOutlet WebView *conversationView; - IBOutlet NSWindow *conversationViewWindow; - WebView *profileView; - NSWindow *profileViewWindow; - NSPanel *openProfileWindow; - NSWindow *loginViewWindow; - NSTextField *loginEntityTextField; - NSProgressIndicator *loginActivityIndicator; - IBOutlet NSMenuItem *globalHotkeyMenuItem; - IBOutlet NSImageView *logoLayer; - ViewDelegate *viewDelegate; - WebView *oauthView; - AccessToken *accessToken; - NSTextField *showProfileTextField; - -} - -@property (assign) IBOutlet WebView *timelineView; -@property (assign) IBOutlet NSWindow *timelineViewWindow; -@property (assign) IBOutlet WebView *mentionsView; -@property (assign) IBOutlet NSWindow *mentionsViewWindow; -@property (assign) IBOutlet WebView *conversationView; -@property (assign) IBOutlet NSWindow *conversationViewWindow; -@property (assign) IBOutlet WebView *profileView; -@property (assign) IBOutlet NSWindow *profileViewWindow; -@property (assign) IBOutlet NSPanel *openProfileWindow; - -@property (assign) IBOutlet NSWindow *loginViewWindow; -@property (assign) IBOutlet NSTextField *loginEntityTextField; -@property (assign) IBOutlet NSProgressIndicator *loginActivityIndicator; -@property (retain, nonatomic) IBOutlet NSMenuItem *globalHotkeyMenuItem; -@property (retain, nonatomic) IBOutlet NSImageView *logoLayer; -@property (retain, nonatomic) IBOutlet ViewDelegate *viewDelegate; -@property (retain, nonatomic) WebView *oauthView; -@property (retain, nonatomic) AccessToken *accessToken; -@property (assign) IBOutlet NSTextField *showProfileTextField; - - -- (void)initOauth; -- (void)authentificationSucceded:(id)sender; -- (void)authentificationDidNotSucceed:(NSString *)errorMessage; -- (void)initWebViews; -- (void)initHotKeys; -- (void)alertTitle:(NSString *)title withMessage:(NSString *)message; -- (void)openNewMessageWindowInReplyTo:(NSString *)userName statusId:(NSString *)statusId withString:(NSString *)string isPrivate:(BOOL)isPrivate; -- (NSString *)pluginURL; -- (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent; -- (void)unreadMentions:(int)count; -- (void)notificateUserAboutMention:(NSString *)text fromName:(NSString *)name withPostId:(NSString *)postId andEntity:(NSString *)entity; - -- (void)openURL:(NSString *)url; -- (IBAction)showProfile:(id)sender; -- (void)notificateViewsAboutDeletedPostWithId:(NSString *)postId byEntity:(NSString*)entity; - -- (void)setString:(NSString *)string forKey:(NSString *)aKey; -- (void)setSecret:(NSString *)string; -- (NSString *)secret; -- (NSString *)stringForKey:(NSString *)aKey; -- (void)loggedIn; - -- (void)stringFromFile:(NSString *)file url: (NSURL **) url content: (NSString **) content; - -- (IBAction)login:(id)sender; -- (IBAction)logout:(id)sender; - -- (IBAction)showConversationForPostId:(NSString *)postId andEntity:(NSString *)entity; - -- (IBAction)clearCache:(id)sender; - -OSStatus handler(EventHandlerCallRef nextHandler, EventRef theEvent, void* userData); - -@end diff --git a/Mac/Controller.m b/Mac/Controller.m deleted file mode 100644 index ed36384..0000000 --- a/Mac/Controller.m +++ /dev/null @@ -1,538 +0,0 @@ -// -// Controller.m -// bungloo -// -// Created by Jeena on 15.04.10. -// Licence: BSD (see attached LICENCE.txt file). -// - -#import "Controller.h" -#import "NewMessageWindow.h" -#import "PostModel.h" -#import "NSData+Base64.h" - -@implementation Controller -@synthesize showProfileTextField; -@synthesize openProfileWindow; -@synthesize loginViewWindow; -@synthesize loginEntityTextField; -@synthesize loginActivityIndicator; -@synthesize timelineView, timelineViewWindow, mentionsView, mentionsViewWindow, conversationView, conversationViewWindow, profileView, profileViewWindow; -@synthesize globalHotkeyMenuItem, viewDelegate; -@synthesize logoLayer; -@synthesize oauthView, accessToken; - -- (void)awakeFromNib -{ - [timelineViewWindow setExcludedFromWindowsMenu:YES]; - [mentionsViewWindow setExcludedFromWindowsMenu:YES]; - - [self initHotKeys]; - - [GrowlApplicationBridge setGrowlDelegate:self]; - - NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; - [nc addObserver:self - selector:@selector(openNewMessageWindow:) - name:@"openNewMessageWindow" - object:nil]; - [nc addObserver:self - selector:@selector(sendPost:) - name:@"sendPost" - object:nil]; - [nc addObserver:self - selector:@selector(authentificationSucceded:) - name:@"authentificationSucceded" - object:nil]; - [nc addObserver:self - selector:@selector(getPostUpdates:) - name:@"getPostUpdates" - object:nil]; - - NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager]; - [appleEventManager setEventHandler:self - andSelector:@selector(handleGetURLEvent:withReplyEvent:) - forEventClass:kInternetEventClass - andEventID:kAEGetURL]; - - - viewDelegate = [[ViewDelegate alloc] init]; - accessToken = [[AccessToken alloc] init]; - - BOOL forceLogin = NO; - /* - if (![accessToken stringForKey:@"version-0.6.0-new-login"]) { - [self logout:self]; - forceLogin = YES; - [accessToken setString:nil forKey:@"entity"]; - [accessToken setString:@"yes" forKey:@"version-0.6.0-new-login"]; - }*/ - - if (forceLogin || ![accessToken stringForKey:@"user_access_token"] || ![accessToken secret]) { - [timelineViewWindow performClose:self]; - [mentionsViewWindow performClose:self]; - [self.loginViewWindow makeKeyAndOrderFront:self]; - [self initOauth]; - } else { - [timelineViewWindow makeKeyAndOrderFront:self]; - [self initWebViews]; - } -} - -# pragma mark Init - -- (void)stringFromFile:(NSString *)file url: (NSURL **) url content: (NSString **) content -{ - NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingFormat: @"/WebKit/%@", file]; - *url = [NSURL fileURLWithPath: path]; - *content = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil]; -} - -- (void)initOauth -{ - if (!oauthView) { - NSString *index_string; - NSURL *url; - - [self stringFromFile: @"index.html" url: &url content: &index_string]; - - oauthView = [[WebView alloc] init]; - viewDelegate.oauthView = oauthView; - [[oauthView mainFrame] loadHTMLString:index_string baseURL:url]; - [oauthView setFrameLoadDelegate:viewDelegate]; - [oauthView setPolicyDelegate:viewDelegate]; - [oauthView setUIDelegate:viewDelegate]; - [[oauthView windowScriptObject] setValue:self forKey:@"controller"]; - - } -} - -- (void)initWebViews -{ - - if (viewDelegate.timelineView != timelineView) - { - NSString *index_string; - NSURL *url; - - [self initOauth]; - - [self stringFromFile: @"index.html" url: &url content: &index_string]; - - viewDelegate.timelineView = timelineView; - [[timelineView mainFrame] loadHTMLString:index_string baseURL:url]; - [timelineView setFrameLoadDelegate:viewDelegate]; - [timelineView setPolicyDelegate:viewDelegate]; - [timelineView setUIDelegate:viewDelegate]; - [[timelineView windowScriptObject] setValue:self forKey:@"controller"]; - //WebPreferences* prefs = [timelineView preferences]; - //[prefs _setLocalStorageDatabasePath:localStoragePath]; - //[prefs setLocalStorageEnabled:YES]; - - viewDelegate.mentionsView = mentionsView; - [[mentionsView mainFrame] loadHTMLString:index_string baseURL:url]; - [mentionsView setFrameLoadDelegate:viewDelegate]; - [mentionsView setPolicyDelegate:viewDelegate]; - [mentionsView setUIDelegate:viewDelegate]; - [[mentionsView windowScriptObject] setValue:self forKey:@"controller"]; - //prefs = [mentionsView preferences]; - //[prefs _setLocalStorageDatabasePath:localStoragePath]; - //[prefs setLocalStorageEnabled:YES]; - - viewDelegate.conversationView = conversationView; - [[conversationView mainFrame] loadHTMLString:index_string baseURL:url]; - [conversationView setFrameLoadDelegate:viewDelegate]; - [conversationView setPolicyDelegate:viewDelegate]; - [conversationView setUIDelegate:viewDelegate]; - [[conversationView windowScriptObject] setValue:self forKey:@"controller"]; - //prefs = [conversationView preferences]; - //[prefs _setLocalStorageDatabasePath:localStoragePath]; - //[prefs setLocalStorageEnabled:YES]; - - viewDelegate.profileView = profileView; - [[profileView mainFrame] loadHTMLString:index_string baseURL:url]; - [profileView setFrameLoadDelegate:viewDelegate]; - [profileView setPolicyDelegate:viewDelegate]; - [profileView setUIDelegate:viewDelegate]; - [[profileView windowScriptObject] setValue:self forKey:@"controller"]; - //prefs = [profileView preferences]; - //[prefs _setLocalStorageDatabasePath:localStoragePath]; - //[prefs setLocalStorageEnabled:YES]; - - } - else - { - [timelineView stringByEvaluatingJavaScriptFromString:@"start('timeline')"]; - [mentionsView stringByEvaluatingJavaScriptFromString:@"start('mentions')"]; - [conversationView stringByEvaluatingJavaScriptFromString:@"start('conversation')"]; - [profileView stringByEvaluatingJavaScriptFromString:@"start('profile')"]; - } -} - -- (void)initHotKeys -{ - - NSInteger newPostKey = kVK_ANSI_M; // http://boredzo.org/blog/archives/2007-05-22/virtual-key-codes - NSInteger newPostModifierKey = controlKey + cmdKey + optionKey; // cmdKey 256, shitfKey 512, optionKey 2048, controlKey 4096 - - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - NSInteger defaultsNewPostKey = (NSInteger)[defaults integerForKey:@"newPostKey"]; - - if ([defaults objectForKey:@"newPostKey"] != nil) - { - newPostKey = defaultsNewPostKey; - } - else - { - [defaults setInteger:newPostKey forKey:@"newPostKey"]; - } - - NSInteger defaultsNewPostModifierKey = (NSInteger)[defaults integerForKey:@"newPostModifierKey"]; - if ([defaults objectForKey:@"newPostModifierKey"] != nil) - { - newPostModifierKey = defaultsNewPostModifierKey; - } - else - { - [defaults setInteger:newPostModifierKey forKey:@"newPostModifierKey"]; - } - - [defaults synchronize]; - - NSUInteger cocoaModifiers = 0; - if (newPostModifierKey & shiftKey) cocoaModifiers = cocoaModifiers | NSShiftKeyMask; - if (newPostModifierKey & optionKey) cocoaModifiers = cocoaModifiers | NSAlternateKeyMask; - if (newPostModifierKey & controlKey) cocoaModifiers = cocoaModifiers | NSControlKeyMask; - if (newPostModifierKey & cmdKey) cocoaModifiers = cocoaModifiers | NSCommandKeyMask; - - [globalHotkeyMenuItem setKeyEquivalent:[Constants stringFromVirtualKeyCode:newPostKey]]; - [globalHotkeyMenuItem setKeyEquivalentModifierMask:cocoaModifiers]; - - /* CARBON from http://github.com/Xjs/drama-button/blob/carbon/Drama_ButtonAppDelegate.m */ - - EventTypeSpec eventType; - eventType.eventClass = kEventClassKeyboard; - eventType.eventKind = kEventHotKeyPressed; - - InstallApplicationEventHandler(&handler, 1, &eventType, NULL, NULL); - - EventHotKeyID g_HotKeyID; - g_HotKeyID.id = 1; - - EventHotKeyRef g_HotKeyRef; - - RegisterEventHotKey(newPostKey, newPostModifierKey, g_HotKeyID, GetApplicationEventTarget(), 0, &g_HotKeyRef); - - /* end CARBON */ -} - -- (void)alertTitle:(NSString *)title withMessage:(NSString *)message -{ - NSAlert *alert = [NSAlert alertWithMessageText:title - defaultButton:@"OK" alternateButton:nil otherButton:nil - informativeTextWithFormat:@"%@", message]; - [alert runModal]; -} - -- (void)authentificationSucceded:(id)sender -{ - [loginActivityIndicator stopAnimation:self]; - [self initWebViews]; - [loginViewWindow performClose:self]; -} - -- (void)authentificationDidNotSucceed:(NSString *)errorMessage -{ - [loginActivityIndicator stopAnimation:self]; - [self alertTitle:@"Authenication error" withMessage:errorMessage]; -} - -+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector -{ - return NO; -} - -+ (BOOL)isKeyExcludedFromWebScript:(const char *)name -{ - return NO; -} - -- (void)setString:(NSString *)string forKey:(NSString *)aKey -{ - [self.accessToken setString:string forKey:aKey]; -} - -- (void)setSecret:(NSString *)string -{ - [self.accessToken setSecret:string]; -} -- (NSString *)secret -{ - return [self.accessToken secret]; -} - -- (NSString *)stringForKey:(NSString *)aKey -{ - return [self.accessToken stringForKey:aKey]; -} - - -#pragma mark Notifications - --(BOOL)applicationShouldOpenUntitledFile:(NSApplication *)theApplication -{ - return NO; -} - -- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag -{ - [timelineViewWindow makeKeyAndOrderFront:self]; - return NO; -} - -- (IBAction)openNewMessageWindow:(id)sender -{ - [NSApp activateIgnoringOtherApps:YES]; - [[NSDocumentController sharedDocumentController] openUntitledDocumentAndDisplay:YES error:nil]; -} - -- (void)openNewMessageWindowInReplyTo:(NSString *)userName statusId:(NSString *)statusId withString:(NSString *)string isPrivate:(BOOL)isPrivate -{ - [NSApp activateIgnoringOtherApps:YES]; - NewMessageWindow *newMessage = (NewMessageWindow *)[[NSDocumentController sharedDocumentController] openUntitledDocumentAndDisplay:YES error:nil]; - [newMessage inReplyTo:userName statusId:statusId withString:string]; - [newMessage setIsPrivate:isPrivate]; -} - -- (void)openNewMessageWindowWithString:(NSString *)aString -{ - [NSApp activateIgnoringOtherApps:YES]; - - NSRange range = [aString rangeOfString:@"oauthtoken"]; - - if (range.length > 0) - { - [oauthView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"bungloo_instance.requestAccessToken('%@')", aString]]; - } - else - { - NewMessageWindow *newPost = (NewMessageWindow *)[[NSDocumentController sharedDocumentController] openUntitledDocumentAndDisplay:YES error:nil]; - [newPost withString:aString]; - } -} - -- (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent -{ - NSString *text = [[[event paramDescriptorForKeyword:keyDirectObject] stringValue] substringFromIndex:8]; - [self openNewMessageWindowWithString:[text stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; -} - -- (IBAction)sendPost:(id)sender -{ - PostModel *post = (PostModel *)[sender object]; - NSString *text = [[post.text stringByReplacingOccurrencesOfString:@"\\" withString:@"\\\\"] stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]; - text = [text stringByReplacingOccurrencesOfString:@"\n" withString:@"\\n"]; - - NSString *locationObject = @"null"; - if (post.location) { - locationObject = [NSString stringWithFormat:@"[%f, %f]", post.location.coordinate.latitude, post.location.coordinate.longitude]; - } - - NSString *imageFilePath = @"null"; - if (post.imageFilePath) { - NSError *error; - NSString *mimeType = [MimeType mimeTypeForFileAtPath:post.imageFilePath error:&error]; - NSData *data = [[NSData alloc] initWithContentsOfFile:post.imageFilePath]; - NSString *base64 = [data base64Encoding_xcd]; - [data release]; - imageFilePath = [NSString stringWithFormat:@"\"data:%@;base64,%@\"", mimeType, base64]; - } - - NSString *isPrivate = @"false"; - if (post.isPrivate) { - isPrivate = @"true"; - } - - NSString *func = [NSString stringWithFormat:@"bungloo_instance.sendNewMessage(\"%@\", \"%@\", \"%@\", %@, %@, %@)", - text, - post.inReplyTostatusId, - post.inReplyToEntity, - locationObject, - imageFilePath, - isPrivate]; - - [timelineView stringByEvaluatingJavaScriptFromString:func]; -} - -- (NSString *)pluginURL -{ - NSFileManager *fileManager = [NSFileManager defaultManager]; - NSString *pathToPlugin = [@"~/Library/Application Support/Bungloo/Plugin.js" stringByExpandingTildeInPath]; - - if([fileManager fileExistsAtPath:pathToPlugin]) - { - return [NSString stringWithFormat:@"%@", [NSURL fileURLWithPath:pathToPlugin]]; - } - return nil; -} - -- (void)unreadMentions:(int)count -{ - if (![mentionsViewWindow isVisible] && count > 0) - { - [timelineViewWindow setTitle:[NSString stringWithFormat:@"Bungloo (^%i)", count]]; - [[[NSApplication sharedApplication] dockTile] setBadgeLabel:[NSString stringWithFormat:@"%i", count]]; - } - else - { - [timelineViewWindow setTitle:[NSString stringWithFormat:@"Bungloo"]]; - [[[NSApplication sharedApplication] dockTile] setBadgeLabel:nil]; - [mentionsView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.unread_mentions = 0;"]; - } -} - -- (void)notificateUserAboutMention:(NSString *)text fromName:(NSString *)name withPostId:(NSString *)postId andEntity:(NSString *)entity -{ - [GrowlApplicationBridge - notifyWithTitle:[NSString stringWithFormat:@"Mentioned by %@ on Tent", name] - description:text - notificationName:@"Mention" - iconData:nil - priority:0 - isSticky:NO - clickContext:[NSDictionary dictionaryWithObjectsAndKeys: - entity, @"entity", - postId, @"postId", nil]]; -} - -- (void)openURL:(NSString *)url -{ - [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:url]]; -} - -- (IBAction)showProfile:(id)sender -{ - NSString *entity = [self.showProfileTextField stringValue]; - if ([entity rangeOfString:@"."].location != NSNotFound && ([entity hasPrefix:@"http://"] || [entity hasPrefix:@"https://"])) { - NSString *func = [NSString stringWithFormat:@"bungloo_instance.showProfileForEntity('%@')", entity]; - [profileView stringByEvaluatingJavaScriptFromString:func]; - [profileViewWindow makeKeyAndOrderFront:self]; - [openProfileWindow performClose:self]; - } -} - -- (void)notificateViewsAboutDeletedPostWithId:(NSString *)postId byEntity:(NSString*)entity -{ - NSString *fun = [NSString stringWithFormat:@"bungloo_instance.postDeleted('%@', '%@')", postId, entity]; - [timelineView stringByEvaluatingJavaScriptFromString:fun]; - [mentionsView stringByEvaluatingJavaScriptFromString:fun]; - [conversationView stringByEvaluatingJavaScriptFromString:fun]; - [profileView stringByEvaluatingJavaScriptFromString:fun]; -} - - -/* -- (void)storeAccessToken:(NSString *)_accessToken secret:(NSString *)secret userId:(NSString *)userId andScreenName:(NSString *)screenName -{ - self.accessToken.accessToken = _accessToken; - self.accessToken.secret = secret; - self.accessToken.userId = userId; - self.accessToken.screenName = screenName; - [timelineViewWindow makeKeyAndOrderFront:self]; - - [[NSNotificationCenter defaultCenter] postNotificationName:@"authentificationSucceded" object:nil]; -}*/ - -- (void)loggedIn -{ - [loginActivityIndicator stopAnimation:self]; - [self initWebViews]; - [loginViewWindow performClose:self]; - [timelineViewWindow makeKeyAndOrderFront:self]; -} - -- (IBAction)login:(id)sender -{ - if ([[loginEntityTextField stringValue] length] > 0) { - [[loginEntityTextField window] makeFirstResponder:nil]; - [loginActivityIndicator startAnimation:self]; - [oauthView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.authenticate();"]; - } -} - -- (IBAction)logout:(id)sender -{ - [oauthView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.logout();"]; - - [timelineViewWindow performClose:self]; - [mentionsViewWindow performClose:self]; - [conversationViewWindow performClose:self]; - [profileViewWindow performClose:self]; - [self.loginViewWindow makeKeyAndOrderFront:self]; - - [timelineView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.logout();"]; - [mentionsView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.logout();"]; -} - -// Mentions window has been visible -- (void)windowDidBecomeKey:(NSNotification *)notification -{ - if ([notification object] == mentionsViewWindow) - { - //[self unreadMentions:0]; - [mentionsView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.setAllMentionsRead();"]; - } -} - -- (void)getPostUpdates:(id)sender -{ - [timelineView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.getNewData(true)"]; - [mentionsView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.getNewData(true)"]; -} - -- (IBAction)showConversationForPostId:(NSString *)postId andEntity:(NSString *)entity -{ - NSString *js = [NSString stringWithFormat:@"bungloo_instance.showStatus('%@', '%@');", postId, entity]; - [conversationView stringByEvaluatingJavaScriptFromString:js]; - [conversationViewWindow makeKeyAndOrderFront:self]; - [[NSApplication sharedApplication] activateIgnoringOtherApps:YES]; -} - -- (IBAction)clearCache:(id)sender -{ - [timelineView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.cache.clear()"]; -} - -- (IBAction)showProfileForEntity:(NSString *)entity -{ - NSString *js = [NSString stringWithFormat:@"bungloo_instance.showProfileForEntity('%@');", entity]; - [profileView stringByEvaluatingJavaScriptFromString:js]; - [profileViewWindow makeKeyAndOrderFront:self]; -} - -- (void)growlNotificationWasClicked:(id)clickContext -{ - NSDictionary *userInfo = (NSDictionary *)clickContext; - NSString *postId = [userInfo objectForKey:@"postId"]; - NSString *entity = [userInfo objectForKey:@"entity"]; - - [self showConversationForPostId:postId andEntity:entity]; - - NSString *js = [NSString stringWithFormat:@"bungloo_instance.mentionRead('%@', '%@');", postId, entity]; - [mentionsView stringByEvaluatingJavaScriptFromString:js]; -} - -- (NSString *) applicationNameForGrowl -{ - return @"Bungloo"; -} - -/* CARBON */ - -OSStatus handler(EventHandlerCallRef nextHandler, EventRef theEvent, void* userData) -{ - [[NSNotificationCenter defaultCenter] postNotificationName:@"openNewMessageWindow" object:nil]; - return noErr; -} - -@end diff --git a/Mac/English.lproj/Credits.rtf b/Mac/English.lproj/Credits.rtf deleted file mode 100644 index 2ee605e..0000000 --- a/Mac/English.lproj/Credits.rtf +++ /dev/null @@ -1,30 +0,0 @@ -{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 -{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\viewkind0 -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720 - -\f0\b\fs24 \cf0 Engineering: -\b0 \ - Jeena Paradies\ -\ - -\b Testing: -\b0 \ - All the early adopters on Tent\ -\ - -\b Documentation: -\b0 \ - http://github.com/jeena/bungloo/wiki\ -\ - -\b With special thanks to: -\b0 \ - Mom\ -\ - -\b Icon by: -\b0 \ - http://www.fasticon.com\ -} \ No newline at end of file diff --git a/Mac/English.lproj/InfoPlist.strings b/Mac/English.lproj/InfoPlist.strings deleted file mode 100644 index 477b28f..0000000 --- a/Mac/English.lproj/InfoPlist.strings +++ /dev/null @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/Mac/English.lproj/MainMenu.xib b/Mac/English.lproj/MainMenu.xib deleted file mode 100644 index 5a0bacb..0000000 --- a/Mac/English.lproj/MainMenu.xib +++ /dev/null @@ -1,3360 +0,0 @@ - - - - 1080 - 12C60 - 3084 - 1187.34 - 625.00 - - YES - - YES - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.WebKitIBPlugin - - - YES - 3084 - 2053 - - - - YES - NSButton - NSButtonCell - NSCustomObject - NSImageCell - NSImageView - NSMenu - NSMenuItem - NSProgressIndicator - NSTextField - NSTextFieldCell - NSUserDefaultsController - NSView - NSWindowTemplate - WebView - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.WebKitIBPlugin - - - PluginDependencyRecalculationVersion - - - - YES - - NSApplication - - - FirstResponder - - - NSApplication - - - AMainMenu - - YES - - - Bungloo - - 1048576 - 2147483647 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - submenuAction: - - Bungloo - - YES - - - About Bungloo - - 2147483647 - - - - - - Check for Updates... - - 2147483647 - - - - - - Preferences... - , - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Services - - 1048576 - 2147483647 - - - submenuAction: - - Services - - YES - - _NSServicesMenu - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Hide Bungloo - h - 1048576 - 2147483647 - - - - - - Hide Others - h - 1572864 - 2147483647 - - - - - - Show All - - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Quit Bungloo - q - 1048576 - 2147483647 - - - - - _NSAppleMenu - - - - - File - - 1048576 - 2147483647 - - - submenuAction: - - File - - YES - - - New Post - n - 1048576 - 2147483647 - - - - - - Global New Post Key - t - 1835008 - 2147483647 - - - - - - Open Profile ... - u - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Close - w - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Logout - - 2147483647 - - - - - - - - - Edit - - 1048576 - 2147483647 - - - submenuAction: - - Edit - - YES - - - Undo - z - 1048576 - 2147483647 - - - - - - Redo - Z - 1179648 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Cut - x - 1048576 - 2147483647 - - - - - - Copy - c - 1048576 - 2147483647 - - - - - - Paste - v - 1048576 - 2147483647 - - - - - - Paste and Match Style - V - 1572864 - 2147483647 - - - - - - Delete - - 1048576 - 2147483647 - - - - - - Select All - a - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Find - - 1048576 - 2147483647 - - - submenuAction: - - Find - - YES - - - Find… - f - 1048576 - 2147483647 - - - 1 - - - - Find Next - g - 1048576 - 2147483647 - - - 2 - - - - Find Previous - G - 1179648 - 2147483647 - - - 3 - - - - Use Selection for Find - e - 1048576 - 2147483647 - - - 7 - - - - Jump to Selection - j - 1048576 - 2147483647 - - - - - - - - - Spelling and Grammar - - 1048576 - 2147483647 - - - submenuAction: - - Spelling and Grammar - - YES - - - Show Spelling and Grammar - : - 1048576 - 2147483647 - - - - - - Check Document Now - ; - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Check Spelling While Typing - - 1048576 - 2147483647 - - - - - - Check Grammar With Spelling - - 1048576 - 2147483647 - - - - - - Correct Spelling Automatically - - 2147483647 - - - - - - - - - Substitutions - - 1048576 - 2147483647 - - - submenuAction: - - Substitutions - - YES - - - Show Substitutions - - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Smart Copy/Paste - f - 1048576 - 2147483647 - - - 1 - - - - Smart Quotes - g - 1048576 - 2147483647 - - - 2 - - - - Smart Dashes - - 2147483647 - - - - - - Smart Links - G - 1179648 - 2147483647 - - - 3 - - - - Text Replacement - - 2147483647 - - - - - - - - - Transformations - - 2147483647 - - - submenuAction: - - Transformations - - YES - - - Make Upper Case - - 2147483647 - - - - - - Make Lower Case - - 2147483647 - - - - - - Capitalize - - 2147483647 - - - - - - - - - Speech - - 1048576 - 2147483647 - - - submenuAction: - - Speech - - YES - - - Start Speaking - - 1048576 - 2147483647 - - - - - - Stop Speaking - - 1048576 - 2147483647 - - - - - - - - - - - - View - - 1048576 - 2147483647 - - - submenuAction: - - View - - YES - - - Show Toolbar - t - 1572864 - 2147483647 - - - - - - Customize Toolbar… - - 1048576 - 2147483647 - - - - - - - - - Window - - 2147483647 - - - submenuAction: - - Window - - YES - - - Minimize - m - 1048576 - 2147483647 - - - - - - Zoom - - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Timeline - 1 - 1048576 - 2147483647 - - - - - - Mentions - 2 - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Bring All to Front - - 2147483647 - - - - - _NSWindowsMenu - - - - - Help - - 2147483647 - - - submenuAction: - - Help - - YES - - - Bungloo - ? - 1048576 - 2147483647 - - - - - _NSHelpMenu - - - - _NSMainMenu - - - NSFontManager - - - Controller - - - 15 - 2 - {{712, 280}, {397, 581}} - 1685586944 - Bungloo - NSWindow - - - - - 256 - - YES - - - 274 - - YES - - YES - Apple HTML pasteboard type - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple URL pasteboard type - Apple Web Archive pasteboard type - NSColor pasteboard type - NSFilenamesPboardType - NSStringPboardType - NeXT RTFD pasteboard type - NeXT Rich Text Format v1.0 pasteboard type - NeXT TIFF v4.0 pasteboard type - WebURLsWithTitlesPboardType - public.png - public.url - public.url-name - - - {397, 581} - - - - - - - 13 - - YES - - YES - 13WebKitJavaEnabled - 13WebKitJavaScriptCanOpenWindowsAutomatically - 13WebKitPluginsEnabled - - - YES - - - - - - - NO - YES - - - {397, 581} - - - - - {{0, 0}, {1920, 1178}} - {10000000000000, 10000000000000} - bungloo - YES - - - SUUpdater - - - 15 - 2 - {{1077, 328}, {376, 581}} - 1685586944 - Mentions - NSWindow - - - - - 256 - - YES - - - 274 - - YES - - YES - Apple HTML pasteboard type - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple URL pasteboard type - Apple Web Archive pasteboard type - NSColor pasteboard type - NSFilenamesPboardType - NSStringPboardType - NeXT RTFD pasteboard type - NeXT Rich Text Format v1.0 pasteboard type - NeXT TIFF v4.0 pasteboard type - WebURLsWithTitlesPboardType - public.png - public.url - public.url-name - - - {376, 581} - - - - - - - 12 - - YES - - YES - 12WebKitJavaEnabled - 12WebKitJavaScriptCanOpenWindowsAutomatically - 12WebKitPluginsEnabled - - - YES - - - - - - - NO - YES - - - {376, 581} - - - - - {{0, 0}, {1920, 1178}} - {10000000000000, 10000000000000} - mentions - YES - - - 15 - 2 - {{1292, 328}, {376, 581}} - 1685586944 - Conversation - NSWindow - - - - - 256 - - YES - - - 274 - - YES - - YES - Apple HTML pasteboard type - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple URL pasteboard type - Apple Web Archive pasteboard type - NSColor pasteboard type - NSFilenamesPboardType - NSStringPboardType - NeXT RTFD pasteboard type - NeXT Rich Text Format v1.0 pasteboard type - NeXT TIFF v4.0 pasteboard type - WebURLsWithTitlesPboardType - public.png - public.url - public.url-name - - - {376, 581} - - - - - - - NO - YES - - - {376, 581} - - - - - {{0, 0}, {1920, 1178}} - {10000000000000, 10000000000000} - conversation - YES - - - 15 - 2 - {{1292, 328}, {376, 581}} - 1685586944 - Profile - NSWindow - - - - - 256 - - YES - - - 274 - - YES - - YES - Apple HTML pasteboard type - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple URL pasteboard type - Apple Web Archive pasteboard type - NSColor pasteboard type - NSFilenamesPboardType - NSStringPboardType - NeXT RTFD pasteboard type - NeXT Rich Text Format v1.0 pasteboard type - NeXT TIFF v4.0 pasteboard type - WebURLsWithTitlesPboardType - public.png - public.url - public.url-name - - - {376, 581} - - - - - - - NO - YES - - - {376, 581} - - - - - {{0, 0}, {1920, 1178}} - {10000000000000, 10000000000000} - profile - YES - - - 7 - 2 - {{641, 502}, {480, 186}} - 1685586944 - Preferences - NSWindow - - - - - 256 - - YES - - - 268 - - YES - - YES - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple PNG pasteboard type - NSFilenamesPboardType - NeXT Encapsulated PostScript v1.2 pasteboard type - NeXT TIFF v4.0 pasteboard type - - - {{20, 20}, {146, 146}} - - - YES - - 0 - 33554432 - - NSImage - Icon - - 0 - 0 - 0 - YES - - NO - YES - - - - 268 - {{194, 82}, {266, 22}} - - - _NS:9 - YES - - -1804599231 - 272630784 - - - LucidaGrande - 13 - 1044 - - https://example.tent.is - _NS:9 - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - 3 - MAA - - - - YES - NSAllRomanInputSourcesLocaleIdentifier - - - NO - - - - 268 - {{191, 112}, {163, 17}} - - - _NS:1535 - YES - - 68157504 - 272630784 - Add your entity to log in: - - _NS:1535 - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - - - NO - - - - 268 - {{391, 46}, {75, 32}} - - _NS:9 - YES - - 67108864 - 134217728 - Login - - _NS:9 - - -2038284288 - 129 - - - 200 - 25 - - NO - - - - 268 - {{373, 55}, {16, 16}} - - - _NS:945 - 28938 - 100 - - - {480, 186} - - _NS:20 - - {{0, 0}, {1920, 1178}} - {10000000000000, 10000000000000} - preferences - YES - - - YES - - - 19 - 2 - {{559, 746}, {373, 116}} - -461896704 - Open Profile ... - NSPanel - - - - - 256 - - YES - - - 268 - {{17, 79}, {192, 17}} - - - _NS:1535 - YES - - 68157504 - 272630784 - Open the profile of the entity: - - _NS:1535 - - - - - NO - - - - 268 - {{20, 49}, {333, 22}} - - - _NS:9 - YES - - -1804599231 - 272630784 - - - https://example.tent.is - _NS:9 - - YES - - - - NO - - - - 268 - {{285, 13}, {74, 32}} - - _NS:9 - YES - - 67108864 - 134217728 - Open - - _NS:9 - - -2038284288 - 129 - - - 200 - 25 - - NO - - - {373, 116} - - _NS:21 - - {{0, 0}, {1920, 1178}} - {10000000000000, 10000000000000} - NO - - - - - YES - - - terminate: - - - - 448 - - - - orderFrontStandardAboutPanel: - - - - 142 - - - - delegate - - - - 564 - - - - performClose: - - - - 193 - - - - toggleContinuousSpellChecking: - - - - 222 - - - - undo: - - - - 223 - - - - copy: - - - - 224 - - - - checkSpelling: - - - - 225 - - - - paste: - - - - 226 - - - - stopSpeaking: - - - - 227 - - - - cut: - - - - 228 - - - - showGuessPanel: - - - - 230 - - - - redo: - - - - 231 - - - - selectAll: - - - - 232 - - - - startSpeaking: - - - - 233 - - - - delete: - - - - 235 - - - - performFindPanelAction: - - - - 241 - - - - centerSelectionInVisibleArea: - - - - 245 - - - - toggleGrammarChecking: - - - - 347 - - - - toggleSmartInsertDelete: - - - - 355 - - - - toggleAutomaticQuoteSubstitution: - - - - 356 - - - - toggleAutomaticLinkDetection: - - - - 357 - - - - runToolbarCustomizationPalette: - - - - 365 - - - - toggleToolbarShown: - - - - 366 - - - - hide: - - - - 367 - - - - hideOtherApplications: - - - - 368 - - - - unhideAllApplications: - - - - 370 - - - - newDocument: - - - - 371 - - - - capitalizeWord: - - - - 454 - - - - lowercaseWord: - - - - 455 - - - - uppercaseWord: - - - - 456 - - - - toggleAutomaticDashSubstitution: - - - - 460 - - - - orderFrontSubstitutionsPanel: - - - - 461 - - - - toggleAutomaticTextReplacement: - - - - 463 - - - - toggleAutomaticSpellingCorrection: - - - - 466 - - - - performFindPanelAction: - - - - 467 - - - - performFindPanelAction: - - - - 468 - - - - performFindPanelAction: - - - - 469 - - - - pasteAsPlainText: - - - - 471 - - - - showHelp: - - - - 494 - - - - newDocument: - - - - 540 - - - - performMiniaturize: - - - - 650 - - - - arrangeInFront: - - - - 651 - - - - performZoom: - - - - 652 - - - - timelineView - - - - 553 - - - - mentionsView - - - - 562 - - - - timelineViewWindow - - - - 565 - - - - mentionsViewWindow - - - - 566 - - - - globalHotkeyMenuItem - - - - 570 - - - - login: - - - - 606 - - - - logout: - - - - 612 - - - - loginViewWindow - - - - 616 - - - - loginActivityIndicator - - - - 622 - - - - conversationView - - - - 632 - - - - conversationViewWindow - - - - 633 - - - - loginEntityTextField - - - - 643 - - - - profileView - - - - 662 - - - - profileViewWindow - - - - 663 - - - - login: - - - - 666 - - - - showProfileTextField - - - - 678 - - - - showProfile: - - - - 680 - - - - showProfile: - - - - 681 - - - - openProfileWindow - - - - 682 - - - - makeKeyAndOrderFront: - - - - 656 - - - - checkForUpdates: - - - - 543 - - - - delegate - - - - 569 - - - - makeKeyAndOrderFront: - - - - 655 - - - - makeKeyAndOrderFront: - - - - 611 - - - - value: values.entity - - - - - - value: values.entity - value - values.entity - 2 - - - 619 - - - - delegate - - - - 631 - - - - delegate - - - - 661 - - - - makeKeyAndOrderFront: - - - - 676 - - - - - YES - - 0 - - YES - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 29 - - - YES - - - - - - - - - - - 56 - - - YES - - - - - - 217 - - - YES - - - - - - 83 - - - YES - - - - - - 81 - - - YES - - - - - - - - - - - - 72 - - - - - 82 - - - - - 79 - - - - - 205 - - - YES - - - - - - - - - - - - - - - - - - - - 202 - - - - - 198 - - - - - 207 - - - - - 214 - - - - - 199 - - - - - 203 - - - - - 197 - - - - - 206 - - - - - 215 - - - - - 218 - - - YES - - - - - - 216 - - - YES - - - - - - 200 - - - YES - - - - - - - - - - - 219 - - - - - 201 - - - - - 204 - - - - - 220 - - - YES - - - - - - - - - - 213 - - - - - 210 - - - - - 221 - - - - - 208 - - - - - 209 - - - - - 57 - - - YES - - - - - - - - - - - - - - - - 58 - - - - - 134 - - - - - 150 - - - - - 136 - - - - - 144 - - - - - 236 - - - - - 131 - - - YES - - - - - - 149 - - - - - 145 - - - - - 130 - - - - - 295 - - - YES - - - - - - 296 - - - YES - - - - - - - 297 - - - - - 298 - - - - - 211 - - - YES - - - - - - 212 - - - YES - - - - - - - 195 - - - - - 196 - - - - - 346 - - - - - 348 - - - YES - - - - - - 349 - - - YES - - - - - - - - - - - - 350 - - - - - 351 - - - - - 354 - - - - - 419 - - - - - 449 - - - YES - - - - - - 450 - - - YES - - - - - - - - 451 - - - - - 452 - - - - - 453 - - - - - 457 - - - - - 458 - - - - - 459 - - - - - 462 - - - - - 464 - - - - - 465 - - - - - 470 - - - - - 491 - - - YES - - - - - - 492 - - - YES - - - - - - 493 - - - - - 533 - - - - - 535 - - - YES - - - - Timeline - - - 536 - - - YES - - - - - - 537 - - - timeline - - - 541 - - - - - 542 - - - - - 559 - - - YES - - - - Mentions - - - 560 - - - YES - - - - - - 561 - - - - - 592 - - - YES - - - - - - 593 - - - YES - - - - - - - - - - 594 - - - YES - - - - - - 595 - - - - - 596 - - - YES - - - - - - 597 - - - - - 598 - - - YES - - - - - - 599 - - - - - 600 - - - YES - - - - - - 601 - - - - - 602 - - - - - 603 - - - - - 610 - - - - - 613 - - - - - 620 - - - - - 73 - - - - - 628 - - - YES - - - - Conversation - - - 629 - - - YES - - - - - - 630 - - - - - 644 - - - YES - - - - - - 645 - - - YES - - - - - - - - - - - - 646 - - - - - 647 - - - - - 648 - - - - - 649 - - - - - 653 - - - - - 654 - - - - - 657 - - - - - 658 - - - YES - - - - Profile - - - 659 - - - YES - - - - - - 660 - - - - - 667 - - - - - 668 - - - YES - - - - - - 669 - - - YES - - - - - - - - 670 - - - YES - - - - - - 671 - - - - - 672 - - - YES - - - - - - 673 - - - - - 674 - - - YES - - - - - - 675 - - - - - - - YES - - YES - -1.IBPluginDependency - -2.IBPluginDependency - -3.IBPluginDependency - 130.IBPluginDependency - 131.IBPluginDependency - 134.IBPluginDependency - 136.IBPluginDependency - 144.IBPluginDependency - 145.IBPluginDependency - 149.IBPluginDependency - 150.IBPluginDependency - 195.IBPluginDependency - 196.IBPluginDependency - 197.IBPluginDependency - 198.IBPluginDependency - 199.IBPluginDependency - 200.IBPluginDependency - 201.IBPluginDependency - 202.IBPluginDependency - 203.IBPluginDependency - 204.IBPluginDependency - 205.IBPluginDependency - 206.IBPluginDependency - 207.IBPluginDependency - 208.IBPluginDependency - 209.IBPluginDependency - 210.IBPluginDependency - 211.IBPluginDependency - 212.IBPluginDependency - 213.IBPluginDependency - 214.IBPluginDependency - 215.IBPluginDependency - 216.IBPluginDependency - 217.IBPluginDependency - 218.IBPluginDependency - 219.IBPluginDependency - 220.IBPluginDependency - 221.IBPluginDependency - 236.IBPluginDependency - 29.IBPluginDependency - 295.IBPluginDependency - 296.IBPluginDependency - 297.IBPluginDependency - 298.IBPluginDependency - 346.IBPluginDependency - 348.IBPluginDependency - 349.IBPluginDependency - 350.IBPluginDependency - 351.IBPluginDependency - 354.IBPluginDependency - 419.IBPluginDependency - 449.IBPluginDependency - 450.IBPluginDependency - 451.IBPluginDependency - 452.IBPluginDependency - 453.IBPluginDependency - 457.IBPluginDependency - 458.IBPluginDependency - 459.IBPluginDependency - 462.IBPluginDependency - 464.IBPluginDependency - 465.IBPluginDependency - 470.IBPluginDependency - 491.IBPluginDependency - 492.IBPluginDependency - 493.IBPluginDependency - 533.IBPluginDependency - 535.IBPluginDependency - 535.IBWindowTemplateEditedContentRect - 535.NSWindowTemplate.visibleAtLaunch - 536.IBPluginDependency - 537.IBPluginDependency - 541.IBPluginDependency - 542.IBPluginDependency - 559.IBPluginDependency - 559.IBWindowTemplateEditedContentRect - 559.NSWindowTemplate.visibleAtLaunch - 56.IBPluginDependency - 560.IBPluginDependency - 561.IBPluginDependency - 57.IBPluginDependency - 58.IBPluginDependency - 592.IBPluginDependency - 592.NSWindowTemplate.visibleAtLaunch - 593.IBPluginDependency - 594.IBPluginDependency - 595.IBPluginDependency - 596.IBPluginDependency - 597.IBPluginDependency - 598.IBPluginDependency - 599.IBPluginDependency - 600.IBPluginDependency - 601.IBPluginDependency - 602.IBPluginDependency - 603.IBPluginDependency - 610.IBPluginDependency - 613.IBPluginDependency - 620.IBPluginDependency - 628.IBPluginDependency - 628.IBWindowTemplateEditedContentRect - 628.NSWindowTemplate.visibleAtLaunch - 629.IBPluginDependency - 630.IBPluginDependency - 644.IBPluginDependency - 645.IBPluginDependency - 646.IBPluginDependency - 647.IBPluginDependency - 648.IBPluginDependency - 649.IBPluginDependency - 653.IBPluginDependency - 654.IBPluginDependency - 657.IBPluginDependency - 658.IBPluginDependency - 658.IBWindowTemplateEditedContentRect - 658.NSWindowTemplate.visibleAtLaunch - 659.IBPluginDependency - 660.IBPluginDependency - 667.IBPluginDependency - 668.IBPluginDependency - 668.NSWindowTemplate.visibleAtLaunch - 669.IBPluginDependency - 670.IBPluginDependency - 671.IBPluginDependency - 672.IBPluginDependency - 673.IBPluginDependency - 674.IBPluginDependency - 675.IBPluginDependency - 72.IBPluginDependency - 73.IBPluginDependency - 79.IBPluginDependency - 81.IBPluginDependency - 82.IBPluginDependency - 83.IBPluginDependency - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{202, 175}, {397, 581}} - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.WebKitIBPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{344, 175}, {376, 581}} - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.WebKitIBPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{344, 175}, {376, 581}} - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.WebKitIBPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{344, 175}, {376, 581}} - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.WebKitIBPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - YES - - - - - - YES - - - - - 682 - - - - YES - - Controller - NSObject - - YES - - YES - clearCache: - login: - logout: - showProfile: - - - YES - id - id - id - id - - - - YES - - YES - clearCache: - login: - logout: - showProfile: - - - YES - - clearCache: - id - - - login: - id - - - logout: - id - - - showProfile: - id - - - - - YES - - YES - conversationView - conversationViewWindow - globalHotkeyMenuItem - loginActivityIndicator - loginEntityTextField - loginViewWindow - logoLayer - mentionsView - mentionsViewWindow - openProfileWindow - profileView - profileViewWindow - showProfileTextField - timelineView - timelineViewWindow - viewDelegate - - - YES - WebView - NSWindow - NSMenuItem - NSProgressIndicator - NSTextField - NSWindow - NSImageView - WebView - NSWindow - NSPanel - WebView - NSWindow - NSTextField - WebView - NSWindow - ViewDelegate - - - - YES - - YES - conversationView - conversationViewWindow - globalHotkeyMenuItem - loginActivityIndicator - loginEntityTextField - loginViewWindow - logoLayer - mentionsView - mentionsViewWindow - openProfileWindow - profileView - profileViewWindow - showProfileTextField - timelineView - timelineViewWindow - viewDelegate - - - YES - - conversationView - WebView - - - conversationViewWindow - NSWindow - - - globalHotkeyMenuItem - NSMenuItem - - - loginActivityIndicator - NSProgressIndicator - - - loginEntityTextField - NSTextField - - - loginViewWindow - NSWindow - - - logoLayer - NSImageView - - - mentionsView - WebView - - - mentionsViewWindow - NSWindow - - - openProfileWindow - NSPanel - - - profileView - WebView - - - profileViewWindow - NSWindow - - - showProfileTextField - NSTextField - - - timelineView - WebView - - - timelineViewWindow - NSWindow - - - viewDelegate - ViewDelegate - - - - - IBProjectSource - ./Classes/Controller.h - - - - SUUpdater - NSObject - - checkForUpdates: - id - - - checkForUpdates: - - checkForUpdates: - id - - - - delegate - id - - - delegate - - delegate - id - - - - IBProjectSource - ./Classes/SUUpdater.h - - - - ViewDelegate - NSObject - - IBProjectSource - ./Classes/ViewDelegate.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - YES - - YES - Icon - NSMenuCheckmark - NSMenuMixedState - - - YES - {256, 256} - {11, 11} - {10, 3} - - - - diff --git a/Mac/English.lproj/NewMessageWindow.xib b/Mac/English.lproj/NewMessageWindow.xib deleted file mode 100644 index c1aacae..0000000 --- a/Mac/English.lproj/NewMessageWindow.xib +++ /dev/null @@ -1,834 +0,0 @@ - - - - 1080 - 12C60 - 2844 - 1187.34 - 625.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 2844 - - - YES - NSButton - NSButtonCell - NSCustomObject - NSMenu - NSMenuItem - NSTextField - NSTextFieldCell - NSView - NSWindowTemplate - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - YES - - NewMessageWindow - - - FirstResponder - - - 15 - 2 - {{133, 535}, {299, 113}} - 1886913536 - New Post - NSWindow - View - - {94, 86} - - - 256 - - YES - - - 274 - {{0, 22}, {299, 91}} - - - - YES - - -1809842175 - 268468224 - - - LucidaGrande - 13 - 1044 - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - 3 - MAA - - - - NO - - - - 289 - {{215, 3}, {38, 17}} - - - - YES - - 68157504 - 71304192 - 256 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - - - NO - - - - 292 - {{2, 0}, {18, 19}} - - - - _NS:9 - YES - - 67108864 - 134217728 - - - LucidaGrande-Bold - 12 - 16 - - _NS:9 - - 113524736 - 268435629 - - NSImage - NSAddTemplate - - - + - 200 - 25 - - NO - - - - 289 - {{258, 2}, {38, 16}} - - - - _NS:9 - YES - - -2080374784 - 134217728 - ⌘↩ - - LucidaGrande-Bold - 11 - 3357 - - _NS:9 - - -2033434624 - 268435623 - - DQ - 400 - 75 - - NO - - - - 292 - {{20, 1}, {19, 19}} - - - - _NS:9 - YES - - 67108864 - 134217728 - - - _NS:9 - - 113524736 - 268435629 - - NSImage - NSLockUnlockedTemplate - - - p - 200 - 25 - - NO - - - {299, 113} - - - - - {{0, 0}, {2560, 1418}} - {94, 108} - {10000000000000, 10000000000000} - newPost - NO - 22 - YES - - - NSApplication - - - - - YES - - - Add current location - - 2147483647 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - - - - Add photo - - 2147483647 - - - - - - - - 268 - {29, 15} - _NS:9 - YES - - 67108864 - 134217728 - - - _NS:9 - - -2030813184 - 39 - - 549650432 - {1, 1} - - YES - - YES - - - - TU0AKgAAAAoAAAAOAQAAAwAAAAEAAQAAAQEAAwAAAAEAAQAAAQIAAwAAAAIACAAIAQMAAwAAAAEAAQAA -AQYAAwAAAAEAAQAAAREABAAAAAEAAAAIARIAAwAAAAEAAQAAARUAAwAAAAEAAgAAARYAAwAAAAEAAQAA -ARcABAAAAAEAAAACARwAAwAAAAEAAQAAAVIAAwAAAAEAAQAAAVMAAwAAAAIAAQABh3MABwAAB7gAAAC4 -AAAAAAAAB7hhcHBsAiAAAG1udHJHUkFZWFlaIAfQAAIADgAMAAAAAGFjc3BBUFBMAAAAAG5vbmUAAAAA -AAAAAAAAAAAAAAAAAAD21gABAAAAANMtYXBwbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAABWRlc2MAAADAAAAAb2RzY20AAAEwAAAGLGNwcnQAAAdcAAAAOHd0cHQAAAeU -AAAAFGtUUkMAAAeoAAAADmRlc2MAAAAAAAAAFUdlbmVyaWMgR3JheSBQcm9maWxlAAAAAAAAAAAAAAAV -R2VuZXJpYyBHcmF5IFByb2ZpbGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAABtbHVjAAAAAAAAAB4AAAAMc2tTSwAAACoAAAF4aHJIUgAAADoAAAGiY2FFUwAAACwAAAHc -cHRCUgAAACoAAAIIdWtVQQAAACwAAAIyZnJGVQAAACoAAAJeemhUVwAAABAAAAKIaXRJVAAAAC4AAAKY -bmJOTwAAACwAAALGa29LUgAAABgAAALyY3NDWgAAACQAAAMKaGVJTAAAACAAAAMuZGVERQAAADoAAANO -aHVIVQAAAC4AAAOIc3ZTRQAAAC4AAAO2emhDTgAAABAAAAPkamFKUAAAABYAAAP0cm9STwAAACIAAAQK -ZWxHUgAAACQAAAQscHRQTwAAADgAAARQbmxOTAAAACoAAASIZXNFUwAAACgAAASydGhUSAAAACQAAATa -dHJUUgAAACIAAAT+ZmlGSQAAACwAAAUgcGxQTAAAADYAAAVMcnVSVQAAACYAAAWCYXJFRwAAACgAAAWo -ZW5VUwAAACgAAAXQZGFESwAAADQAAAX4AFYBYQBlAG8AYgBlAGMAbgD9ACAAcwBpAHYA/QAgAHAAcgBv -AGYAaQBsAEcAZQBuAGUAcgBpAQ0AawBpACAAcAByAG8AZgBpAGwAIABzAGkAdgBpAGgAIAB0AG8AbgBv -AHYAYQBQAGUAcgBmAGkAbAAgAGQAZQAgAGcAcgBpAHMAIABnAGUAbgDoAHIAaQBjAFAAZQByAGYAaQBs -ACAAQwBpAG4AegBhACAARwBlAG4A6QByAGkAYwBvBBcEMAQzBDAEOwRMBD0EOAQ5ACAEPwRABD4ERAQw -BDkEOwAgAEcAcgBhAHkAUAByAG8AZgBpAGwAIABnAOkAbgDpAHIAaQBxAHUAZQAgAGcAcgBpAHOQGnUo -cHCWjoJyX2ljz4/wAFAAcgBvAGYAaQBsAG8AIABnAHIAaQBnAGkAbwAgAGcAZQBuAGUAcgBpAGMAbwBH -AGUAbgBlAHIAaQBzAGsAIABnAHIA5QB0AG8AbgBlAHAAcgBvAGYAaQBsx3y8GAAgAEcAcgBhAHkAINUE -uFzTDMd8AE8AYgBlAGMAbgD9ACABYQBlAGQA/QAgAHAAcgBvAGYAaQBsBeQF6AXVBeQF2QXcACAARwBy -AGEAeQAgBdsF3AXcBdkAQQBsAGwAZwBlAG0AZQBpAG4AZQBzACAARwByAGEAdQBzAHQAdQBmAGUAbgAt -AFAAcgBvAGYAaQBsAMEAbAB0AGEAbADhAG4AbwBzACAAcwB6APwAcgBrAGUAIABwAHIAbwBmAGkAbABH -AGUAbgBlAHIAaQBzAGsAIABnAHIA5QBzAGsAYQBsAGUAcAByAG8AZgBpAGxmbpAacHBepmPPj/Blh072 -TgCCLDCwMOwwpDDXMO0w1TChMKQw6wBQAHIAbwBmAGkAbAAgAGcAcgBpACAAZwBlAG4AZQByAGkDkwO1 -A70DuQO6A8wAIAPAA8EDvwPGA68DuwAgA7MDugPBA7kAUABlAHIAZgBpAGwAIABnAGUAbgDpAHIAaQBj -AG8AIABkAGUAIABjAGkAbgB6AGUAbgB0AG8AcwBBAGwAZwBlAG0AZQBlAG4AIABnAHIAaQBqAHMAcABy -AG8AZgBpAGUAbABQAGUAcgBmAGkAbAAgAGcAcgBpAHMAIABnAGUAbgDpAHIAaQBjAG8OQg4bDiMORA4f -DiUOTA4qDjUOQA4XDjIOFw4xDkgOJw5EDhsARwBlAG4AZQBsACAARwByAGkAIABQAHIAbwBmAGkAbABp -AFkAbABlAGkAbgBlAG4AIABoAGEAcgBtAGEAYQBwAHIAbwBmAGkAaQBsAGkAVQBuAGkAdwBlAHIAcwBh -AGwAbgB5ACAAcAByAG8AZgBpAGwAIABzAHoAYQByAG8BWwBjAGkEHgQxBEkEOAQ5ACAEQQQ1BEAESwQ5 -ACAEPwRABD4ERAQ4BDsETAZFBkQGQQAgBioGOQYxBkoGQQAgAEcAcgBhAHkAIAYnBkQGOQYnBkUARwBl -AG4AZQByAGkAYwAgAEcAcgBhAHkAIABQAHIAbwBmAGkAbABlAEcAZQBuAGUAcgBlAGwAIABnAHIA5QB0 -AG8AbgBlAGIAZQBzAGsAcgBpAHYAZQBsAHMAZXRleHQAAAAAQ29weXJpZ2h0IDIwMDcgQXBwbGUgSW5j -LiwgYWxsIHJpZ2h0cyByZXNlcnZlZC4AWFlaIAAAAAAAAPNRAAEAAAABFsxjdXJ2AAAAAAAAAAEBzQAA -A - - - - - - 3 - MCAwAA - - - - - 200 - 25 - - NO - - - - - YES - - - window - - - - 18 - - - - textField - - - - 100034 - - - - counter - - - - 100038 - - - - addMenu - - - - 100048 - - - - addCurrentLocation: - - - - 100049 - - - - openAddMenu: - - - - 100053 - - - - addMenuButton - - - - 100054 - - - - sendPost: - - - - 100068 - - - - sendPostButtonPressed: - - - - 100070 - - - - togglePrivate: - - - - 100076 - - - - togglePrivateButton - - - - 100080 - - - - addImage: - - - - 100083 - - - - delegate - - - - 100035 - - - - menu - - - - 100045 - - - - - YES - - 0 - - YES - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 5 - - - YES - - - - Window - - - 6 - - - YES - - - - - - - - - - -3 - - - Application - - - 100028 - - - YES - - - - - - 100029 - - - - - 100036 - - - YES - - - - - - 100037 - - - - - 100039 - - - YES - - - - - - 100040 - - - - - 100041 - - - YES - - - - - - - 100043 - - - - - 100059 - - - YES - - - - - - 100060 - - - - - 100065 - - - YES - - - - - - 100066 - - - - - 100074 - - - YES - - - - - - 100075 - - - - - 100081 - - - - - - - YES - - YES - -1.IBPluginDependency - -2.IBPluginDependency - -3.IBPluginDependency - 100028.IBPluginDependency - 100029.IBPluginDependency - 100036.IBPluginDependency - 100037.IBPluginDependency - 100039.IBPluginDependency - 100040.IBPluginDependency - 100041.IBPluginDependency - 100043.IBPluginDependency - 100059.IBPluginDependency - 100060.IBPluginDependency - 100065.IBPluginDependency - 100066.IBPluginDependency - 100074.IBPluginDependency - 100075.IBPluginDependency - 100081.IBPluginDependency - 5.IBPluginDependency - 5.IBWindowTemplateEditedContentRect - 6.IBPluginDependency - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{127, 736}, {299, 113}} - com.apple.InterfaceBuilder.CocoaPlugin - - - - YES - - - - - - YES - - - - - 100083 - - - - YES - - NewMessageWindow - NSDocument - - YES - - YES - addCurrentLocation: - addImage: - openAddMenu: - sendPost: - sendPostButtonPressed: - togglePrivate: - - - YES - id - id - id - NSControl - id - id - - - - YES - - YES - addCurrentLocation: - addImage: - openAddMenu: - sendPost: - sendPostButtonPressed: - togglePrivate: - - - YES - - addCurrentLocation: - id - - - addImage: - id - - - openAddMenu: - id - - - sendPost: - NSControl - - - sendPostButtonPressed: - id - - - togglePrivate: - id - - - - - YES - - YES - addMenu - addMenuButton - counter - textField - togglePrivateButton - - - YES - NSMenu - NSButton - NSTextField - NSTextField - NSButton - - - - YES - - YES - addMenu - addMenuButton - counter - textField - togglePrivateButton - - - YES - - addMenu - NSMenu - - - addMenuButton - NSButton - - - counter - NSTextField - - - textField - NSTextField - - - togglePrivateButton - NSButton - - - - - IBProjectSource - ./Classes/NewMessageWindow.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - YES - - YES - NSAddTemplate - NSLockUnlockedTemplate - NSMenuCheckmark - NSMenuMixedState - - - YES - {8, 8} - {9, 12} - {11, 11} - {10, 3} - - - - diff --git a/Mac/Growl Registration Ticket.growlRegDict b/Mac/Growl Registration Ticket.growlRegDict deleted file mode 100644 index b7c02c5..0000000 --- a/Mac/Growl Registration Ticket.growlRegDict +++ /dev/null @@ -1,17 +0,0 @@ - - - - - TicketVersion - 1 - DefaultNotifications - - Mention - - AllNotifications - - Mention - Status - - - diff --git a/Mac/Growl.framework/Growl b/Mac/Growl.framework/Growl deleted file mode 120000 index 85956e2..0000000 --- a/Mac/Growl.framework/Growl +++ /dev/null @@ -1 +0,0 @@ -Versions/Current/Growl \ No newline at end of file diff --git a/Mac/Growl.framework/Headers b/Mac/Growl.framework/Headers deleted file mode 120000 index a177d2a..0000000 --- a/Mac/Growl.framework/Headers +++ /dev/null @@ -1 +0,0 @@ -Versions/Current/Headers \ No newline at end of file diff --git a/Mac/Growl.framework/Resources b/Mac/Growl.framework/Resources deleted file mode 120000 index 953ee36..0000000 --- a/Mac/Growl.framework/Resources +++ /dev/null @@ -1 +0,0 @@ -Versions/Current/Resources \ No newline at end of file diff --git a/Mac/Growl.framework/Versions/A/Growl b/Mac/Growl.framework/Versions/A/Growl deleted file mode 100755 index f61df83..0000000 Binary files a/Mac/Growl.framework/Versions/A/Growl and /dev/null differ diff --git a/Mac/Growl.framework/Versions/A/Headers/Growl.h b/Mac/Growl.framework/Versions/A/Headers/Growl.h deleted file mode 100644 index 7b1a324..0000000 --- a/Mac/Growl.framework/Versions/A/Headers/Growl.h +++ /dev/null @@ -1,5 +0,0 @@ -#include - -#ifdef __OBJC__ -# include -#endif diff --git a/Mac/Growl.framework/Versions/A/Headers/GrowlApplicationBridge.h b/Mac/Growl.framework/Versions/A/Headers/GrowlApplicationBridge.h deleted file mode 100644 index 6ad38f9..0000000 --- a/Mac/Growl.framework/Versions/A/Headers/GrowlApplicationBridge.h +++ /dev/null @@ -1,567 +0,0 @@ -// -// GrowlApplicationBridge.h -// Growl -// -// Created by Evan Schoenberg on Wed Jun 16 2004. -// Copyright 2004-2006 The Growl Project. All rights reserved. -// - -/*! - * @header GrowlApplicationBridge.h - * @abstract Defines the GrowlApplicationBridge class. - * @discussion This header defines the GrowlApplicationBridge class as well as - * the GROWL_PREFPANE_BUNDLE_IDENTIFIER constant. - */ - -#ifndef __GrowlApplicationBridge_h__ -#define __GrowlApplicationBridge_h__ - -#import -#import -#import - -//Forward declarations -@protocol GrowlApplicationBridgeDelegate; - -//------------------------------------------------------------------------------ -#pragma mark - - -/*! - * @class GrowlApplicationBridge - * @abstract A class used to interface with Growl. - * @discussion This class provides a means to interface with Growl. - * - * Currently it provides a way to detect if Growl is installed and launch the - * GrowlHelperApp if it's not already running. - */ -@interface GrowlApplicationBridge : NSObject { - -} - -/*! - * @method isGrowlInstalled - * @abstract Detects whether Growl is installed. - * @discussion Determines if the Growl prefpane and its helper app are installed. - * @result this method will forever return YES. - */ -+ (BOOL) isGrowlInstalled __attribute__((deprecated)); - -/*! - * @method isGrowlRunning - * @abstract Detects whether GrowlHelperApp is currently running. - * @discussion Cycles through the process list to find whether GrowlHelperApp is running and returns its findings. - * @result Returns YES if GrowlHelperApp is running, NO otherwise. - */ -+ (BOOL) isGrowlRunning; - - -/*! - * @method isMistEnabled - * @abstract Gives the caller a fairly good indication of whether or not built-in notifications(Mist) will be used. - * @discussion since this call makes use of isGrowlRunning it is entirely possible for this value to change between call and - * executing a notification dispatch - * @result Returns YES if Growl isn't reachable and the developer has not opted-out of - * Mist and the user hasn't set the global mist enable key to false. - */ -+ (BOOL)isMistEnabled; - -/*! - * @method setShouldUseBuiltInNotifications - * @abstract opt-out mechanism for the mist notification style in the event growl can't be reached. - * @discussion if growl is unavailable due to not being installed or as a result of being turned off then - * this option can enable/disable a built-in fire and forget display style - * @param should Specifies whether or not the developer wants to opt-in (default) or opt out - * of the built-in Mist style in the event Growl is unreachable. - */ -+ (void)setShouldUseBuiltInNotifications:(BOOL)should; - -/*! - * @method shouldUseBuiltInNotifications - * @abstract returns the current opt-in state of the framework's use of the Mist display style. - * @result Returns NO if the developer opt-ed out of Mist, the default value is YES. - */ -+ (BOOL)shouldUseBuiltInNotifications; - -#pragma mark - - -/*! - * @method setGrowlDelegate: - * @abstract Set the object which will be responsible for providing and receiving Growl information. - * @discussion This must be called before using GrowlApplicationBridge. - * - * The methods in the GrowlApplicationBridgeDelegate protocol are required - * and return the basic information needed to register with Growl. - * - * The methods in the GrowlApplicationBridgeDelegate_InformalProtocol - * informal protocol are individually optional. They provide a greater - * degree of interaction between the application and growl such as informing - * the application when one of its Growl notifications is clicked by the user. - * - * The methods in the GrowlApplicationBridgeDelegate_Installation_InformalProtocol - * informal protocol are individually optional and are only applicable when - * using the Growl-WithInstaller.framework which allows for automated Growl - * installation. - * - * When this method is called, data will be collected from inDelegate, Growl - * will be launched if it is not already running, and the application will be - * registered with Growl. - * - * If using the Growl-WithInstaller framework, if Growl is already installed - * but this copy of the framework has an updated version of Growl, the user - * will be prompted to update automatically. - * - * @param inDelegate The delegate for the GrowlApplicationBridge. It must conform to the GrowlApplicationBridgeDelegate protocol. - */ -+ (void) setGrowlDelegate:(id)inDelegate; - -/*! - * @method growlDelegate - * @abstract Return the object responsible for providing and receiving Growl information. - * @discussion See setGrowlDelegate: for details. - * @result The Growl delegate. - */ -+ (id) growlDelegate; - -#pragma mark - - -/*! - * @method notifyWithTitle:description:notificationName:iconData:priority:isSticky:clickContext: - * @abstract Send a Growl notification. - * @discussion This is the preferred means for sending a Growl notification. - * The notification name and at least one of the title and description are - * required (all three are preferred). All other parameters may be - * nil (or 0 or NO as appropriate) to accept default values. - * - * If using the Growl-WithInstaller framework, if Growl is not installed the - * user will be prompted to install Growl. If the user cancels, this method - * will have no effect until the next application session, at which time when - * it is called the user will be prompted again. The user is also given the - * option to not be prompted again. If the user does choose to install Growl, - * the requested notification will be displayed once Growl is installed and - * running. - * - * @param title The title of the notification displayed to the user. - * @param description The full description of the notification displayed to the user. - * @param notifName The internal name of the notification. Should be human-readable, as it will be displayed in the Growl preference pane. - * @param iconData NSData object to show with the notification as its icon. If nil, the application's icon will be used instead. - * @param priority The priority of the notification. The default value is 0; positive values are higher priority and negative values are lower priority. Not all Growl displays support priority. - * @param isSticky If YES, the notification will remain on screen until clicked. Not all Growl displays support sticky notifications. - * @param clickContext A context passed back to the Growl delegate if it implements -(void)growlNotificationWasClicked: and the notification is clicked. Not all display plugins support clicking. The clickContext must be plist-encodable (completely of NSString, NSArray, NSNumber, NSDictionary, and NSData types). - */ -+ (void) notifyWithTitle:(NSString *)title - description:(NSString *)description - notificationName:(NSString *)notifName - iconData:(NSData *)iconData - priority:(signed int)priority - isSticky:(BOOL)isSticky - clickContext:(id)clickContext; - -/*! - * @method notifyWithTitle:description:notificationName:iconData:priority:isSticky:clickContext:identifier: - * @abstract Send a Growl notification. - * @discussion This is the preferred means for sending a Growl notification. - * The notification name and at least one of the title and description are - * required (all three are preferred). All other parameters may be - * nil (or 0 or NO as appropriate) to accept default values. - * - * If using the Growl-WithInstaller framework, if Growl is not installed the - * user will be prompted to install Growl. If the user cancels, this method - * will have no effect until the next application session, at which time when - * it is called the user will be prompted again. The user is also given the - * option to not be prompted again. If the user does choose to install Growl, - * the requested notification will be displayed once Growl is installed and - * running. - * - * @param title The title of the notification displayed to the user. - * @param description The full description of the notification displayed to the user. - * @param notifName The internal name of the notification. Should be human-readable, as it will be displayed in the Growl preference pane. - * @param iconData NSData object to show with the notification as its icon. If nil, the application's icon will be used instead. - * @param priority The priority of the notification. The default value is 0; positive values are higher priority and negative values are lower priority. Not all Growl displays support priority. - * @param isSticky If YES, the notification will remain on screen until clicked. Not all Growl displays support sticky notifications. - * @param clickContext A context passed back to the Growl delegate if it implements -(void)growlNotificationWasClicked: and the notification is clicked. Not all display plugins support clicking. The clickContext must be plist-encodable (completely of NSString, NSArray, NSNumber, NSDictionary, and NSData types). - * @param identifier An identifier for this notification. Notifications with equal identifiers are coalesced. - */ -+ (void) notifyWithTitle:(NSString *)title - description:(NSString *)description - notificationName:(NSString *)notifName - iconData:(NSData *)iconData - priority:(signed int)priority - isSticky:(BOOL)isSticky - clickContext:(id)clickContext - identifier:(NSString *)identifier; - -/*! @method notifyWithDictionary: - * @abstract Notifies using a userInfo dictionary suitable for passing to - * NSDistributedNotificationCenter. - * @param userInfo The dictionary to notify with. - * @discussion Before Growl 0.6, your application would have posted - * notifications using NSDistributedNotificationCenter by - * creating a userInfo dictionary with the notification data. This had the - * advantage of allowing you to add other data to the dictionary for programs - * besides Growl that might be listening. - * - * This method allows you to use such dictionaries without being restricted - * to using NSDistributedNotificationCenter. The keys for this dictionary - * can be found in GrowlDefines.h. - */ -+ (void) notifyWithDictionary:(NSDictionary *)userInfo; - -#pragma mark - - -/*! @method registerWithDictionary: - * @abstract Register your application with Growl without setting a delegate. - * @discussion When you call this method with a dictionary, - * GrowlApplicationBridge registers your application using that dictionary. - * If you pass nil, GrowlApplicationBridge will ask the delegate - * (if there is one) for a dictionary, and if that doesn't work, it will look - * in your application's bundle for an auto-discoverable plist. - * (XXX refer to more information on that) - * - * If you pass a dictionary to this method, it must include the - * GROWL_APP_NAME key, unless a delegate is set. - * - * This method is mainly an alternative to the delegate system introduced - * with Growl 0.6. Without a delegate, you cannot receive callbacks such as - * -growlIsReady (since they are sent to the delegate). You can, - * however, set a delegate after registering without one. - * - * This method was introduced in Growl.framework 0.7. - */ -+ (BOOL) registerWithDictionary:(NSDictionary *)regDict; - -/*! @method reregisterGrowlNotifications - * @abstract Reregister the notifications for this application. - * @discussion This method does not normally need to be called. If your - * application changes what notifications it is registering with Growl, call - * this method to have the Growl delegate's - * -registrationDictionaryForGrowl method called again and the - * Growl registration information updated. - * - * This method is now implemented using -registerWithDictionary:. - */ -+ (void) reregisterGrowlNotifications; - -#pragma mark - - -/*! @method setWillRegisterWhenGrowlIsReady: - * @abstract Tells GrowlApplicationBridge to register with Growl when Growl - * launches (or not). - * @discussion When Growl has started listening for notifications, it posts a - * GROWL_IS_READY notification on the Distributed Notification - * Center. GrowlApplicationBridge listens for this notification, using it to - * perform various tasks (such as calling your delegate's - * -growlIsReady method, if it has one). If this method is - * called with YES, one of those tasks will be to reregister - * with Growl (in the manner of -reregisterGrowlNotifications). - * - * This attribute is automatically set back to NO (the default) - * after every GROWL_IS_READY notification. - * @param flag YES if you want GrowlApplicationBridge to register with - * Growl when next it is ready; NO if not. - */ -+ (void) setWillRegisterWhenGrowlIsReady:(BOOL)flag; - -/*! @method willRegisterWhenGrowlIsReady - * @abstract Reports whether GrowlApplicationBridge will register with Growl - * when Growl next launches. - * @result YES if GrowlApplicationBridge will register with Growl - * when next it posts GROWL_IS_READY; NO if not. - */ -+ (BOOL) willRegisterWhenGrowlIsReady; - -#pragma mark - - -/*! @method registrationDictionaryFromDelegate - * @abstract Asks the delegate for a registration dictionary. - * @discussion If no delegate is set, or if the delegate's - * -registrationDictionaryForGrowl method returns - * nil, this method returns nil. - * - * This method does not attempt to clean up the dictionary in any way - for - * example, if it is missing the GROWL_APP_NAME key, the result - * will be missing it too. Use +[GrowlApplicationBridge - * registrationDictionaryByFillingInDictionary:] or - * +[GrowlApplicationBridge - * registrationDictionaryByFillingInDictionary:restrictToKeys:] to try - * to fill in missing keys. - * - * This method was introduced in Growl.framework 0.7. - * @result A registration dictionary. - */ -+ (NSDictionary *) registrationDictionaryFromDelegate; - -/*! @method registrationDictionaryFromBundle: - * @abstract Looks in a bundle for a registration dictionary. - * @discussion This method looks in a bundle for an auto-discoverable - * registration dictionary file using -[NSBundle - * pathForResource:ofType:]. If it finds one, it loads the file using - * +[NSDictionary dictionaryWithContentsOfFile:] and returns the - * result. - * - * If you pass nil as the bundle, the main bundle is examined. - * - * This method does not attempt to clean up the dictionary in any way - for - * example, if it is missing the GROWL_APP_NAME key, the result - * will be missing it too. Use +[GrowlApplicationBridge - * registrationDictionaryByFillingInDictionary:] or - * +[GrowlApplicationBridge - * registrationDictionaryByFillingInDictionary:restrictToKeys:] to try - * to fill in missing keys. - * - * This method was introduced in Growl.framework 0.7. - * @result A registration dictionary. - */ -+ (NSDictionary *) registrationDictionaryFromBundle:(NSBundle *)bundle; - -/*! @method bestRegistrationDictionary - * @abstract Obtains a registration dictionary, filled out to the best of - * GrowlApplicationBridge's knowledge. - * @discussion This method creates a registration dictionary as best - * GrowlApplicationBridge knows how. - * - * First, GrowlApplicationBridge contacts the Growl delegate (if there is - * one) and gets the registration dictionary from that. If no such dictionary - * was obtained, GrowlApplicationBridge looks in your application's main - * bundle for an auto-discoverable registration dictionary file. If that - * doesn't exist either, this method returns nil. - * - * Second, GrowlApplicationBridge calls - * +registrationDictionaryByFillingInDictionary: with whatever - * dictionary was obtained. The result of that method is the result of this - * method. - * - * GrowlApplicationBridge uses this method when you call - * +setGrowlDelegate:, or when you call - * +registerWithDictionary: with nil. - * - * This method was introduced in Growl.framework 0.7. - * @result A registration dictionary. - */ -+ (NSDictionary *) bestRegistrationDictionary; - -#pragma mark - - -/*! @method registrationDictionaryByFillingInDictionary: - * @abstract Tries to fill in missing keys in a registration dictionary. - * @discussion This method examines the passed-in dictionary for missing keys, - * and tries to work out correct values for them. As of 0.7, it uses: - * - * Key Value - * --- ----- - * GROWL_APP_NAME CFBundleExecutableName - * GROWL_APP_ICON_DATA The data of the icon of the application. - * GROWL_APP_LOCATION The location of the application. - * GROWL_NOTIFICATIONS_DEFAULT GROWL_NOTIFICATIONS_ALL - * - * Keys are only filled in if missing; if a key is present in the dictionary, - * its value will not be changed. - * - * This method was introduced in Growl.framework 0.7. - * @param regDict The dictionary to fill in. - * @result The dictionary with the keys filled in. This is an autoreleased - * copy of regDict. - */ -+ (NSDictionary *) registrationDictionaryByFillingInDictionary:(NSDictionary *)regDict; - -/*! @method registrationDictionaryByFillingInDictionary:restrictToKeys: - * @abstract Tries to fill in missing keys in a registration dictionary. - * @discussion This method examines the passed-in dictionary for missing keys, - * and tries to work out correct values for them. As of 0.7, it uses: - * - * Key Value - * --- ----- - * GROWL_APP_NAME CFBundleExecutableName - * GROWL_APP_ICON_DATA The data of the icon of the application. - * GROWL_APP_LOCATION The location of the application. - * GROWL_NOTIFICATIONS_DEFAULT GROWL_NOTIFICATIONS_ALL - * - * Only those keys that are listed in keys will be filled in. - * Other missing keys are ignored. Also, keys are only filled in if missing; - * if a key is present in the dictionary, its value will not be changed. - * - * This method was introduced in Growl.framework 0.7. - * @param regDict The dictionary to fill in. - * @param keys The keys to fill in. If nil, any missing keys are filled in. - * @result The dictionary with the keys filled in. This is an autoreleased - * copy of regDict. - */ -+ (NSDictionary *) registrationDictionaryByFillingInDictionary:(NSDictionary *)regDict restrictToKeys:(NSSet *)keys; - -/*! @brief Tries to fill in missing keys in a notification dictionary. - * @param notifDict The dictionary to fill in. - * @return The dictionary with the keys filled in. This will be a separate instance from \a notifDict. - * @discussion This function examines the \a notifDict for missing keys, and - * tries to get them from the last known registration dictionary. As of 1.1, - * the keys that it will look for are: - * - * \li GROWL_APP_NAME - * \li GROWL_APP_ICON_DATA - * - * @since Growl.framework 1.1 - */ -+ (NSDictionary *) notificationDictionaryByFillingInDictionary:(NSDictionary *)regDict; - -+ (NSDictionary *) frameworkInfoDictionary; - -#pragma mark - - -/*! - *@method growlURLSchemeAvailable - *@abstract Lets the app know whether growl:// is registered on the system, used for certain methods below this - *@return Returns whether growl:// is registered on the system - *@discussion Methods such as openGrowlPreferences rely on the growl:// URL scheme to function - * Further, this method can provide a check on whether Growl is installed, - * however, the framework will not be relying on this method for choosing when/how to notify, - * and it is not recommended that the app rely on it for other than whether to use growl:// methods - *@since Growl.framework 1.4 - */ -+ (BOOL) isGrowlURLSchemeAvailable; - -/*! - * @method openGrowlPreferences: - * @abstract Open Growl preferences, optionally to this app's settings, growl:// method - * @param showApp Whether to show the application's settings, otherwise just opens to the last position - * @return Return's whether opening the URL was succesfull or not. - * @discussion Will launch if Growl is installed, but not running, and open the preferences window - * Uses growl:// URL scheme - * @since Growl.framework 1.4 - */ -+ (BOOL) openGrowlPreferences:(BOOL)showApp; - -@end - -//------------------------------------------------------------------------------ -#pragma mark - - -/*! - * @protocol GrowlApplicationBridgeDelegate - * @abstract Required protocol for the Growl delegate. - * @discussion The methods in this protocol are optional and are called - * automatically as needed by GrowlApplicationBridge. See - * +[GrowlApplicationBridge setGrowlDelegate:]. - * See also GrowlApplicationBridgeDelegate_InformalProtocol. - */ - -@protocol GrowlApplicationBridgeDelegate - -@optional - -/*! - * @method registrationDictionaryForGrowl - * @abstract Return the dictionary used to register this application with Growl. - * @discussion The returned dictionary gives Growl the complete list of - * notifications this application will ever send, and it also specifies which - * notifications should be enabled by default. Each is specified by an array - * of NSString objects. - * - * For most applications, these two arrays can be the same (if all sent - * notifications should be displayed by default). - * - * The NSString objects of these arrays will correspond to the - * notificationName: parameter passed in - * +[GrowlApplicationBridge - * notifyWithTitle:description:notificationName:iconData:priority:isSticky:clickContext:] calls. - * - * The dictionary should have the required key object pairs: - * key: GROWL_NOTIFICATIONS_ALL object: NSArray of NSString objects - * key: GROWL_NOTIFICATIONS_DEFAULT object: NSArray of NSString objects - * - * The dictionary may have the following key object pairs: - * key: GROWL_NOTIFICATIONS_HUMAN_READABLE_NAMES object: NSDictionary of key: notification name object: human-readable notification name - * - * You do not need to implement this method if you have an auto-discoverable - * plist file in your app bundle. (XXX refer to more information on that) - * - * @result The NSDictionary to use for registration. - */ -- (NSDictionary *) registrationDictionaryForGrowl; - -/*! - * @method applicationNameForGrowl - * @abstract Return the name of this application which will be used for Growl bookkeeping. - * @discussion This name is used both internally and in the Growl preferences. - * - * This should remain stable between different versions and incarnations of - * your application. - * For example, "SurfWriter" is a good app name, whereas "SurfWriter 2.0" and - * "SurfWriter Lite" are not. - * - * You do not need to implement this method if you are providing the - * application name elsewhere, meaning in an auto-discoverable plist file in - * your app bundle (XXX refer to more information on that) or in the result - * of -registrationDictionaryForGrowl. - * - * @result The name of the application using Growl. - */ -- (NSString *) applicationNameForGrowl; - -/*! - * @method applicationIconForGrowl - * @abstract Return the NSImage to treat as the application icon. - * @discussion The delegate may optionally return an NSImage - * object to use as the application icon. If this method is not implemented, - * {{{-applicationIconDataForGrowl}}} is tried. If that method is not - * implemented, the application's own icon is used. Neither method is - * generally needed. - * @result The NSImage to treat as the application icon. - */ -- (NSImage *) applicationIconForGrowl; - -/*! - * @method applicationIconDataForGrowl - * @abstract Return the NSData to treat as the application icon. - * @discussion The delegate may optionally return an NSData - * object to use as the application icon; if this is not implemented, the - * application's own icon is used. This is not generally needed. - * @result The NSData to treat as the application icon. - * @deprecated In version 1.1, in favor of {{{-applicationIconForGrowl}}}. - */ -- (NSData *) applicationIconDataForGrowl; - -/*! - * @method growlIsReady - * @abstract Informs the delegate that Growl has launched. - * @discussion Informs the delegate that Growl (specifically, the - * GrowlHelperApp) was launched successfully. The application can take actions - * with the knowledge that Growl is installed and functional. - */ -- (void) growlIsReady; - -/*! - * @method growlNotificationWasClicked: - * @abstract Informs the delegate that a Growl notification was clicked. - * @discussion Informs the delegate that a Growl notification was clicked. It - * is only sent for notifications sent with a non-nil - * clickContext, so if you want to receive a message when a notification is - * clicked, clickContext must not be nil when calling - * +[GrowlApplicationBridge notifyWithTitle: description:notificationName:iconData:priority:isSticky:clickContext:]. - * @param clickContext The clickContext passed when displaying the notification originally via +[GrowlApplicationBridge notifyWithTitle:description:notificationName:iconData:priority:isSticky:clickContext:]. - */ -- (void) growlNotificationWasClicked:(id)clickContext; - -/*! - * @method growlNotificationTimedOut: - * @abstract Informs the delegate that a Growl notification timed out. - * @discussion Informs the delegate that a Growl notification timed out. It - * is only sent for notifications sent with a non-nil - * clickContext, so if you want to receive a message when a notification is - * clicked, clickContext must not be nil when calling - * +[GrowlApplicationBridge notifyWithTitle: description:notificationName:iconData:priority:isSticky:clickContext:]. - * @param clickContext The clickContext passed when displaying the notification originally via +[GrowlApplicationBridge notifyWithTitle:description:notificationName:iconData:priority:isSticky:clickContext:]. - */ -- (void) growlNotificationTimedOut:(id)clickContext; - - -/*! - * @method hasNetworkClientEntitlement - * @abstract Used only in sandboxed situations since we don't know whether the app has com.apple.security.network.client entitlement - * @discussion GrowlDelegate calls to find out if we have the com.apple.security.network.client entitlement, - * since we can't find this out without hitting the sandbox. We only call it if we detect that the application is sandboxed. - */ -- (BOOL) hasNetworkClientEntitlement; - -@end - -#pragma mark - - -#endif /* __GrowlApplicationBridge_h__ */ diff --git a/Mac/Growl.framework/Versions/A/Headers/GrowlDefines.h b/Mac/Growl.framework/Versions/A/Headers/GrowlDefines.h deleted file mode 100644 index 0a196f1..0000000 --- a/Mac/Growl.framework/Versions/A/Headers/GrowlDefines.h +++ /dev/null @@ -1,386 +0,0 @@ -// -// GrowlDefines.h -// - -#ifndef _GROWLDEFINES_H -#define _GROWLDEFINES_H - -#ifdef __OBJC__ -#define XSTR(x) (@x) -#else -#define XSTR CFSTR -#endif - -/*! @header GrowlDefines.h - * @abstract Defines all the notification keys. - * @discussion Defines all the keys used for registration with Growl and for - * Growl notifications. - * - * Most applications should use the functions or methods of Growl.framework - * instead of posting notifications such as those described here. - * @updated 2004-01-25 - */ - -// UserInfo Keys for Registration -#pragma mark UserInfo Keys for Registration - -/*! @group Registration userInfo keys */ -/* @abstract Keys for the userInfo dictionary of a GROWL_APP_REGISTRATION distributed notification. - * @discussion The values of these keys describe the application and the - * notifications it may post. - * - * Your application must register with Growl before it can post Growl - * notifications (and have them not be ignored). However, as of Growl 0.6, - * posting GROWL_APP_REGISTRATION notifications directly is no longer the - * preferred way to register your application. Your application should instead - * use Growl.framework's delegate system. - * See +[GrowlApplicationBridge setGrowlDelegate:] or Growl_SetDelegate for - * more information. - */ - -/*! @defined GROWL_APP_NAME - * @abstract The name of your application. - * @discussion The name of your application. This should remain stable between - * different versions and incarnations of your application. - * For example, "SurfWriter" is a good app name, whereas "SurfWriter 2.0" and - * "SurfWriter Lite" are not. - */ -#define GROWL_APP_NAME XSTR("ApplicationName") -/*! @defined GROWL_APP_ID - * @abstract The bundle identifier of your application. - * @discussion The bundle identifier of your application. This key should - * be unique for your application while there may be several applications - * with the same GROWL_APP_NAME. - * This key is optional. - */ -#define GROWL_APP_ID XSTR("ApplicationId") -/*! @defined GROWL_APP_ICON_DATA - * @abstract The image data for your application's icon. - * @discussion Image data representing your application's icon. This may be - * superimposed on a notification icon as a badge, used as the notification - * icon when a notification-specific icon is not supplied, or ignored - * altogether, depending on the display. Must be in a format supported by - * NSImage, such as TIFF, PNG, GIF, JPEG, BMP, PICT, or PDF. - * - * Optional. Not supported by all display plugins. - */ -#define GROWL_APP_ICON_DATA XSTR("ApplicationIcon") -/*! @defined GROWL_NOTIFICATIONS_DEFAULT - * @abstract The array of notifications to turn on by default. - * @discussion These are the names of the notifications that should be enabled - * by default when your application registers for the first time. If your - * application reregisters, Growl will look here for any new notification - * names found in GROWL_NOTIFICATIONS_ALL, but ignore any others. - */ -#define GROWL_NOTIFICATIONS_DEFAULT XSTR("DefaultNotifications") -/*! @defined GROWL_NOTIFICATIONS_ALL - * @abstract The array of all notifications your application can send. - * @discussion These are the names of all of the notifications that your - * application may post. See GROWL_NOTIFICATION_NAME for a discussion of good - * notification names. - */ -#define GROWL_NOTIFICATIONS_ALL XSTR("AllNotifications") -/*! @defined GROWL_NOTIFICATIONS_HUMAN_READABLE_DESCRIPTIONS - * @abstract A dictionary of human-readable names for your notifications. - * @discussion By default, the Growl UI will display notifications by the names given in GROWL_NOTIFICATIONS_ALL - * which correspond to the GROWL_NOTIFICATION_NAME. This dictionary specifies the human-readable name to display. - * The keys of the dictionary are GROWL_NOTIFICATION_NAME strings; the objects are the human-readable versions. - * For any GROWL_NOTIFICATION_NAME not specific in this dictionary, the GROWL_NOTIFICATION_NAME will be displayed. - * - * This key is optional. - */ -#define GROWL_NOTIFICATIONS_HUMAN_READABLE_NAMES XSTR("HumanReadableNames") -/*! @defined GROWL_NOTIFICATIONS_DESCRIPTIONS -* @abstract A dictionary of descriptions of _when_ each notification occurs -* @discussion This is an NSDictionary whose keys are GROWL_NOTIFICATION_NAME strings and whose objects are -* descriptions of _when_ each notification occurs, such as "You received a new mail message" or -* "A file finished downloading". -* -* This key is optional. -*/ -#define GROWL_NOTIFICATIONS_DESCRIPTIONS XSTR("NotificationDescriptions") -/*! @defined GROWL_NOTIFICATIONS_ICONS - * @abstract A dictionary of icons for each notification - * @discussion This is an NSDictionary whose keys are GROWL_NOTIFICATION_NAME strings and whose objects are - * icons for each notification, for GNTP spec - * - * This key is optional. - */ -#define GROWL_NOTIFICATIONS_ICONS XSTR("NotificationIcons") - -/*! @defined GROWL_TICKET_VERSION - * @abstract The version of your registration ticket. - * @discussion Include this key in a ticket plist file that you put in your - * application bundle for auto-discovery. The current ticket version is 1. - */ -#define GROWL_TICKET_VERSION XSTR("TicketVersion") -// UserInfo Keys for Notifications -#pragma mark UserInfo Keys for Notifications - -/*! @group Notification userInfo keys */ -/* @abstract Keys for the userInfo dictionary of a GROWL_NOTIFICATION distributed notification. - * @discussion The values of these keys describe the content of a Growl - * notification. - * - * Not all of these keys are supported by all displays. Only the name, title, - * and description of a notification are universal. Most of the built-in - * displays do support all of these keys, and most other visual displays - * probably will also. But, as of 0.6, the Log, MailMe, and Speech displays - * support only textual data. - */ - -/*! @defined GROWL_NOTIFICATION_NAME - * @abstract The name of the notification. - * @discussion The name of the notification. Note that if you do not define - * GROWL_NOTIFICATIONS_HUMAN_READABLE_NAMES when registering your ticket originally this name - * will the one displayed within the Growl preference pane and should be human-readable. - */ -#define GROWL_NOTIFICATION_NAME XSTR("NotificationName") -/*! @defined GROWL_NOTIFICATION_TITLE - * @abstract The title to display in the notification. - * @discussion The title of the notification. Should be very brief. - * The title usually says what happened, e.g. "Download complete". - */ -#define GROWL_NOTIFICATION_TITLE XSTR("NotificationTitle") -/*! @defined GROWL_NOTIFICATION_DESCRIPTION - * @abstract The description to display in the notification. - * @discussion The description should be longer and more verbose than the title. - * The description usually tells the subject of the action, - * e.g. "Growl-0.6.dmg downloaded in 5.02 minutes". - */ -#define GROWL_NOTIFICATION_DESCRIPTION XSTR("NotificationDescription") -/*! @defined GROWL_NOTIFICATION_ICON - * @discussion Image data for the notification icon. Image data must be in a format - * supported by NSImage, such as TIFF, PNG, GIF, JPEG, BMP, PICT, or PDF. - * - * Optional. Not supported by all display plugins. - */ -#define GROWL_NOTIFICATION_ICON_DATA XSTR("NotificationIcon") -/*! @defined GROWL_NOTIFICATION_APP_ICON - * @discussion Image data for the application icon, in case GROWL_APP_ICON does - * not apply for some reason. Image data be in a format supported by NSImage, such - * as TIFF, PNG, GIF, JPEG, BMP, PICT, or PDF. - * - * Optional. Not supported by all display plugins. - */ -#define GROWL_NOTIFICATION_APP_ICON_DATA XSTR("NotificationAppIcon") -/*! @defined GROWL_NOTIFICATION_PRIORITY - * @discussion The priority of the notification as an integer number from - * -2 to +2 (+2 being highest). - * - * Optional. Not supported by all display plugins. - */ -#define GROWL_NOTIFICATION_PRIORITY XSTR("NotificationPriority") -/*! @defined GROWL_NOTIFICATION_STICKY - * @discussion A Boolean number controlling whether the notification is sticky. - * - * Optional. Not supported by all display plugins. - */ -#define GROWL_NOTIFICATION_STICKY XSTR("NotificationSticky") -/*! @defined GROWL_NOTIFICATION_CLICK_CONTEXT - * @abstract Identifies which notification was clicked. - * @discussion An identifier for the notification for clicking purposes. - * - * This will be passed back to the application when the notification is - * clicked. It must be plist-encodable (a data, dictionary, array, number, or - * string object), and it should be unique for each notification you post. - * A good click context would be a UUID string returned by NSProcessInfo or - * CFUUID. - * - * Optional. Not supported by all display plugins. - */ -#define GROWL_NOTIFICATION_CLICK_CONTEXT XSTR("NotificationClickContext") - -/*! @defined GROWL_NOTIFICATION_IDENTIFIER - * @abstract An identifier for the notification for coalescing purposes. - * Notifications with the same identifier fall into the same class; only - * the last notification of a class is displayed on the screen. If a - * notification of the same class is currently being displayed, it is - * replaced by this notification. - * - * Optional. Not supported by all display plugins. - */ -#define GROWL_NOTIFICATION_IDENTIFIER XSTR("GrowlNotificationIdentifier") - -/*! @defined GROWL_APP_PID - * @abstract The process identifier of the process which sends this - * notification. If this field is set, the application will only receive - * clicked and timed out notifications which originate from this process. - * - * Optional. - */ -#define GROWL_APP_PID XSTR("ApplicationPID") - -/*! @defined GROWL_NOTIFICATION_PROGRESS -* @abstract If this key is set, it should contain a double value wrapped -* in a NSNumber which describes some sort of progress (from 0.0 to 100.0). -* If this is key is not set, no progress bar is shown. -* -* Optional. Not supported by all display plugins. -*/ -#define GROWL_NOTIFICATION_PROGRESS XSTR("NotificationProgress") - -/*! @defined GROWL_NOTIFICATION_ALREADY_SHOWN - * @abstract If this key is set, it should contain a bool value wrapped - * in a NSNumber which describes whether the notification has - * already been displayed, for instance by built in Notification - * Center support. This value can be used to allow display - * plugins to skip a notification, while still allowing Growl - * actions to run on them. - * - * Optional. Not supported by all display plugins. - */ -#define GROWL_NOTIFICATION_ALREADY_SHOWN XSTR("AlreadyShown") - - -// Notifications -#pragma mark Notifications - -/*! @group Notification names */ -/* @abstract Names of distributed notifications used by Growl. - * @discussion These are notifications used by applications (directly or - * indirectly) to interact with Growl, and by Growl for interaction between - * its components. - * - * Most of these should no longer be used in Growl 0.6 and later, in favor of - * Growl.framework's GrowlApplicationBridge APIs. - */ - -/*! @defined GROWL_APP_REGISTRATION - * @abstract The distributed notification for registering your application. - * @discussion This is the name of the distributed notification that can be - * used to register applications with Growl. - * - * The userInfo dictionary for this notification can contain these keys: - *
    - *
  • GROWL_APP_NAME
  • - *
  • GROWL_APP_ICON_DATA
  • - *
  • GROWL_NOTIFICATIONS_ALL
  • - *
  • GROWL_NOTIFICATIONS_DEFAULT
  • - *
- * - * No longer recommended as of Growl 0.6. An alternate method of registering - * is to use Growl.framework's delegate system. - * See +[GrowlApplicationBridge setGrowlDelegate:] or Growl_SetDelegate for - * more information. - */ -#define GROWL_APP_REGISTRATION XSTR("GrowlApplicationRegistrationNotification") -/*! @defined GROWL_APP_REGISTRATION_CONF - * @abstract The distributed notification for confirming registration. - * @discussion The name of the distributed notification sent to confirm the - * registration. Used by the Growl preference pane. Your application probably - * does not need to use this notification. - */ -#define GROWL_APP_REGISTRATION_CONF XSTR("GrowlApplicationRegistrationConfirmationNotification") -/*! @defined GROWL_NOTIFICATION - * @abstract The distributed notification for Growl notifications. - * @discussion This is what it all comes down to. This is the name of the - * distributed notification that your application posts to actually send a - * Growl notification. - * - * The userInfo dictionary for this notification can contain these keys: - *
    - *
  • GROWL_NOTIFICATION_NAME (required)
  • - *
  • GROWL_NOTIFICATION_TITLE (required)
  • - *
  • GROWL_NOTIFICATION_DESCRIPTION (required)
  • - *
  • GROWL_NOTIFICATION_ICON
  • - *
  • GROWL_NOTIFICATION_APP_ICON
  • - *
  • GROWL_NOTIFICATION_PRIORITY
  • - *
  • GROWL_NOTIFICATION_STICKY
  • - *
  • GROWL_NOTIFICATION_CLICK_CONTEXT
  • - *
  • GROWL_APP_NAME (required)
  • - *
- * - * No longer recommended as of Growl 0.6. Three alternate methods of posting - * notifications are +[GrowlApplicationBridge notifyWithTitle:description:notificationName:iconData:priority:isSticky:clickContext:], - * Growl_NotifyWithTitleDescriptionNameIconPriorityStickyClickContext, and - * Growl_PostNotification. - */ -#define GROWL_NOTIFICATION XSTR("GrowlNotification") -/*! @defined GROWL_PING - * @abstract A distributed notification to check whether Growl is running. - * @discussion This is used by the Growl preference pane. If it receives a - * GROWL_PONG, the preference pane takes this to mean that Growl is running. - */ -#define GROWL_PING XSTR("Honey, Mind Taking Out The Trash") -/*! @defined GROWL_PONG - * @abstract The distributed notification sent in reply to GROWL_PING. - * @discussion GrowlHelperApp posts this in reply to GROWL_PING. - */ -#define GROWL_PONG XSTR("What Do You Want From Me, Woman") -/*! @defined GROWL_IS_READY - * @abstract The distributed notification sent when Growl starts up. - * @discussion GrowlHelperApp posts this when it has begin listening on all of - * its sources for new notifications. GrowlApplicationBridge (in - * Growl.framework), upon receiving this notification, reregisters using the - * registration dictionary supplied by its delegate. - */ -#define GROWL_IS_READY XSTR("Lend Me Some Sugar; I Am Your Neighbor!") - - -/*! @defined GROWL_DISTRIBUTED_NOTIFICATION_CLICKED_SUFFIX - * @abstract Part of the name of the distributed notification sent when a supported notification is clicked. - * @discussion When a Growl notification with a click context is clicked on by - * the user, Growl posts a distributed notification whose name is in the format: - * [NSString stringWithFormat:@"%@-%d-%@", appName, pid, GROWL_DISTRIBUTED_NOTIFICATION_CLICKED_SUFFIX] - * The GrowlApplicationBridge responds to this notification by calling a callback in its delegate. - */ -#define GROWL_DISTRIBUTED_NOTIFICATION_CLICKED_SUFFIX XSTR("GrowlClicked!") - -/*! @defined GROWL_DISTRIBUTED_NOTIFICATION_TIMED_OUT_SUFFIX - * @abstract Part of the name of the distributed notification sent when a supported notification times out without being clicked. - * @discussion When a Growl notification with a click context times out, Growl posts a distributed notification - * whose name is in the format: - * [NSString stringWithFormat:@"%@-%d-%@", appName, pid, GROWL_DISTRIBUTED_NOTIFICATION_TIMED_OUT_SUFFIX] - * The GrowlApplicationBridge responds to this notification by calling a callback in its delegate. - * NOTE: The user may have actually clicked the 'close' button; this triggers an *immediate* time-out of the notification. - */ -#define GROWL_DISTRIBUTED_NOTIFICATION_TIMED_OUT_SUFFIX XSTR("GrowlTimedOut!") - -/*! @defined GROWL_DISTRIBUTED_NOTIFICATION_NOTIFICATIONCENTER_ON - * @abstract The distributed notification sent when the Notification Center support is toggled on in Growl 2.0 - * @discussion When the user enables Notification Center support in Growl 2.0, this notification is sent - * to inform all running apps that they should now speak to Notification Center directly. - */ -#define GROWL_DISTRIBUTED_NOTIFICATION_NOTIFICATIONCENTER_ON XSTR("GrowlNotificationCenterOn!") - -/*! @defined GROWL_DISTRIBUTED_NOTIFICATION_NOTIFICATIONCENTER_OFF - * @abstract The distributed notification sent when the Notification Center support is toggled off in Growl 2.0 - * @discussion When the user enables Notification Center support in Growl 2.0, this notification is sent - * to inform all running apps that they should no longer speak to Notification Center directly. - */ -#define GROWL_DISTRIBUTED_NOTIFICATION_NOTIFICATIONCENTER_OFF XSTR("GrowlNotificationCenterOff!") - -/*! @defined GROWL_DISTRIBUTED_NOTIFICATION_NOTIFICATIONCENTER_QUERY - * @abstract The distributed notification sent by an application to query Growl 2.0's notification center support. - * @discussion When an app starts up, it will send this query to get Growl 2.0 to spit out whether notification - * center support is on or off. - */ -#define GROWL_DISTRIBUTED_NOTIFICATION_NOTIFICATIONCENTER_QUERY XSTR("GrowlNotificationCenterYN?") - - -/*! @group Other symbols */ -/* Symbols which don't fit into any of the other categories. */ - -/*! @defined GROWL_KEY_CLICKED_CONTEXT - * @abstract Used internally as the key for the clickedContext passed over DNC. - * @discussion This key is used in GROWL_NOTIFICATION_CLICKED, and contains the - * click context that was supplied in the original notification. - */ -#define GROWL_KEY_CLICKED_CONTEXT XSTR("ClickedContext") -/*! @defined GROWL_REG_DICT_EXTENSION - * @abstract The filename extension for registration dictionaries. - * @discussion The GrowlApplicationBridge in Growl.framework registers with - * Growl by creating a file with the extension of .(GROWL_REG_DICT_EXTENSION) - * and opening it in the GrowlHelperApp. This happens whether or not Growl is - * running; if it was stopped, it quits immediately without listening for - * notifications. - */ -#define GROWL_REG_DICT_EXTENSION XSTR("growlRegDict") - - -#define GROWL_POSITION_PREFERENCE_KEY @"GrowlSelectedPosition" - -#define GROWL_PLUGIN_CONFIG_ID XSTR("GrowlPluginConfigurationID") - -#endif //ndef _GROWLDEFINES_H diff --git a/Mac/Growl.framework/Versions/A/Headers/GrowlPluginPreferenceStrings.h b/Mac/Growl.framework/Versions/A/Headers/GrowlPluginPreferenceStrings.h deleted file mode 100644 index 4632ba6..0000000 --- a/Mac/Growl.framework/Versions/A/Headers/GrowlPluginPreferenceStrings.h +++ /dev/null @@ -1,67 +0,0 @@ -// -// GrowlPluginPreferenceStrings.h -// Growl -// -// Created by Daniel Siemer on 1/30/12. -// Copyright (c) 2012 The Growl Project. All rights reserved. -// - -/* FOR GROWL DEVELOPED COCOA PLUGINS ONLY AT THIS TIME, NOT STABLE */ - -#import - -#define GrowlDisplayOpacity NSLocalizedStringFromTable(@"Opacity:", @"PluginPrefStrings", @"How clear the display is") -#define GrowlDisplayDuration NSLocalizedStringFromTable(@"Duration:", @"PluginPrefStrings", @"How long a notification will stay on screen") - -#define GrowlDisplayPriority NSLocalizedStringFromTable(@"Priority: (low to high)", @"PluginPrefStrings", @"Label for columns of color wells for various priority levels") -#define GrowlDisplayPriorityLow NSLocalizedStringFromTable(@"Very Low", @"PluginPrefStrings", @"Notification Priority Very Low") -#define GrowlDisplayPriorityModerate NSLocalizedStringFromTable(@"Moderate", @"PluginPrefStrings", @"Notification Priority Moderate") -#define GrowlDisplayPriorityNormal NSLocalizedStringFromTable(@"Normal", @"PluginPrefStrings", @"Notification Priority Normal") -#define GrowlDisplayPriorityHigh NSLocalizedStringFromTable(@"High", @"PluginPrefStrings", @"Notification Priority High") -#define GrowlDisplayPriorityEmergency NSLocalizedStringFromTable(@"Emergency", @"PluginPrefStrings", @"Notification Priority Emergency") - -#define GrowlDisplayTextColor NSLocalizedStringFromTable(@"Text", @"PluginPrefStrings", @"Label for row of color wells for the text element of the plugin") -#define GrowlDisplayBackgroundColor NSLocalizedStringFromTable(@"Background", @"PluginPrefStrings", @"Label for row of color wells for the background of the plugin") - -#define GrowlDisplayLimitLines NSLocalizedStringFromTable(@"Limit to 2-5 lines", @"PluginPrefStrings", @"Checkbox to limit the display to 2-5 lines") -#define GrowlDisplayScreen NSLocalizedStringFromTable(@"Screen:", @"PluginPrefStrings", @"Label for box to select screen for display to use") -#define GrowlDisplaySize NSLocalizedStringFromTable(@"Size:", @"PluginPrefStrings", @"Label for pop up box for selecting the size of the display") -#define GrowlDisplaySizeNormal NSLocalizedStringFromTable(@"Normal", @"PluginPrefStrings", @"Normal size for the display") -#define GrowlDisplaySizeLarge NSLocalizedStringFromTable(@"Large", @"PluginPrefStrings", @"Large size for the display") -#define GrowlDisplaySizeSmall NSLocalizedStringFromTable(@"Small", @"PluginPrefStrings", @"Small size for the display") - -#define GrowlDisplayFloatingIcon NSLocalizedStringFromTable(@"Floating Icon", @"PluginPrefStrings", @"Label for checkbox that says to do a floating icon") - -#define GrowlDisplayEffect NSLocalizedStringFromTable(@"Effect:", @"PluginPrefStrings", @"Label for the effect to use") -#define GrowlDisplayEffectSlide NSLocalizedStringFromTable(@"Slide", @"PluginPrefStrings", @"A slide effect") -#define GrowlDisplayEffectFade NSLocalizedStringFromTable(@"Fade", @"PluginPrefStrings", @"A fade effect") - -@interface GrowlPluginPreferenceStrings : NSObject - -@property (nonatomic, retain) NSString *growlDisplayOpacity; -@property (nonatomic, retain) NSString *growlDisplayDuration; - -@property (nonatomic, retain) NSString *growlDisplayPriority; -@property (nonatomic, retain) NSString *growlDisplayPriorityVeryLow; -@property (nonatomic, retain) NSString *growlDisplayPriorityModerate; -@property (nonatomic, retain) NSString *growlDisplayPriorityNormal; -@property (nonatomic, retain) NSString *growlDisplayPriorityHigh; -@property (nonatomic, retain) NSString *growlDisplayPriorityEmergency; - -@property (nonatomic, retain) NSString *growlDisplayTextColor; -@property (nonatomic, retain) NSString *growlDisplayBackgroundColor; - -@property (nonatomic, retain) NSString *growlDisplayLimitLines; -@property (nonatomic, retain) NSString *growlDisplayScreen; -@property (nonatomic, retain) NSString *growlDisplaySize; -@property (nonatomic, retain) NSString *growlDisplaySizeNormal; -@property (nonatomic, retain) NSString *growlDisplaySizeLarge; -@property (nonatomic, retain) NSString *growlDisplaySizeSmall; - -@property (nonatomic, retain) NSString *growlDisplayFloatingIcon; - -@property (nonatomic, retain) NSString *effectLabel; -@property (nonatomic, retain) NSString *slideEffect; -@property (nonatomic, retain) NSString *fadeEffect; - -@end diff --git a/Mac/Growl.framework/Versions/A/Resources/Info.plist b/Mac/Growl.framework/Versions/A/Resources/Info.plist deleted file mode 100644 index 4d9bd5f..0000000 --- a/Mac/Growl.framework/Versions/A/Resources/Info.plist +++ /dev/null @@ -1,40 +0,0 @@ - - - - - BuildMachineOSBuild - 12A269 - CFBundleDevelopmentRegion - English - CFBundleExecutable - Growl - CFBundleIdentifier - com.growl.growlframework - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - FMWK - CFBundleShortVersionString - 2.0 - CFBundleSignature - GRRR - CFBundleVersion - 2.0 - DTCompiler - com.apple.compilers.llvm.clang.1_0 - DTPlatformBuild - 4F250 - DTPlatformVersion - GM - DTSDKBuild - 12A264 - DTSDKName - macosx10.8 - DTXcode - 0440 - DTXcodeBuild - 4F250 - NSPrincipalClass - GrowlApplicationBridge - - diff --git a/Mac/Growl.framework/Versions/A/_CodeSignature/CodeResources b/Mac/Growl.framework/Versions/A/_CodeSignature/CodeResources deleted file mode 100644 index d4a95e2..0000000 --- a/Mac/Growl.framework/Versions/A/_CodeSignature/CodeResources +++ /dev/null @@ -1,34 +0,0 @@ - - - - - files - - Resources/Info.plist - - lnx8exuPwE/bsUq32R5DXDQholc= - - - rules - - ^Resources/ - - ^Resources/.*\.lproj/ - - optional - - weight - 1000 - - ^Resources/.*\.lproj/locversion.plist$ - - omit - - weight - 1100 - - ^version.plist$ - - - - diff --git a/Mac/Growl.framework/Versions/Current b/Mac/Growl.framework/Versions/Current deleted file mode 120000 index 8c7e5a6..0000000 --- a/Mac/Growl.framework/Versions/Current +++ /dev/null @@ -1 +0,0 @@ -A \ No newline at end of file diff --git a/Mac/MimeType.h b/Mac/MimeType.h deleted file mode 100644 index 2072838..0000000 --- a/Mac/MimeType.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// MimeType.h -// bungloo -// -// Created by Jeena on 23/11/2012. -// -// - -#import - -@interface MimeType : NSObject -+(NSString *)mimeTypeForFileAtPath:(NSString *)path error:(NSError **)err; -@end diff --git a/Mac/MimeType.m b/Mac/MimeType.m deleted file mode 100644 index f1327c4..0000000 --- a/Mac/MimeType.m +++ /dev/null @@ -1,27 +0,0 @@ -// -// MimeType.m -// bungloo -// -// Created by Jeena on 23/11/2012. -// -// - -#import "MimeType.h" - -@implementation MimeType - -+(NSString *)mimeTypeForFileAtPath:(NSString *)path error:(NSError **)err { - NSString *uti, *mimeType = nil; - - if (!(uti = [[NSWorkspace sharedWorkspace] typeOfFile:path error:err])) - return nil; - if (err) - *err = nil; - - if ((mimeType = (NSString *)UTTypeCopyPreferredTagWithClass((CFStringRef)uti, kUTTagClassMIMEType))) - mimeType = NSMakeCollectable(mimeType); - - return mimeType; -} - -@end diff --git a/Mac/NSData+Base64.h b/Mac/NSData+Base64.h deleted file mode 100644 index fc674c8..0000000 --- a/Mac/NSData+Base64.h +++ /dev/null @@ -1,46 +0,0 @@ -// -// Created by Cédric Luthi on 2012-02-24. -// Copyright (c) 2012 Cédric Luthi. All rights reserved. -// - -#import "NSData+Base64.h" - -#ifndef __has_feature -#define __has_feature(x) 0 -#endif - -@implementation NSData (Base64) - -+ (id) dataWithBase64Encoding_xcd:(NSString *)base64Encoding -{ - if ([base64Encoding length] % 4 != 0) - return nil; - - NSString *plist = [NSString stringWithFormat:@"%@", base64Encoding]; - return [NSPropertyListSerialization propertyListWithData:[plist dataUsingEncoding:NSASCIIStringEncoding] options:0 format:NULL error:NULL]; -} - -- (NSString *) base64Encoding_xcd -{ - NSData *plist = [NSPropertyListSerialization dataWithPropertyList:self format:NSPropertyListXMLFormat_v1_0 options:0 error:NULL]; - NSRange fullRange = NSMakeRange(0, [plist length]); - NSRange startRange = [plist rangeOfData:[@"" dataUsingEncoding:NSASCIIStringEncoding] options:0 range:fullRange]; - NSRange endRange = [plist rangeOfData:[@"" dataUsingEncoding:NSASCIIStringEncoding] options:NSDataSearchBackwards range:fullRange]; - if (startRange.location == NSNotFound || endRange.location == NSNotFound) - return nil; - - NSUInteger base64Location = startRange.location + startRange.length; - NSUInteger base64length = endRange.location - base64Location; - NSData *base64Data = [NSData dataWithBytesNoCopy:(void *)((uintptr_t)base64Location + (uintptr_t)[plist bytes]) length:base64length freeWhenDone:NO]; - NSString *base64Encoding = [[NSString alloc] initWithData:base64Data encoding:NSASCIIStringEncoding]; - base64Encoding = [base64Encoding stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; - base64Encoding = [base64Encoding stringByReplacingOccurrencesOfString:@"\n" withString:@""]; - -#if __has_feature(objc_arc) - return base64Encoding; -#else - return [base64Encoding autorelease]; -#endif -} - -@end \ No newline at end of file diff --git a/Mac/NSData+Base64.m b/Mac/NSData+Base64.m deleted file mode 100644 index 1a71914..0000000 --- a/Mac/NSData+Base64.m +++ /dev/null @@ -1,13 +0,0 @@ -// -// Created by Cédric Luthi on 2012-02-24. -// Copyright (c) 2012 Cédric Luthi. All rights reserved. -// - -#import - -@interface NSData (Base64) - -+ (id) dataWithBase64Encoding_xcd:(NSString *)base64String; -- (NSString *) base64Encoding_xcd; - -@end \ No newline at end of file diff --git a/Mac/NewMessageWindow.h b/Mac/NewMessageWindow.h deleted file mode 100644 index b8893ab..0000000 --- a/Mac/NewMessageWindow.h +++ /dev/null @@ -1,47 +0,0 @@ -// -// NewMessageWindow.h -// bungloo -// -// Created by Jeena on 16.04.10. -// Licence: BSD (see attached LICENCE.txt file). -// - - -#import -#import - - -@interface NewMessageWindow : NSDocument -{ - IBOutlet NSTextField *textField; - IBOutlet NSTextField *counter; - NSMenu *addMenu; - NSButton *addMenuButton; - NSString *inReplyTostatusId; - NSString *inReplyToEntity; - NSMenuItem *addImage; - CLLocationManager *locationManager; - CLLocation *currentLocation; - NSString *imageFilePath; - NSButton *togglePrivateButton; -} - -@property (nonatomic, retain) IBOutlet NSTextField *textField; -@property (nonatomic, retain) IBOutlet NSTextField *counter; -@property (assign) IBOutlet NSMenu *addMenu; -@property (assign) IBOutlet NSButton *addMenuButton; -@property (retain, nonatomic) CLLocationManager *locationManager; -@property (retain, nonatomic) CLLocation *currentLocation; -@property (retain, nonatomic) NSString *imageFilePath; -@property (assign) IBOutlet NSButton *togglePrivateButton; - -- (IBAction)sendPost:(NSControl *)control; -- (void)inReplyTo:(NSString *)userName statusId:(NSString *)statusId withString:(NSString *)string; -- (void)withString:(NSString *)aString; -- (IBAction)addCurrentLocation:(id)sender; -- (IBAction)addImage:(id)sender; -- (IBAction)openAddMenu:(id)sender; -- (IBAction)togglePrivate:(id)sender; -- (void)setIsPrivate:(BOOL)isPrivate; - -@end diff --git a/Mac/NewMessageWindow.m b/Mac/NewMessageWindow.m deleted file mode 100644 index c69e78c..0000000 --- a/Mac/NewMessageWindow.m +++ /dev/null @@ -1,344 +0,0 @@ -// -// NewPostWindow.m -// bungloo -// -// Created by Jeena on 16.04.10. -// Licence: BSD (see attached LICENCE.txt file). -// - -#import "NewMessageWindow.h" -#import "Constants.h" -#import "PostModel.h" -#import "Controller.h" - -@interface NewMessageWindow (private) -- (BOOL)isCommandEnterEvent:(NSEvent *)e; -- (void)initLocationManager; -@end - -@implementation NewMessageWindow - -@synthesize addMenu; -@synthesize addMenuButton; -@synthesize textField, counter; -@synthesize locationManager, currentLocation; -@synthesize imageFilePath; -@synthesize togglePrivateButton; - -- (void)dealloc -{ - [locationManager stopUpdatingLocation]; - [locationManager release]; - [currentLocation release]; - [imageFilePath release]; - [super dealloc]; -} - -- (id)init -{ - self = [super init]; - if (self) - { - // Add your subclass-specific initialization here. - // If an error occurs here, send a [self release] message and return nil. - inReplyTostatusId = @""; - inReplyToEntity = @""; - } - return self; -} - -- (NSString *)windowNibName -{ - // Override returning the nib file name of the document - // If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead. - return @"NewMessageWindow"; -} - -- (NSString *)displayName -{ - return @"New Post"; -} - -- (void)windowControllerDidLoadNib:(NSWindowController *) aController -{ - [super windowControllerDidLoadNib:aController]; - // Add any code here that needs to be executed once the windowController has loaded the document's window. - [textField becomeFirstResponder]; - - // Enable Continous Spelling - NSTextView *textView = (NSTextView *)[[[self.windowControllers objectAtIndex:0] window] firstResponder];; - [textView setContinuousSpellCheckingEnabled:YES]; -} - -- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError -{ - // Insert code here to write your document to data of the specified type. If the given outError != NULL, ensure that you set *outError when returning nil. - - // You can also choose to override -fileWrapperOfType:error:, -writeToURL:ofType:error:, or -writeToURL:ofType:forSaveOperation:originalContentsURL:error: instead. - - // For applications targeted for Panther or earlier systems, you should use the deprecated API -dataRepresentationOfType:. In this case you can also choose to override -fileWrapperRepresentationOfType: or -writeToFile:ofType: instead. - - if ( outError != NULL ) { - *outError = [NSError errorWithDomain:NSOSStatusErrorDomain code:unimpErr userInfo:NULL]; - } - return nil; -} - -- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError -{ - // Insert code here to read your document from the given data of the specified type. If the given outError != NULL, ensure that you set *outError when returning NO. - - // You can also choose to override -readFromFileWrapper:ofType:error: or -readFromURL:ofType:error: instead. - - // For applications targeted for Panther or earlier systems, you should use the deprecated API -loadDataRepresentation:ofType. In this case you can also choose to override -readFromFile:ofType: or -loadFileWrapperRepresentation:ofType: instead. - - if ( outError != NULL ) - { - *outError = [NSError errorWithDomain:NSOSStatusErrorDomain code:unimpErr userInfo:NULL]; - } - return YES; -} - -- (void)inReplyTo:(NSString *)entity statusId:(NSString *)statusId withString:(NSString *)string -{ - [textField setStringValue:string]; - - NSInteger location = [string rangeOfString:@" "].location; - NSInteger length = 0; - if (location != NSNotFound) { - length = [[textField stringValue] length] - location - 1; - } - - - NSRange range = {location + 1, length}; - [[textField currentEditor] setSelectedRange:range]; - - [inReplyTostatusId release]; - inReplyTostatusId = statusId; - [inReplyTostatusId retain]; - - [inReplyToEntity release]; - inReplyToEntity = entity; - [inReplyToEntity retain]; - - [self controlTextDidChange:nil]; -} - -- (void)withString:(NSString *)aString -{ - [textField setStringValue:aString]; - NSRange range = {[[textField stringValue] length] , 0}; - [[textField currentEditor] setSelectedRange:range]; - NSLog(@"BB"); - - [self controlTextDidChange:nil]; -} - -- (IBAction)addCurrentLocation:(id)sender -{ - NSMenuItem *menuItem = (NSMenuItem *)sender; - if (!self.locationManager) - { - [menuItem setTitle:@"Current location not available"]; - [self initLocationManager]; - } - else - { - [self.locationManager stopUpdatingLocation]; - self.currentLocation = nil; - self.locationManager = nil; - [menuItem setTitle:@"Add current location"]; - } -} - -- (IBAction)openAddMenu:(id)sender -{ - NSRect frame = [(NSButton *)sender frame]; - NSPoint menuOrigin = [[(NSButton *)sender superview] convertPoint:NSMakePoint(frame.origin.x, frame.origin.y+frame.size.height) toView:nil]; - - NSEvent *event = [NSEvent mouseEventWithType:NSLeftMouseDown - location:menuOrigin - modifierFlags:NSLeftMouseDownMask // 0x100 - timestamp:NSTimeIntervalSince1970 - windowNumber:[[(NSButton *)sender window] windowNumber] - context:[[(NSButton *)sender window] graphicsContext] - eventNumber:0 - clickCount:1 - pressure:1]; - - [NSMenu popUpContextMenu:self.addMenu withEvent:event forView:self.addMenuButton]; -} - -- (IBAction)togglePrivate:(id)sender -{ - NSImage *image = [NSImage imageNamed:NSImageNameLockLockedTemplate]; - if (self.togglePrivateButton.image == [NSImage imageNamed:NSImageNameLockLockedTemplate]) - { - image = [NSImage imageNamed:NSImageNameLockUnlockedTemplate]; - } - [self.togglePrivateButton setImage:image]; -} - -- (void)setIsPrivate:(BOOL)isPrivate { - NSImage *image = [NSImage imageNamed:(isPrivate ? NSImageNameLockLockedTemplate : NSImageNameLockUnlockedTemplate)]; - [self.togglePrivateButton setImage:image]; -} - --(void)controlTextDidChange:(NSNotification *)aNotification { - NSInteger c = MESSAGE_MAX_LENGTH - [[textField stringValue] length]; - [counter setIntValue:c]; - if(c < 0) { - [counter setTextColor:[NSColor redColor]]; - } else { - [counter setTextColor:[NSColor controlTextColor]]; - } -} - -- (void)initLocationManager -{ - self.locationManager = [[CLLocationManager alloc] init]; - [self.locationManager setDelegate:self]; - [self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest]; - [self.locationManager setDistanceFilter:kCLDistanceFilterNone]; - [self.locationManager startUpdatingLocation]; -} - -- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation -{ - self.currentLocation = newLocation; - NSMenuItem *menuItem = [self.addMenu itemAtIndex:0]; - [menuItem setTitle:@"Remove current location"]; -} - -- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{ - NSLog(@"CLLocationManager Error: %@", error); - - NSMenuItem *menuItem = [self.addMenu itemAtIndex:0]; - [menuItem setTitle:@"Current location not available"]; -} - -- (IBAction)sendPostButtonPressed:(id)sender -{ - [self sendPost:self.textField]; -} - -#pragma mark Keyboard delegate methods - -- (IBAction)sendPost:(NSControl *)control { - BOOL emptyIsOk = self.currentLocation || self.imageFilePath; - if (emptyIsOk || ([[control stringValue] length] <= MESSAGE_MAX_LENGTH && [[control stringValue] length] > 0)) { - PostModel *post = [[[PostModel alloc] init] autorelease]; - post.text = [control stringValue]; - post.inReplyTostatusId = inReplyTostatusId; - post.inReplyToEntity = inReplyToEntity; - post.location = self.currentLocation; - post.imageFilePath = self.imageFilePath; - post.isPrivate = self.togglePrivateButton.image == [NSImage imageNamed:NSImageNameLockLockedTemplate]; - [[NSNotificationCenter defaultCenter] postNotificationName:@"sendPost" object:post]; - [self close]; - } else { - NSBeep(); - } - -} - -- (BOOL)isCommandEnterEvent:(NSEvent *)e { - NSUInteger flags = (e.modifierFlags & NSDeviceIndependentModifierFlagsMask); - BOOL isCommand = (flags & NSCommandKeyMask) == NSCommandKeyMask; - BOOL isEnter = (e.keyCode == 0x24); // VK_RETURN - return (isCommand && isEnter); -} - -- (BOOL)control:(NSControl *)control textView:(NSTextView *)fieldEditor doCommandBySelector:(SEL)commandSelector -{ - BOOL retval = NO; - - BOOL isEnter = [[NSApp currentEvent] keyCode] == 76; - - if (commandSelector == @selector(insertNewline:) && !isEnter) { - - NSText *text = [[textField window] fieldEditor:YES forObject:nil]; - - NSRange range = [text selectedRange]; - NSString *stringBefore = [textField.stringValue substringToIndex:range.location]; - NSString *stringAfter = [textField.stringValue substringFromIndex:range.location + range.length]; - - textField.stringValue = [NSString stringWithFormat:@"%@\n%@", stringBefore, stringAfter]; - - NSRange r = NSMakeRange(range.location + 1, 0); - [text scrollRangeToVisible:r]; - [text setSelectedRange:r]; - - retval = YES; // causes Apple to NOT fire the default enter action - } - else if (commandSelector == @selector(noop:) && isEnter) { - retval = YES; - [self sendPost:control]; - } - - return retval; -} - -#pragma mark Add images - -- (IBAction)addImage:(id)sender -{ - NSMenuItem *menuItem = (NSMenuItem *)sender; - - if (!self.imageFilePath) - { - [menuItem setTitle:@"Remove photo"]; - - NSOpenPanel* openDlg = [NSOpenPanel openPanel]; - [openDlg setPrompt:@"Select"]; - [openDlg setDelegate:self]; - - // Enable the selection of files in the dialog. - [openDlg setCanChooseFiles:YES]; - - // Enable the selection of directories in the dialog. - [openDlg setCanChooseDirectories:NO]; - - // Display the dialog. If the OK button was pressed, - // process the files. - if ( [openDlg runModalForDirectory:nil file:nil] == NSOKButton ) - { - // Get an array containing the full filenames of all - // files and directories selected. - NSArray* files = [openDlg filenames]; - - // Loop through all the files and process them. - for( int i = 0; i < [files count]; i++ ) - { - self.imageFilePath = [files objectAtIndex:i]; - } - } - } - else - { - self.imageFilePath = nil; - [menuItem setTitle:@"Add photo"]; - } -} - --(BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename -{ - NSString* ext = [filename pathExtension]; - if ([ext isEqualToString:@""] || [ext isEqualToString:@"/"] || ext == nil || ext == NULL || [ext length] < 1) { - return YES; - } - - NSEnumerator* tagEnumerator = [[NSArray arrayWithObjects:@"png", @"jpg", @"gif", @"jpeg", nil] objectEnumerator]; - NSString* allowedExt; - while ((allowedExt = [tagEnumerator nextObject])) - { - if ([ext caseInsensitiveCompare:allowedExt] == NSOrderedSame) - { - return YES; - } - } - - return NO; -} - -@end diff --git a/Mac/PostModel.h b/Mac/PostModel.h deleted file mode 100644 index 39eaef9..0000000 --- a/Mac/PostModel.h +++ /dev/null @@ -1,28 +0,0 @@ -// -// PostModel.h -// bungloo -// -// Created by Jeena on 10.01.11. -// Copyright 2011 __MyCompanyName__. All rights reserved. -// - -#import -#import - -@interface PostModel : NSObject { - NSString *text; - NSString *inReplyTostatusId; - NSString *inReplyToEntity; - CLLocation *location; - NSString *imageFilePath; - BOOL isPrivate; -} - -@property (nonatomic, retain) NSString *text; -@property (nonatomic, retain) NSString *inReplyTostatusId; -@property (nonatomic, retain) NSString *inReplyToEntity; -@property (nonatomic, retain) CLLocation *location; -@property (nonatomic, retain) NSString *imageFilePath; -@property (nonatomic) BOOL isPrivate; - -@end diff --git a/Mac/PostModel.m b/Mac/PostModel.m deleted file mode 100644 index b62c093..0000000 --- a/Mac/PostModel.m +++ /dev/null @@ -1,26 +0,0 @@ -// -// PostModel.m -// bungloo -// -// Created by Jeena on 10.01.11. -// Copyright 2011 __MyCompanyName__. All rights reserved. -// - -#import "PostModel.h" - - -@implementation PostModel - -@synthesize text, inReplyTostatusId, inReplyToEntity, location, imageFilePath, isPrivate; - -- (void)dealloc -{ - [text release]; - [inReplyTostatusId release]; - [inReplyToEntity release]; - [location release]; - [imageFilePath release]; - [super dealloc]; -} - -@end diff --git a/Mac/Sparkle.framework/Headers b/Mac/Sparkle.framework/Headers deleted file mode 120000 index a177d2a..0000000 --- a/Mac/Sparkle.framework/Headers +++ /dev/null @@ -1 +0,0 @@ -Versions/Current/Headers \ No newline at end of file diff --git a/Mac/Sparkle.framework/Resources b/Mac/Sparkle.framework/Resources deleted file mode 120000 index 953ee36..0000000 --- a/Mac/Sparkle.framework/Resources +++ /dev/null @@ -1 +0,0 @@ -Versions/Current/Resources \ No newline at end of file diff --git a/Mac/Sparkle.framework/Sparkle b/Mac/Sparkle.framework/Sparkle deleted file mode 120000 index b2c5273..0000000 --- a/Mac/Sparkle.framework/Sparkle +++ /dev/null @@ -1 +0,0 @@ -Versions/Current/Sparkle \ No newline at end of file diff --git a/Mac/Sparkle.framework/Versions/A/Headers/SUAppcast.h b/Mac/Sparkle.framework/Versions/A/Headers/SUAppcast.h deleted file mode 100644 index 171148a..0000000 --- a/Mac/Sparkle.framework/Versions/A/Headers/SUAppcast.h +++ /dev/null @@ -1,33 +0,0 @@ -// -// SUAppcast.h -// Sparkle -// -// Created by Andy Matuschak on 3/12/06. -// Copyright 2006 Andy Matuschak. All rights reserved. -// - -#ifndef SUAPPCAST_H -#define SUAPPCAST_H - -@class SUAppcastItem; -@interface SUAppcast : NSObject { - NSArray *items; - NSString *userAgentString; - id delegate; - NSMutableData *incrementalData; -} - -- (void)fetchAppcastFromURL:(NSURL *)url; -- (void)setDelegate:delegate; -- (void)setUserAgentString:(NSString *)userAgentString; - -- (NSArray *)items; - -@end - -@interface NSObject (SUAppcastDelegate) -- (void)appcastDidFinishLoading:(SUAppcast *)appcast; -- (void)appcast:(SUAppcast *)appcast failedToLoadWithError:(NSError *)error; -@end - -#endif diff --git a/Mac/Sparkle.framework/Versions/A/Headers/SUAppcastItem.h b/Mac/Sparkle.framework/Versions/A/Headers/SUAppcastItem.h deleted file mode 100644 index f2d128c..0000000 --- a/Mac/Sparkle.framework/Versions/A/Headers/SUAppcastItem.h +++ /dev/null @@ -1,47 +0,0 @@ -// -// SUAppcastItem.h -// Sparkle -// -// Created by Andy Matuschak on 3/12/06. -// Copyright 2006 Andy Matuschak. All rights reserved. -// - -#ifndef SUAPPCASTITEM_H -#define SUAPPCASTITEM_H - -@interface SUAppcastItem : NSObject { - NSString *title; - NSDate *date; - NSString *itemDescription; - - NSURL *releaseNotesURL; - - NSString *DSASignature; - NSString *minimumSystemVersion; - - NSURL *fileURL; - NSString *versionString; - NSString *displayVersionString; - - NSDictionary *propertiesDictionary; -} - -// Initializes with data from a dictionary provided by the RSS class. -- initWithDictionary:(NSDictionary *)dict; - -- (NSString *)title; -- (NSString *)versionString; -- (NSString *)displayVersionString; -- (NSDate *)date; -- (NSString *)itemDescription; -- (NSURL *)releaseNotesURL; -- (NSURL *)fileURL; -- (NSString *)DSASignature; -- (NSString *)minimumSystemVersion; - -// Returns the dictionary provided in initWithDictionary; this might be useful later for extensions. -- (NSDictionary *)propertiesDictionary; - -@end - -#endif diff --git a/Mac/Sparkle.framework/Versions/A/Headers/SUUpdater.h b/Mac/Sparkle.framework/Versions/A/Headers/SUUpdater.h deleted file mode 100644 index e5b5081..0000000 --- a/Mac/Sparkle.framework/Versions/A/Headers/SUUpdater.h +++ /dev/null @@ -1,118 +0,0 @@ -// -// SUUpdater.h -// Sparkle -// -// Created by Andy Matuschak on 1/4/06. -// Copyright 2006 Andy Matuschak. All rights reserved. -// - -#ifndef SUUPDATER_H -#define SUUPDATER_H - -#import - -@class SUUpdateDriver, SUAppcastItem, SUHost, SUAppcast; -@interface SUUpdater : NSObject { - NSTimer *checkTimer; - SUUpdateDriver *driver; - - SUHost *host; - IBOutlet id delegate; -} - -+ (SUUpdater *)sharedUpdater; -+ (SUUpdater *)updaterForBundle:(NSBundle *)bundle; -- (NSBundle *)hostBundle; - -- (void)setDelegate:(id)delegate; -- delegate; - -- (void)setAutomaticallyChecksForUpdates:(BOOL)automaticallyChecks; -- (BOOL)automaticallyChecksForUpdates; - -- (void)setUpdateCheckInterval:(NSTimeInterval)interval; -- (NSTimeInterval)updateCheckInterval; - -- (void)setFeedURL:(NSURL *)feedURL; -- (NSURL *)feedURL; - -- (void)setSendsSystemProfile:(BOOL)sendsSystemProfile; -- (BOOL)sendsSystemProfile; - -- (void)setAutomaticallyDownloadsUpdates:(BOOL)automaticallyDownloadsUpdates; -- (BOOL)automaticallyDownloadsUpdates; - -// This IBAction is meant for a main menu item. Hook up any menu item to this action, -// and Sparkle will check for updates and report back its findings verbosely. -- (IBAction)checkForUpdates:sender; - -// This kicks off an update meant to be programmatically initiated. That is, it will display no UI unless it actually finds an update, -// in which case it proceeds as usual. If the fully automated updating is turned on, however, this will invoke that behavior, and if an -// update is found, it will be downloaded and prepped for installation. -- (void)checkForUpdatesInBackground; - -// Date of last update check. Returns null if no check has been performed. -- (NSDate*)lastUpdateCheckDate; - -// This begins a "probing" check for updates which will not actually offer to update to that version. The delegate methods, though, -// (up to updater:didFindValidUpdate: and updaterDidNotFindUpdate:), are called, so you can use that information in your UI. -- (void)checkForUpdateInformation; - -// Call this to appropriately schedule or cancel the update checking timer according to the preferences for time interval and automatic checks. This call does not change the date of the next check, but only the internal NSTimer. -- (void)resetUpdateCycle; - -- (BOOL)updateInProgress; -@end - -@interface NSObject (SUUpdaterDelegateInformalProtocol) -// This method allows you to add extra parameters to the appcast URL, potentially based on whether or not Sparkle will also be sending along the system profile. This method should return an array of dictionaries with keys: "key", "value", "displayKey", "displayValue", the latter two being specifically for display to the user. -- (NSArray *)feedParametersForUpdater:(SUUpdater *)updater sendingSystemProfile:(BOOL)sendingProfile; - -// Use this to override the default behavior for Sparkle prompting the user about automatic update checks. -- (BOOL)updaterShouldPromptForPermissionToCheckForUpdates:(SUUpdater *)bundle; - -// Implement this if you want to do some special handling with the appcast once it finishes loading. -- (void)updater:(SUUpdater *)updater didFinishLoadingAppcast:(SUAppcast *)appcast; - -// If you're using special logic or extensions in your appcast, implement this to use your own logic for finding -// a valid update, if any, in the given appcast. -- (SUAppcastItem *)bestValidUpdateInAppcast:(SUAppcast *)appcast forUpdater:(SUUpdater *)bundle; - -// Sent when a valid update is found by the update driver. -- (void)updater:(SUUpdater *)updater didFindValidUpdate:(SUAppcastItem *)update; - -// Sent when a valid update is not found. -- (void)updaterDidNotFindUpdate:(SUUpdater *)update; - -// Sent immediately before installing the specified update. -- (void)updater:(SUUpdater *)updater willInstallUpdate:(SUAppcastItem *)update; - -// Return YES to delay the relaunch until you do some processing; invoke the given NSInvocation to continue. -- (BOOL)updater:(SUUpdater *)updater shouldPostponeRelaunchForUpdate:(SUAppcastItem *)update untilInvoking:(NSInvocation *)invocation; - -// Called immediately before relaunching. -- (void)updaterWillRelaunchApplication:(SUUpdater *)updater; - -// This method allows you to provide a custom version comparator. -// If you don't implement this method or return nil, the standard version comparator will be used. -- (id )versionComparatorForUpdater:(SUUpdater *)updater; - -// Returns the path which is used to relaunch the client after the update is installed. By default, the path of the host bundle. -- (NSString *)pathToRelaunchForUpdater:(SUUpdater *)updater; - -@end - -// Define some minimum intervals to avoid DOS-like checking attacks. These are in seconds. -#ifdef DEBUG -#define SU_MIN_CHECK_INTERVAL 60 -#else -#define SU_MIN_CHECK_INTERVAL 60*60 -#endif - -#ifdef DEBUG -#define SU_DEFAULT_CHECK_INTERVAL 60 -#else -#define SU_DEFAULT_CHECK_INTERVAL 60*60*24 -#endif - -#endif diff --git a/Mac/Sparkle.framework/Versions/A/Headers/SUVersionComparisonProtocol.h b/Mac/Sparkle.framework/Versions/A/Headers/SUVersionComparisonProtocol.h deleted file mode 100644 index d9ac619..0000000 --- a/Mac/Sparkle.framework/Versions/A/Headers/SUVersionComparisonProtocol.h +++ /dev/null @@ -1,27 +0,0 @@ -// -// SUVersionComparisonProtocol.h -// Sparkle -// -// Created by Andy Matuschak on 12/21/07. -// Copyright 2007 Andy Matuschak. All rights reserved. -// - -#ifndef SUVERSIONCOMPARISONPROTOCOL_H -#define SUVERSIONCOMPARISONPROTOCOL_H - -/*! - @protocol - @abstract Implement this protocol to provide version comparison facilities for Sparkle. -*/ -@protocol SUVersionComparison - -/*! - @method - @abstract An abstract method to compare two version strings. - @discussion Should return NSOrderedAscending if b > a, NSOrderedDescending if b < a, and NSOrderedSame if they are equivalent. -*/ -- (NSComparisonResult)compareVersion:(NSString *)versionA toVersion:(NSString *)versionB; - -@end - -#endif diff --git a/Mac/Sparkle.framework/Versions/A/Headers/Sparkle.h b/Mac/Sparkle.framework/Versions/A/Headers/Sparkle.h deleted file mode 100644 index 08dd577..0000000 --- a/Mac/Sparkle.framework/Versions/A/Headers/Sparkle.h +++ /dev/null @@ -1,21 +0,0 @@ -// -// Sparkle.h -// Sparkle -// -// Created by Andy Matuschak on 3/16/06. (Modified by CDHW on 23/12/07) -// Copyright 2006 Andy Matuschak. All rights reserved. -// - -#ifndef SPARKLE_H -#define SPARKLE_H - -// This list should include the shared headers. It doesn't matter if some of them aren't shared (unless -// there are name-space collisions) so we can list all of them to start with: - -#import - -#import -#import -#import - -#endif diff --git a/Mac/Sparkle.framework/Versions/A/Resources/Info.plist b/Mac/Sparkle.framework/Versions/A/Resources/Info.plist deleted file mode 100644 index c7f277d..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/Info.plist +++ /dev/null @@ -1,24 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - Sparkle - CFBundleIdentifier - org.andymatuschak.Sparkle - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - Sparkle - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.5 Beta 6 - CFBundleSignature - ???? - CFBundleVersion - 313 - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/License.txt b/Mac/Sparkle.framework/Versions/A/Resources/License.txt deleted file mode 100644 index 20466c4..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/License.txt +++ /dev/null @@ -1,7 +0,0 @@ -Copyright (c) 2006 Andy Matuschak - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/Mac/Sparkle.framework/Versions/A/Resources/SUModelTranslation.plist b/Mac/Sparkle.framework/Versions/A/Resources/SUModelTranslation.plist deleted file mode 100644 index 92ef947..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/SUModelTranslation.plist +++ /dev/null @@ -1,174 +0,0 @@ - - - - - ADP2,1 - Developer Transition Kit - MacBook1,1 - MacBook (Core Duo) - MacBook2,1 - MacBook (Core 2 Duo) - MacBook4,1 - MacBook (Core 2 Duo Feb 2008) - MacBookAir1,1 - MacBook Air (January 2008) - MacBookPro1,1 - MacBook Pro Core Duo (15-inch) - MacBookPro1,2 - MacBook Pro Core Duo (17-inch) - MacBookPro2,1 - MacBook Pro Core 2 Duo (17-inch) - MacBookPro2,2 - MacBook Pro Core 2 Duo (15-inch) - MacBookPro3,1 - MacBook Pro Core 2 Duo (15-inch LED, Core 2 Duo) - MacBookPro3,2 - MacBook Pro Core 2 Duo (17-inch HD, Core 2 Duo) - MacBookPro4,1 - MacBook Pro (Core 2 Duo Feb 2008) - MacPro1,1 - Mac Pro (four-core) - MacPro2,1 - Mac Pro (eight-core) - MacPro3,1 - Mac Pro (January 2008 4- or 8- core "Harpertown") - Macmini1,1 - Mac Mini (Core Solo/Duo) - PowerBook1,1 - PowerBook G3 - PowerBook2,1 - iBook G3 - PowerBook2,2 - iBook G3 (FireWire) - PowerBook2,3 - iBook G3 - PowerBook2,4 - iBook G3 - PowerBook3,1 - PowerBook G3 (FireWire) - PowerBook3,2 - PowerBook G4 - PowerBook3,3 - PowerBook G4 (Gigabit Ethernet) - PowerBook3,4 - PowerBook G4 (DVI) - PowerBook3,5 - PowerBook G4 (1GHz / 867MHz) - PowerBook4,1 - iBook G3 (Dual USB, Late 2001) - PowerBook4,2 - iBook G3 (16MB VRAM) - PowerBook4,3 - iBook G3 Opaque 16MB VRAM, 32MB VRAM, Early 2003) - PowerBook5,1 - PowerBook G4 (17 inch) - PowerBook5,2 - PowerBook G4 (15 inch FW 800) - PowerBook5,3 - PowerBook G4 (17-inch 1.33GHz) - PowerBook5,4 - PowerBook G4 (15 inch 1.5/1.33GHz) - PowerBook5,5 - PowerBook G4 (17-inch 1.5GHz) - PowerBook5,6 - PowerBook G4 (15 inch 1.67GHz/1.5GHz) - PowerBook5,7 - PowerBook G4 (17-inch 1.67GHz) - PowerBook5,8 - PowerBook G4 (Double layer SD, 15 inch) - PowerBook5,9 - PowerBook G4 (Double layer SD, 17 inch) - PowerBook6,1 - PowerBook G4 (12 inch) - PowerBook6,2 - PowerBook G4 (12 inch, DVI) - PowerBook6,3 - iBook G4 - PowerBook6,4 - PowerBook G4 (12 inch 1.33GHz) - PowerBook6,5 - iBook G4 (Early-Late 2004) - PowerBook6,7 - iBook G4 (Mid 2005) - PowerBook6,8 - PowerBook G4 (12 inch 1.5GHz) - PowerMac1,1 - Power Macintosh G3 (Blue & White) - PowerMac1,2 - Power Macintosh G4 (PCI Graphics) - PowerMac10,1 - Mac Mini G4 - PowerMac10,2 - Mac Mini (Late 2005) - PowerMac11,2 - Power Macintosh G5 (Late 2005) - PowerMac12,1 - iMac G5 (iSight) - PowerMac2,1 - iMac G3 (Slot-loading CD-ROM) - PowerMac2,2 - iMac G3 (Summer 2000) - PowerMac3,1 - Power Macintosh G4 (AGP Graphics) - PowerMac3,2 - Power Macintosh G4 (AGP Graphics) - PowerMac3,3 - Power Macintosh G4 (Gigabit Ethernet) - PowerMac3,4 - Power Macintosh G4 (Digital Audio) - PowerMac3,5 - Power Macintosh G4 (Quick Silver) - PowerMac3,6 - Power Macintosh G4 (Mirrored Drive Door) - PowerMac4,1 - iMac G3 (Early/Summer 2001) - PowerMac4,2 - iMac G4 (Flat Panel) - PowerMac4,4 - eMac - PowerMac4,5 - iMac G4 (17-inch Flat Panel) - PowerMac5,1 - Power Macintosh G4 Cube - PowerMac6,1 - iMac G4 (USB 2.0) - PowerMac6,3 - iMac G4 (20-inch Flat Panel) - PowerMac6,4 - eMac (USB 2.0, 2005) - PowerMac7,2 - Power Macintosh G5 - PowerMac7,3 - Power Macintosh G5 - PowerMac8,1 - iMac G5 - PowerMac8,2 - iMac G5 (Ambient Light Sensor) - PowerMac9,1 - Power Macintosh G5 (Late 2005) - RackMac1,1 - Xserve G4 - RackMac1,2 - Xserve G4 (slot-loading, cluster node) - RackMac3,1 - Xserve G5 - Xserve1,1 - Xserve (Intel Xeon) - Xserve2,1 - Xserve (January 2008 quad-core) - iMac1,1 - iMac G3 (Rev A-D) - iMac4,1 - iMac (Core Duo) - iMac4,2 - iMac for Education (17-inch, Core Duo) - iMac5,1 - iMac (Core 2 Duo, 17 or 20 inch, SuperDrive) - iMac5,2 - iMac (Core 2 Duo, 17 inch, Combo Drive) - iMac6,1 - iMac (Core 2 Duo, 24 inch, SuperDrive) - iMac8,1 - iMac (April 2008) - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/SUStatus.nib/classes.nib b/Mac/Sparkle.framework/Versions/A/Resources/SUStatus.nib/classes.nib deleted file mode 100644 index 22f13f8..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/SUStatus.nib/classes.nib +++ /dev/null @@ -1,56 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - CLASS - NSApplication - LANGUAGE - ObjC - SUPERCLASS - NSResponder - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - CLASS - SUStatusController - LANGUAGE - ObjC - OUTLETS - - actionButton - NSButton - progressBar - NSProgressIndicator - - SUPERCLASS - SUWindowController - - - IBVersion - 1 - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/SUStatus.nib/info.nib b/Mac/Sparkle.framework/Versions/A/Resources/SUStatus.nib/info.nib deleted file mode 100644 index a9ac867..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/SUStatus.nib/info.nib +++ /dev/null @@ -1,20 +0,0 @@ - - - - - IBFramework Version - 670 - IBLastKnownRelativeProjectPath - Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - 6 - - IBSystem Version - 10A96 - targetFramework - IBCocoaFramework - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/SUStatus.nib/keyedobjects.nib b/Mac/Sparkle.framework/Versions/A/Resources/SUStatus.nib/keyedobjects.nib deleted file mode 100644 index 4f1d598..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/SUStatus.nib/keyedobjects.nib and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/classes.nib b/Mac/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/classes.nib deleted file mode 100644 index 4b1ab30..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,50 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - ACTIONS - - doNotInstall - id - installLater - id - installNow - id - - CLASS - SUAutomaticUpdateAlert - LANGUAGE - ObjC - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/info.nib b/Mac/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/info.nib deleted file mode 100644 index 2e04cfa..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/info.nib +++ /dev/null @@ -1,20 +0,0 @@ - - - - - IBFramework Version - 667 - IBLastKnownRelativeProjectPath - ../Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - 6 - - IBSystem Version - 9D34 - targetFramework - IBCocoaFramework - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib b/Mac/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index 6b92630..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/classes.nib b/Mac/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/classes.nib deleted file mode 100644 index 994d4c3..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,67 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - CLASS - NSApplication - LANGUAGE - ObjC - SUPERCLASS - NSResponder - - - ACTIONS - - installUpdate - id - remindMeLater - id - skipThisVersion - id - - CLASS - SUUpdateAlert - LANGUAGE - ObjC - OUTLETS - - delegate - id - description - NSTextField - releaseNotesView - WebView - - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/info.nib b/Mac/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/info.nib deleted file mode 100644 index 2e04cfa..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/info.nib +++ /dev/null @@ -1,20 +0,0 @@ - - - - - IBFramework Version - 667 - IBLastKnownRelativeProjectPath - ../Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - 6 - - IBSystem Version - 9D34 - targetFramework - IBCocoaFramework - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/keyedobjects.nib b/Mac/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index b4353d2..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/classes.nib b/Mac/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/classes.nib deleted file mode 100644 index 5220a22..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/classes.nib +++ /dev/null @@ -1,59 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - ACTIONS - - finishPrompt - id - toggleMoreInfo - id - - CLASS - SUUpdatePermissionPrompt - LANGUAGE - ObjC - OUTLETS - - delegate - id - descriptionTextField - NSTextField - moreInfoButton - NSButton - moreInfoView - NSView - - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/info.nib b/Mac/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/info.nib deleted file mode 100644 index 2e04cfa..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/info.nib +++ /dev/null @@ -1,20 +0,0 @@ - - - - - IBFramework Version - 667 - IBLastKnownRelativeProjectPath - ../Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - 6 - - IBSystem Version - 9D34 - targetFramework - IBCocoaFramework - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib b/Mac/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib deleted file mode 100644 index b403a3e..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings b/Mac/Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings deleted file mode 100644 index b31f928..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/classes.nib b/Mac/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/classes.nib deleted file mode 100644 index 4b1ab30..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,50 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - ACTIONS - - doNotInstall - id - installLater - id - installNow - id - - CLASS - SUAutomaticUpdateAlert - LANGUAGE - ObjC - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/info.nib b/Mac/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/info.nib deleted file mode 100644 index ab36d31..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/info.nib +++ /dev/null @@ -1,20 +0,0 @@ - - - - - IBFramework Version - 658 - IBLastKnownRelativeProjectPath - ../Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - 6 - - IBSystem Version - 9C7010 - targetFramework - IBCocoaFramework - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib b/Mac/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index 7630390..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/classes.nib b/Mac/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/classes.nib deleted file mode 100644 index 994d4c3..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,67 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - CLASS - NSApplication - LANGUAGE - ObjC - SUPERCLASS - NSResponder - - - ACTIONS - - installUpdate - id - remindMeLater - id - skipThisVersion - id - - CLASS - SUUpdateAlert - LANGUAGE - ObjC - OUTLETS - - delegate - id - description - NSTextField - releaseNotesView - WebView - - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/info.nib b/Mac/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/info.nib deleted file mode 100644 index 2fb8a83..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/info.nib +++ /dev/null @@ -1,20 +0,0 @@ - - - - - IBFramework Version - 670 - IBLastKnownRelativeProjectPath - ../Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - 18 - - IBSystem Version - 10A96 - targetFramework - IBCocoaFramework - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/keyedobjects.nib b/Mac/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index e7e7497..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/classes.nib b/Mac/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/classes.nib deleted file mode 100644 index 5220a22..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/classes.nib +++ /dev/null @@ -1,59 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - ACTIONS - - finishPrompt - id - toggleMoreInfo - id - - CLASS - SUUpdatePermissionPrompt - LANGUAGE - ObjC - OUTLETS - - delegate - id - descriptionTextField - NSTextField - moreInfoButton - NSButton - moreInfoView - NSView - - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/info.nib b/Mac/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/info.nib deleted file mode 100644 index b1cd28e..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/info.nib +++ /dev/null @@ -1,21 +0,0 @@ - - - - - IBFramework Version - 670 - IBLastKnownRelativeProjectPath - ../Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - 6 - 41 - - IBSystem Version - 10A96 - targetFramework - IBCocoaFramework - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib b/Mac/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib deleted file mode 100644 index e8dc5b8..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings b/Mac/Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings deleted file mode 100644 index 16e0787..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/classes.nib b/Mac/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/classes.nib deleted file mode 100644 index 4b1ab30..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,50 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - ACTIONS - - doNotInstall - id - installLater - id - installNow - id - - CLASS - SUAutomaticUpdateAlert - LANGUAGE - ObjC - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/info.nib b/Mac/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/info.nib deleted file mode 100644 index 2e04cfa..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/info.nib +++ /dev/null @@ -1,20 +0,0 @@ - - - - - IBFramework Version - 667 - IBLastKnownRelativeProjectPath - ../Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - 6 - - IBSystem Version - 9D34 - targetFramework - IBCocoaFramework - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib b/Mac/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index 6b2f938..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/classes.nib b/Mac/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/classes.nib deleted file mode 100644 index 994d4c3..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,67 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - CLASS - NSApplication - LANGUAGE - ObjC - SUPERCLASS - NSResponder - - - ACTIONS - - installUpdate - id - remindMeLater - id - skipThisVersion - id - - CLASS - SUUpdateAlert - LANGUAGE - ObjC - OUTLETS - - delegate - id - description - NSTextField - releaseNotesView - WebView - - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/info.nib b/Mac/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/info.nib deleted file mode 100644 index 2e04cfa..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/info.nib +++ /dev/null @@ -1,20 +0,0 @@ - - - - - IBFramework Version - 667 - IBLastKnownRelativeProjectPath - ../Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - 6 - - IBSystem Version - 9D34 - targetFramework - IBCocoaFramework - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/keyedobjects.nib b/Mac/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index c9b1e7d..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/classes.nib b/Mac/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/classes.nib deleted file mode 100644 index 5220a22..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/classes.nib +++ /dev/null @@ -1,59 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - ACTIONS - - finishPrompt - id - toggleMoreInfo - id - - CLASS - SUUpdatePermissionPrompt - LANGUAGE - ObjC - OUTLETS - - delegate - id - descriptionTextField - NSTextField - moreInfoButton - NSButton - moreInfoView - NSView - - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/info.nib b/Mac/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/info.nib deleted file mode 100644 index 3eb7f81..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/info.nib +++ /dev/null @@ -1,20 +0,0 @@ - - - - - IBFramework Version - 667 - IBLastKnownRelativeProjectPath - ../../Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - 6 - - IBSystem Version - 9D34 - targetFramework - IBCocoaFramework - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib b/Mac/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib deleted file mode 100644 index 8c54c21..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings b/Mac/Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings deleted file mode 100644 index f83ea23..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/classes.nib b/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/classes.nib deleted file mode 100644 index 4b1ab30..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,50 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - ACTIONS - - doNotInstall - id - installLater - id - installNow - id - - CLASS - SUAutomaticUpdateAlert - LANGUAGE - ObjC - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/info.nib b/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/info.nib deleted file mode 100644 index 33a6020..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/info.nib +++ /dev/null @@ -1,16 +0,0 @@ - - - - - IBFramework Version - 629 - IBOldestOS - 5 - IBOpenObjects - - IBSystem Version - 9D34 - targetFramework - IBCocoaFramework - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib b/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index 4cd529a..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/classes.nib b/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/classes.nib deleted file mode 100644 index 994d4c3..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,67 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - CLASS - NSApplication - LANGUAGE - ObjC - SUPERCLASS - NSResponder - - - ACTIONS - - installUpdate - id - remindMeLater - id - skipThisVersion - id - - CLASS - SUUpdateAlert - LANGUAGE - ObjC - OUTLETS - - delegate - id - description - NSTextField - releaseNotesView - WebView - - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/info.nib b/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/info.nib deleted file mode 100644 index d2586ea..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/info.nib +++ /dev/null @@ -1,16 +0,0 @@ - - - - - IBFramework Version - 629 - IBOldestOS - 5 - IBOpenObjects - - IBSystem Version - 9E17 - targetFramework - IBCocoaFramework - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/keyedobjects.nib b/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index 65dfc95..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/classes.nib b/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/classes.nib deleted file mode 100644 index 5220a22..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/classes.nib +++ /dev/null @@ -1,59 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - ACTIONS - - finishPrompt - id - toggleMoreInfo - id - - CLASS - SUUpdatePermissionPrompt - LANGUAGE - ObjC - OUTLETS - - delegate - id - descriptionTextField - NSTextField - moreInfoButton - NSButton - moreInfoView - NSView - - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/info.nib b/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/info.nib deleted file mode 100644 index d2586ea..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/info.nib +++ /dev/null @@ -1,16 +0,0 @@ - - - - - IBFramework Version - 629 - IBOldestOS - 5 - IBOpenObjects - - IBSystem Version - 9E17 - targetFramework - IBCocoaFramework - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib b/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib deleted file mode 100644 index 4b7cc90..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings b/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings deleted file mode 100644 index ea175ae..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/fr.lproj b/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/fr.lproj deleted file mode 120000 index 88614fe..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/fr.lproj/fr.lproj +++ /dev/null @@ -1 +0,0 @@ -/Users/andym/Development/Build Products/Release/Sparkle.framework/Resources/fr.lproj \ No newline at end of file diff --git a/Mac/Sparkle.framework/Versions/A/Resources/fr_CA.lproj b/Mac/Sparkle.framework/Versions/A/Resources/fr_CA.lproj deleted file mode 120000 index 88614fe..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/fr_CA.lproj +++ /dev/null @@ -1 +0,0 @@ -/Users/andym/Development/Build Products/Release/Sparkle.framework/Resources/fr.lproj \ No newline at end of file diff --git a/Mac/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/classes.nib b/Mac/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/classes.nib deleted file mode 100644 index 4b1ab30..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,50 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - ACTIONS - - doNotInstall - id - installLater - id - installNow - id - - CLASS - SUAutomaticUpdateAlert - LANGUAGE - ObjC - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/info.nib b/Mac/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/info.nib deleted file mode 100644 index 2e04cfa..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/info.nib +++ /dev/null @@ -1,20 +0,0 @@ - - - - - IBFramework Version - 667 - IBLastKnownRelativeProjectPath - ../Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - 6 - - IBSystem Version - 9D34 - targetFramework - IBCocoaFramework - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib b/Mac/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index 15ba8f4..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/classes.nib b/Mac/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/classes.nib deleted file mode 100644 index 994d4c3..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,67 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - CLASS - NSApplication - LANGUAGE - ObjC - SUPERCLASS - NSResponder - - - ACTIONS - - installUpdate - id - remindMeLater - id - skipThisVersion - id - - CLASS - SUUpdateAlert - LANGUAGE - ObjC - OUTLETS - - delegate - id - description - NSTextField - releaseNotesView - WebView - - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/info.nib b/Mac/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/info.nib deleted file mode 100644 index 2e04cfa..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/info.nib +++ /dev/null @@ -1,20 +0,0 @@ - - - - - IBFramework Version - 667 - IBLastKnownRelativeProjectPath - ../Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - 6 - - IBSystem Version - 9D34 - targetFramework - IBCocoaFramework - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/keyedobjects.nib b/Mac/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index 2984064..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/classes.nib b/Mac/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/classes.nib deleted file mode 100644 index 5220a22..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/classes.nib +++ /dev/null @@ -1,59 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - ACTIONS - - finishPrompt - id - toggleMoreInfo - id - - CLASS - SUUpdatePermissionPrompt - LANGUAGE - ObjC - OUTLETS - - delegate - id - descriptionTextField - NSTextField - moreInfoButton - NSButton - moreInfoView - NSView - - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/info.nib b/Mac/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/info.nib deleted file mode 100644 index c493485..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/info.nib +++ /dev/null @@ -1,20 +0,0 @@ - - - - - IBFramework Version - 667 - IBLastKnownRelativeProjectPath - ../Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - 5 - - IBSystem Version - 9D34 - targetFramework - IBCocoaFramework - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib b/Mac/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib deleted file mode 100644 index 55cc2c2..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings b/Mac/Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings deleted file mode 100644 index 5c410d0..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/classes.nib b/Mac/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/classes.nib deleted file mode 100644 index 4b1ab30..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,50 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - ACTIONS - - doNotInstall - id - installLater - id - installNow - id - - CLASS - SUAutomaticUpdateAlert - LANGUAGE - ObjC - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/info.nib b/Mac/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/info.nib deleted file mode 100644 index 3f09790..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/info.nib +++ /dev/null @@ -1,18 +0,0 @@ - - - - - IBFramework Version - 629 - IBOldestOS - 5 - IBOpenObjects - - 6 - - IBSystem Version - 9D34 - targetFramework - IBCocoaFramework - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib b/Mac/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index aa38f86..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/classes.nib b/Mac/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/classes.nib deleted file mode 100644 index 994d4c3..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,67 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - CLASS - NSApplication - LANGUAGE - ObjC - SUPERCLASS - NSResponder - - - ACTIONS - - installUpdate - id - remindMeLater - id - skipThisVersion - id - - CLASS - SUUpdateAlert - LANGUAGE - ObjC - OUTLETS - - delegate - id - description - NSTextField - releaseNotesView - WebView - - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/info.nib b/Mac/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/info.nib deleted file mode 100644 index d2586ea..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/info.nib +++ /dev/null @@ -1,16 +0,0 @@ - - - - - IBFramework Version - 629 - IBOldestOS - 5 - IBOpenObjects - - IBSystem Version - 9E17 - targetFramework - IBCocoaFramework - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/keyedobjects.nib b/Mac/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index c82d358..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/classes.nib b/Mac/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/classes.nib deleted file mode 100644 index 5220a22..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/classes.nib +++ /dev/null @@ -1,59 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - ACTIONS - - finishPrompt - id - toggleMoreInfo - id - - CLASS - SUUpdatePermissionPrompt - LANGUAGE - ObjC - OUTLETS - - delegate - id - descriptionTextField - NSTextField - moreInfoButton - NSButton - moreInfoView - NSView - - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/info.nib b/Mac/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/info.nib deleted file mode 100644 index d2586ea..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/info.nib +++ /dev/null @@ -1,16 +0,0 @@ - - - - - IBFramework Version - 629 - IBOldestOS - 5 - IBOpenObjects - - IBSystem Version - 9E17 - targetFramework - IBCocoaFramework - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib b/Mac/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib deleted file mode 100644 index ac298ce..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings b/Mac/Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings deleted file mode 100644 index 67cf535..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/relaunch b/Mac/Sparkle.framework/Versions/A/Resources/relaunch deleted file mode 100755 index e7b96d6..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/relaunch and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/classes.nib b/Mac/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/classes.nib deleted file mode 100644 index 4b1ab30..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,50 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - ACTIONS - - doNotInstall - id - installLater - id - installNow - id - - CLASS - SUAutomaticUpdateAlert - LANGUAGE - ObjC - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/info.nib b/Mac/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/info.nib deleted file mode 100644 index 2b3d425..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/info.nib +++ /dev/null @@ -1,20 +0,0 @@ - - - - - IBFramework Version - 670 - IBLastKnownRelativeProjectPath - ../Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - 6 - - IBSystem Version - 9E17 - targetFramework - IBCocoaFramework - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib b/Mac/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index 1d4655c..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/classes.nib b/Mac/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/classes.nib deleted file mode 100644 index 994d4c3..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,67 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - CLASS - NSApplication - LANGUAGE - ObjC - SUPERCLASS - NSResponder - - - ACTIONS - - installUpdate - id - remindMeLater - id - skipThisVersion - id - - CLASS - SUUpdateAlert - LANGUAGE - ObjC - OUTLETS - - delegate - id - description - NSTextField - releaseNotesView - WebView - - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/info.nib b/Mac/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/info.nib deleted file mode 100644 index 2b3d425..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/info.nib +++ /dev/null @@ -1,20 +0,0 @@ - - - - - IBFramework Version - 670 - IBLastKnownRelativeProjectPath - ../Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - 6 - - IBSystem Version - 9E17 - targetFramework - IBCocoaFramework - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/keyedobjects.nib b/Mac/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index 103b1cf..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/classes.nib b/Mac/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/classes.nib deleted file mode 100644 index 0f776c8..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/classes.nib +++ /dev/null @@ -1,59 +0,0 @@ - - - - - IBClasses - - - CLASS - NSObject - LANGUAGE - ObjC - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - ACTIONS - - finishPrompt - id - toggleMoreInfo - id - - CLASS - SUUpdatePermissionPrompt - LANGUAGE - ObjC - OUTLETS - - delegate - id - descriptionTextField - NSTextField - moreInfoButton - NSButton - moreInfoView - NSView - - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - IBVersion - 1 - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/info.nib b/Mac/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/info.nib deleted file mode 100644 index 5132e29..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/info.nib +++ /dev/null @@ -1,18 +0,0 @@ - - - - - IBFramework Version - 670 - IBLastKnownRelativeProjectPath - ../Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - IBSystem Version - 9E17 - targetFramework - IBCocoaFramework - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib b/Mac/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib deleted file mode 100644 index c09d9e7..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings b/Mac/Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings deleted file mode 100644 index f3ff9d8..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/classes.nib b/Mac/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/classes.nib deleted file mode 100644 index 4b1ab30..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,50 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - ACTIONS - - doNotInstall - id - installLater - id - installNow - id - - CLASS - SUAutomaticUpdateAlert - LANGUAGE - ObjC - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/info.nib b/Mac/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/info.nib deleted file mode 100644 index c5a067e..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/info.nib +++ /dev/null @@ -1,20 +0,0 @@ - - - - - IBFramework Version - 670 - IBLastKnownRelativeProjectPath - ../Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - 6 - - IBSystem Version - 10A96 - targetFramework - IBCocoaFramework - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib b/Mac/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index 53cb91a..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/classes.nib b/Mac/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/classes.nib deleted file mode 100644 index 018710a..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/classes.nib +++ /dev/null @@ -1,39 +0,0 @@ -{ - IBClasses = ( - { - CLASS = FirstResponder; - LANGUAGE = ObjC; - SUPERCLASS = NSObject; - }, - { - CLASS = NSApplication; - LANGUAGE = ObjC; - SUPERCLASS = NSResponder; - }, - { - CLASS = NSObject; - LANGUAGE = ObjC; - }, - { - ACTIONS = { - installUpdate = id; - remindMeLater = id; - skipThisVersion = id; - }; - CLASS = SUUpdateAlert; - LANGUAGE = ObjC; - OUTLETS = { - delegate = id; - description = NSTextField; - releaseNotesView = WebView; - }; - SUPERCLASS = SUWindowController; - }, - { - CLASS = SUWindowController; - LANGUAGE = ObjC; - SUPERCLASS = NSWindowController; - } - ); - IBVersion = 1; -} \ No newline at end of file diff --git a/Mac/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/info.nib b/Mac/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/info.nib deleted file mode 100644 index 6b787d4..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/info.nib +++ /dev/null @@ -1,18 +0,0 @@ - - - - - IBDocumentLocation - 69 14 356 240 0 0 1280 778 - IBFramework Version - 489.0 - IBLastKnownRelativeProjectPath - ../Sparkle.xcodeproj - IBOldestOS - 5 - IBSystem Version - 9D34 - targetFramework - IBCocoaFramework - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/keyedobjects.nib b/Mac/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/keyedobjects.nib deleted file mode 100644 index 7e6d490..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/keyedobjects.nib and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/classes.nib b/Mac/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/classes.nib deleted file mode 100644 index 5220a22..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/classes.nib +++ /dev/null @@ -1,59 +0,0 @@ - - - - - IBClasses - - - CLASS - SUWindowController - LANGUAGE - ObjC - SUPERCLASS - NSWindowController - - - ACTIONS - - finishPrompt - id - toggleMoreInfo - id - - CLASS - SUUpdatePermissionPrompt - LANGUAGE - ObjC - OUTLETS - - delegate - id - descriptionTextField - NSTextField - moreInfoButton - NSButton - moreInfoView - NSView - - SUPERCLASS - SUWindowController - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/info.nib b/Mac/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/info.nib deleted file mode 100644 index c5a067e..0000000 --- a/Mac/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/info.nib +++ /dev/null @@ -1,20 +0,0 @@ - - - - - IBFramework Version - 670 - IBLastKnownRelativeProjectPath - ../Sparkle.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - 6 - - IBSystem Version - 10A96 - targetFramework - IBCocoaFramework - - diff --git a/Mac/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib b/Mac/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib deleted file mode 100644 index 64babac..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings b/Mac/Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings deleted file mode 100644 index b676a4f..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/A/Sparkle b/Mac/Sparkle.framework/Versions/A/Sparkle deleted file mode 100755 index 0db0a8f..0000000 Binary files a/Mac/Sparkle.framework/Versions/A/Sparkle and /dev/null differ diff --git a/Mac/Sparkle.framework/Versions/Current b/Mac/Sparkle.framework/Versions/Current deleted file mode 120000 index 8c7e5a6..0000000 --- a/Mac/Sparkle.framework/Versions/Current +++ /dev/null @@ -1 +0,0 @@ -A \ No newline at end of file diff --git a/Mac/TB_SendTemplate.png b/Mac/TB_SendTemplate.png deleted file mode 100644 index b2602fe..0000000 Binary files a/Mac/TB_SendTemplate.png and /dev/null differ diff --git a/Mac/ViewDelegate.h b/Mac/ViewDelegate.h deleted file mode 100644 index 7e3cb80..0000000 --- a/Mac/ViewDelegate.h +++ /dev/null @@ -1,27 +0,0 @@ -// -// ViewDelegate.h -// bungloo -// -// Created by Jeena on 15.04.10. -// Licence: BSD (see attached LICENCE.txt file). -// - -#import -#import -#import "Constants.h" - -@interface ViewDelegate : NSObject { - WebView *timelineView; - WebView *mentionsView; - WebView *conversationView; - WebView *profileView; - WebView *oauthView; -} - -@property (nonatomic, assign) WebView *timelineView; -@property (nonatomic, assign) WebView *mentionsView; -@property (nonatomic, assign) WebView *conversationView; -@property (nonatomic, assign) WebView *profileView; -@property (nonatomic, assign) WebView *oauthView; - -@end diff --git a/Mac/ViewDelegate.m b/Mac/ViewDelegate.m deleted file mode 100644 index c49b7b2..0000000 --- a/Mac/ViewDelegate.m +++ /dev/null @@ -1,145 +0,0 @@ -// -// ViewDelegate.m -// bungloo -// -// Created by Jeena on 15.04.10. -// Licence: BSD (see attached LICENCE.txt file). -// - -#import "ViewDelegate.h" - - -@implementation ViewDelegate - -@synthesize timelineView, mentionsView, conversationView, profileView, oauthView; - -- (void)webView:(WebView *)sender addMessageToConsole:(NSDictionary *)message { - - if (![message isKindOfClass:[NSDictionary class]]) return; - - NSString *viewName = @"TimelineView"; - if (sender == mentionsView) viewName = @"MentionsView"; - if (sender == conversationView) viewName = @"ConversationView"; - if (sender == oauthView) viewName = @"OauthView"; - if (sender == profileView) viewName = @"ProfileView"; - - NSLog(@"js<%@>: %@:%@: %@", - viewName, - [[message objectForKey:@"sourceURL"] lastPathComponent], - [message objectForKey:@"lineNumber"], - [message objectForKey:@"message"] - ); -} - -- (void)webView:(WebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame { - NSString *viewName = @"TimelineView"; - if (sender == mentionsView) viewName = @"MentionsView"; - if (sender == conversationView) viewName = @"ConversationView"; - if (sender == oauthView) viewName = @"OauthView"; - - NSLog(@"jsa<%@>: %@", viewName, message); -} - -- (BOOL)webView:(WebView *)sender runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame { - NSInteger result = NSRunCriticalAlertPanel(NSLocalizedString(@"Bungloo", @""), // title - message, // message - NSLocalizedString(@"OK", @""), // default button - NSLocalizedString(@"Cancel", @""), // alt button - nil); - return NSAlertDefaultReturn == result; - return NO; -} - -- (void)webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id )listener { - - NSArray *frames = [NSArray arrayWithObjects:timelineView.mainFrame, mentionsView.mainFrame, conversationView.mainFrame, oauthView.mainFrame, profileView.mainFrame, nil]; - - // If it is clicked from one of the views the open default browser - if ([frames indexOfObject:frame] != NSNotFound) { - [listener ignore]; - [[NSWorkspace sharedWorkspace] openURL:[request URL]]; - } else { // otherwies load the iframe stuff like YouTube or vimeo - [listener use]; - } -} - -- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame { - - NSFileManager *fileManager = [NSFileManager defaultManager]; - NSString *pathToJsPlugin = [@"~/Library/Application Support/bungloo/Plugin.js" stringByExpandingTildeInPath]; - NSString *pathToCssPlugin = [@"~/Library/Application Support/bungloo/Plugin.css" stringByExpandingTildeInPath]; - - if([fileManager fileExistsAtPath:pathToCssPlugin]) - { - [sender stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"setTimeout(function() { loadCssPlugin('file://localhost%@') }, 1000);", pathToCssPlugin]]; - } - - if([fileManager fileExistsAtPath:pathToJsPlugin]) - { - [sender stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"setTimeout(function() { loadJsPlugin('file://localhost%@') }, 1000);", pathToJsPlugin]]; - } - - [sender stringByEvaluatingJavaScriptFromString:@"var OS_TYPE = 'mac';"]; - - if (sender == oauthView) { - - [oauthView stringByEvaluatingJavaScriptFromString:@"function HostAppGo() { start('oauth') }"]; - - } else if(sender == conversationView) { - - [conversationView stringByEvaluatingJavaScriptFromString:@"function HostAppGo() { start('conversation') }"]; - - } else if(sender == profileView) { - - [profileView stringByEvaluatingJavaScriptFromString:@"function HostAppGo() { start('profile') }"]; - - } else { - - NSString *action = @"timeline"; - NSString *delay = @"1"; - - if (sender == mentionsView) { - action = @"mentions"; - delay = @"1000"; - } - - [sender stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"function HostAppGo() { start('%@') }", action]]; - } -} - -- (NSArray *)webView:(WebView *)sender contextMenuItemsForElement:(NSDictionary *)element defaultMenuItems:(NSArray *)defaultMenuItems -{ - // FIXME - /* - NSMutableArray *menuItems = [NSMutableArray arrayWithArray:defaultMenuItems]; - - for (NSMenuItem*item in defaultMenuItems) { - if ([[item title] isEqualToString:@"Reload"]) { - //[item setAction:@selector(reload:)]; - //[item setTarget:self]; - } else { - [menuItems addObject:item]; - } - }*/ - - return defaultMenuItems; -} - -- (void)reload:(id)sender { - [timelineView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.getNewData();"]; - [mentionsView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.getNewData();"]; -} - -- (NSString *)pluginURL -{ - NSFileManager *fileManager = [NSFileManager defaultManager]; - NSString *pathToPlugin = [@"~/Library/Application Support/Bungloo/Plugin.js" stringByExpandingTildeInPath]; - - if([fileManager fileExistsAtPath:pathToPlugin]) - { - return [NSString stringWithFormat:@"%@", [NSURL fileURLWithPath:pathToPlugin]]; - } - return nil; -} - -@end diff --git a/Mac/deploy.sh b/Mac/deploy.sh new file mode 100755 index 0000000..44841e9 --- /dev/null +++ b/Mac/deploy.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +HERE=`pwd` +TMP="/tmp" + +rm -rf Bungloo.app +rm -rf $TMP/bungloo +mkdir $TMP/bungloo +cp -r ../Qt/* $TMP/bungloo +cp -r ../WebKit $TMP/bungloo +cp -r ../images $TMP/bungloo +cp Icon.icns $TMP/bungloo/images +cp setup.py $TMP/bungloo +cp Info.plist $TMP/bungloo +cd $TMP/bungloo +python setup.py py2app +mv $TMP/bungloo/dist/Bungloo.app $HERE +cd $HERE +rm -rf $TMP/bungloo +Bungloo.app/Contents/MacOS/Bungloo \ No newline at end of file diff --git a/Mac/main.m b/Mac/main.m deleted file mode 100644 index 75ec058..0000000 --- a/Mac/main.m +++ /dev/null @@ -1,14 +0,0 @@ -// -// main.m -// bungloo -// -// Created by Jeena on 16.04.10. -// Licence: BSD (see attached LICENCE.txt file). -// - -#import - -int main(int argc, char *argv[]) -{ - return NSApplicationMain(argc, (const char **) argv); -} diff --git a/Mac/publish/Appcast.xml b/Mac/publish/Appcast.xml deleted file mode 100755 index 548fc83..0000000 --- a/Mac/publish/Appcast.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - Bungloo's Changelog - http://jabs.nu/Bungloo/download/Appcast.xml - Most recent changes with links to updates. - en - - Version 1.1.0 - 10.5.0 - http://jabs.nu/bungloo/download/ReleaseNotes.html - Mon, 18 Feb 2013 11:33:48 +0100 - - - - diff --git a/Mac/publish/ReleaseNotes.html b/Mac/publish/ReleaseNotes.html deleted file mode 100644 index 4934529..0000000 --- a/Mac/publish/ReleaseNotes.html +++ /dev/null @@ -1,225 +0,0 @@ - - - - Tentia Release Notes - - - - -

Bungloo 1.2.0

- -

Inline video for YouTube and Vimeo + inline sound for SoundCloud, sadly some buttons in the widgets still don't work but you can watch the videos and hear the music :)

-

Better handling of non square avatars

-

Bugfixes, now loading more profiles correctly

-

Multiple mentions now are added behind a /cc while responding

-

Bugfix, better handling of - in entities

- -
- -

Bungloo 1.1.0

- -

Moved time ago so it is always visible

-

Implemented thumbnails for linked images and videos

-

Added a map to posts with position

-

Links now are only linked if they start with http

-

Smaller bugfixes

- -
- -

Bungloo 1.0.0

- -

Automatic updade doesn't work, please download Bungloo from here: Bungloo.app.zip and then remove the old Tentia from your Applications directory.

-

Renamed the application from Tentia to Bungloo as proposed by ^nn.tent.is - (Thank you for that!). Watch OfficeHours 2013-01-22 - if you want to know why it needed to be renamed

-

Added new icon by http://www.fasticon.com

-

Smaller bugfixes

-

Allowing empty text if location or image is present

-

Changed the look of names

-

Shows in profile if entity is following you

-

Added "follows since 'timeago'" to following/followers lists, thanks for the - pullrequest ^nn.tent.is

-

Temporarily highlights a reposted post

- - -
- -

Tentia 0.6.2

- -

Added possibility to show followings and followers to profile view. Just click on the number.

- -
- -

Tentia 0.6.1

- -

Removed shaddows from posts like discussed with ^kevinkleinman.tent.is, more UI changes to come

-

Thanks to ^nn.tent.is for fixing the bug which would send on Cmd+something

-

Smaller bugfixes.

- -
- -

Tentia 0.6.0

- -

Reposts are now collected

-

Open profile is now Cmd U

-

Sending mentions read cursor, therefor you need to reauthenticate

-

Fixed entity detection which contain dot at the end

-

Profiles with no name are linked now

-

Using open street map now when clicking on the pin

- -
- -

Tentia 0.5.4

- -

Fixed critical bug which prevented finding mentions in text

- -
- -

Tentia 0.5.3

- -

Fixed problem where deleted posts weren't removed from Mentions

-

Fixed problem with localStorage on 10.7

-

Showind photos now on the profile

-

Smaller bugfixes

- -
- -

Tentia 0.5.2

- -

Click on avatar opens profile

-

Added possibility to post photos (not available on basic tent.is plan)

-

Bugfixes

-

Changed app name to "Tentia on OS X", therefor you need to reauthenticate.

- -
- -

Tentia 0.5.1

- -

Implemented private posts

-

Implemented cache

-

Support for HTML <link> element

-

Clicking on dock icon opens main window

-

Fixed conversation view loading posts

-

Repost is now mentioning the original post

-

Several bugfixes

- -
- -

Tentia 0.5.0

- -

Added "Send" button to "New Post" window

-

Added Profile view

-

Added follow and unfollow possibility

- -
- -

Tentia 0.4.2

- -

Removed Photo post type because the Tent protocol in version 0.1.0 does not quite support it yet

-

Implemented showing and making reposts

- -
- -

Tentia 0.4.1

- -

Fixed problem where you couldn't log in again after you logged out.

- -
- -

Tentia 0.4.0

- -

Implemented Photo post type, you can now upload a photo and see the photos others uploaded

- -
- -

Tentia 0.3.1

- -

Security update

-

Thanks to ^epirat.tent.is the secret key is now saved in the OS X Keychain instead of the NSUserDefaults file

- -
- -

Tentia 0.3.0

- -

Implemented delete own posts

-

Implemented remove deleted posts

-

Added a JS and CSS Plugin API

-

Implemented adding location to post

-

Implemented blue right border if you're mentioned in a post

-

Bugfixes

- -
- -

Tentia 0.2.4

- -

Activeted spell checking

-

Fixed problem where Tentia would stop updating

-

Added a better detection of links in status texts

-

Hashed are linked to skate.io now

- -
- -

Tentia 0.2.3

- -

Fixed problem where you couldn't login with a https entity

-

Moved Mentions and Timeline from File to Window menu item

- -
- -

Tentia 0.2.2

- -

Resizable "New Post" window

-

Better authentication guidance

-

Fixed broken Window menu

-

Enter now works in "Nes Post" and is visible in all views

-

Bugfixes

- -
- -

Tentia 0.2.1

- -

Sadly the automatic update from 0.2.0 will not work. Please download - this version manually from - HERE.

-

Working on OS X < 10.8 again

-

Added growl support

-

Bugfixes

-

Moved reply icon to left so it is easier to use when the scrollbar is shown

-

Login with the [Login] button now works

-

Fixed automatic updates so it will work next time again.

- -
- -

Tentia 0.2.0

- -

Bugfixes

-

Implemented Notification Center

-

Implemented new Conversation view

-

Needs to reauthenticate to get all needed permissions

- -
- -

Tentia 0.1.2

-

Bugfixes

-

Mentions now appear as realnames

- -
- -

Tentia 0.1.1

-

Bugfixes

-

Changed to send on Cmd+Enter.

- -
- -

Tentia 0.1.0

-

First attempt to rewrite the old Twitter client Twittia to a new and shiny Tent client Tentia.

- - - \ No newline at end of file diff --git a/Mac/publish/dsa_pub.pem b/Mac/publish/dsa_pub.pem deleted file mode 100644 index 4c959f3..0000000 --- a/Mac/publish/dsa_pub.pem +++ /dev/null @@ -1,20 +0,0 @@ ------BEGIN PUBLIC KEY----- -MIIDPDCCAi4GByqGSM44BAEwggIhAoIBAQDjho3c9LB9TBv/wUQSegtiD2Q/YFjK -HvJH2ndtw2MIwd9iLA4JgXuZAZHpIa+YV7vU97TCvdRmO50VkfULkRona2SjE8lR -oK3VMOkJNGlAK0MfNgDF3/KcI7W6wTZRq/QLLI9Hi1oUpfheDCrrONyvHhCRW5UD -Rm/1Y/TltWfvDi2XmzvVFc9ISnuWoAntzp0IshWeAkcpDLbXJ3u9GudVAHeowEps -+BlMHMrzKPyvviRp0skJkmYvDpZn1YI9WhI4a65hPvgGO7a0/bgc1WbI6nR9mx6f -v+L37eqXoAJ+jrd2BaxD73BH7gBidO3xEYP0oUAxi1xkh2t587yyPU9lAhUAkKxj -3QWYyr+bYg6PDQyx2XpU+hcCggEBAJjhPOB+yLjbobEKJLzdjYujO0XMKVwej6k9 -14lCems95gwjWVS8t8rLAEYcheUPsz4rAid0ONCRQYbWmMBksv6AuXYH/qQM0BcB -DXtXnTRjUkDHCyWw+/QnkiQ+oHrzsZHPO1j+gsLOvZw2dfC1DUHHqsqaW1Oq8Xu9 -q+slmwbjTuymsbgfBJ27P09PU+FM0VNVQTCEXfZTMlDsCl6o19QmRbCLAqY0VhKZ -qPeL0atvdkaczDrNReZYRHcCfa9sO74Kt/m10UW7vEL5bIjYTN7kWvLh5HAuMvZo -Ta77PJpD0X0HbPUrX0/2YXZchxt3is1Tfy03T9aO4iWE+0Qy6wYDggEGAAKCAQEA -4AxqBHt4LMlsK330/0YXhyKYJEBjDHftz8vFuyq7Zob0t5euDExqtkjnDTo9BD/m -4tOE3/12IHL8kPpB0augGHONyoCO7Fdm+CR+mWNMqg2qo5mdPxEzP74WFrryhvh3 -z/GMhBPfZ/qSbfOvI9snc2KS6Pi34L+Je1UiYt8+gmN/uF/cUTWIkOUavI6AuGIB -oCkWGpEYjAYfZkR80/pKNQq2qLc9hiUAj1VpY5B6pxlelmos+/F62Je+E6Fd1VZN -cJfvL2kp/9bPU35cye4/FGkrW94DgRBw3IpAVrnwjnglJn2JUr7BySLO7PhFfTvO -ZbWeowFp6qKpOugZ7kS//w== ------END PUBLIC KEY----- diff --git a/Mac/publish/publish.rb b/Mac/publish/publish.rb deleted file mode 100755 index b036fb8..0000000 --- a/Mac/publish/publish.rb +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env ruby -wKU -require 'time' - -def test var, message - unless var - puts message - exit - end -end - -path = File.dirname File.expand_path(__FILE__) -mac_path = File.expand_path(path + "/..") -release_path = mac_path + "/build/Release/" - -version = `defaults read \"#{release_path}/Bungloo.app/Contents/Info\" CFBundleVersion`.gsub(/\n/,'') -length = `stat -f %z \"#{release_path}/Bungloo.app.zip\"`.gsub(/\n/,'') -signature = `ruby \"#{mac_path}/../../Sparkle\ 1.5b6/Extras/Signing Tools/sign_update.rb\" \"#{release_path}/Bungloo.app.zip\" \"#{mac_path}/publish/dsa_priv.pem\"`.gsub(/\n/,'') - -test version, "Couldn't find version" -test length, "Couldn't find length" -test signature, "Couldn't find signature" - -unless File.exists? "#{release_path}/Bungloo.app/Contents/Resources/dsa_pub.pem" - puts "#{release_path}/Bungloo.app/Contents/dsa_pub.pem" - exit -end - -xml = < - - - Bungloo's Changelog - http://jabs.nu/Bungloo/download/Appcast.xml - Most recent changes with links to updates. - en - - Version #{version} - 10.5.0 - http://jabs.nu/bungloo/download/ReleaseNotes.html - #{Time.now.rfc2822} - - - - -XML - -File.open("#{path}/Appcast.xml", 'w') {|f| f.write(xml) } -system "scp \"#{release_path}/Bungloo.app.zip\" jeena@jeena.net:~/jabs.nu/public/bungloo/download/" -system "scp \"#{path}/ReleaseNotes.html\" jeena@jeena.net:~/jabs.nu/public/bungloo/download/" -system "scp \"#{path}/Appcast.xml\" jeena@jeena.net:~/jabs.nu/public/bungloo/download/" - -puts "Done." diff --git a/Mac/setup.py b/Mac/setup.py new file mode 100644 index 0000000..f684a7c --- /dev/null +++ b/Mac/setup.py @@ -0,0 +1,49 @@ +""" +This is a setup.py script generated by py2applet + +Usage: + python setup.py py2app +""" + +from setuptools import setup +import os, PyQt4 + +files = [] + +for dirname, dirnames, filenames in os.walk('WebKit'): + for filename in filenames: + files += [(dirname, [os.path.join(dirname, filename)])] + +for dirname, dirnames, filenames in os.walk('images'): + for filename in filenames: + files += [(dirname, [os.path.join(dirname, filename)])] + +VERSION = "2.0.0" + +APP = ['Bungloo.py'] +OPTIONS = { + 'argv_emulation': False, + 'iconfile': 'images/Icon.icns', + 'plist': { + 'CFBundleShortVersionString': VERSION, + 'CFBundleIdentifier': "nu.jabs.apps.bungloo", + 'LSMinimumSystemVersion': "10.4", + 'CFBundleURLTypes': [ + { + 'CFBundleURLName': 'nu.jabs.apps.bungloo.handler', + 'CFBundleURLSchemes': ['bungloo'] + } + ] + }, + 'includes':['PyQt4.QtWebKit', 'PyQt4', 'PyQt4.QtCore', 'PyQt4.QtGui', 'simplejson', 'PyQt4.QtNetwork'], + 'excludes': ['PyQt4.QtDesigner', 'PyQt4.QtOpenGL', 'PyQt4.QtScript', 'PyQt4.QtSql', 'PyQt4.QtTest', 'PyQt4.QtXml', 'PyQt4.phonon'], + 'qt_plugins': 'imageformats', +} + +setup( + app=APP, + version=VERSION, + data_files=files, + options={'py2app': OPTIONS}, + setup_requires=['py2app'], +) diff --git a/Linux/Bungloo.py b/Qt/Bungloo.py similarity index 64% rename from Linux/Bungloo.py rename to Qt/Bungloo.py index 3c357f8..e76061f 100755 --- a/Linux/Bungloo.py +++ b/Qt/Bungloo.py @@ -1,19 +1,22 @@ #!/usr/bin/env python2 -import os, sys, pickle, subprocess, shutil -from PyQt4 import QtCore, QtGui, QtWebKit +import os, sys, pickle, subprocess, shutil, json +from PyQt4 import QtCore, QtGui, QtWebKit, QtNetwork +from sys import platform as _platform -RUNNING_LOCAL = os.path.basename(__file__) == "Bungloo.py" +try: + import Windows, Helper, SingleApplication +except: + from bungloo import Windows, Helper, SingleApplication -if RUNNING_LOCAL: - import Windows, Helper -else: - from bungloo import Windows, Helper - -class Bungloo: +class Bungloo(): def __init__(self): - self.app = QtGui.QApplication(sys.argv) + + sslConfig = QtNetwork.QSslConfiguration.defaultConfiguration() + sslConfig.setProtocol(QtNetwork.QSsl.TlsV1) + QtNetwork.QSslConfiguration.setDefaultConfiguration(sslConfig) + self.new_message_windows = [] self.controller = Controller(self) self.console = Console() @@ -22,15 +25,14 @@ class Bungloo: self.preferences.show() self.oauth_implementation = Windows.Oauth(self) + self.conversation_views = [] if self.controller.stringForKey("user_access_token") != "": self.authentification_succeded() - self.app.exec_() - def resources_path(self): - if RUNNING_LOCAL: - return os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) + if Helper.Helper.is_local() and not Helper.Helper.is_mac(): + return os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '..')) else: return Helper.Helper.get_resource_path() @@ -83,8 +85,23 @@ class Bungloo: self.oauth_implementation.log_out() self.timeline.hide() self.preferences.show() - self.timeline.evaluateJavaScript("bungloo.sidebar.logout()") + self.timeline.evaluateJavaScript("bungloo.sidebar.logout();") + def next_show(self): + self.timeline.evaluateJavaScript("bungloo.sidebar.showContentForNext();") + + def handleMessage(self, args): + # argv is just a array of words which you can get in from the outside + argv = json.loads(str(args)) + print args + if len(argv) > 0: + if argv[0] == "--new-message": + text = " ".join(argv[1:]) + self.controller.openNewMessageWidow(text) + elif argv[0].startswith("bungloo://oauthtoken"): + self.oauth_implementation.bungloo_callback(QtCore.QUrl(argv[0].encode("utf-8"), QtCore.QUrl.TolerantMode)) + + class Controller(QtCore.QObject): @@ -92,15 +109,12 @@ class Controller(QtCore.QObject): QtCore.QObject.__init__(self) self.app = app - oldpath = os.path.expanduser('~/.bungloo/') - if os.path.isdir(oldpath): - shutil.copytree(oldpath, os.path.expanduser('~/.config/bungloo/')) - shutil.rmtree(os.path.expanduser('~/.bungloo/')) + name = "bungloo2" - if not os.path.exists(os.path.expanduser("~/.config/bungloo/")): - os.makedirs(os.path.expanduser("~/.config/bungloo/")) + if not os.path.exists(os.path.expanduser("~/.config/" + name + "/")): + os.makedirs(os.path.expanduser("~/.config/" + name + "/")) - self.config_path = os.path.expanduser('~/.config/bungloo/bungloo.cfg') + self.config_path = os.path.expanduser('~/.config/' + name + '/bungloo.cfg') if os.access(self.config_path, os.R_OK): with open(self.config_path, 'r') as f: @@ -151,28 +165,27 @@ class Controller(QtCore.QObject): @QtCore.pyqtSlot(str, str, str, str) def notificateUserAboutMentionFromNameWithPostIdAndEntity(self, text, name, post_id, entity): try: - subprocess.check_output(['kdialog', '--passivepopup', name + ' mentioned you: ' + text]) + subprocess.check_output(['kdialog', '--passivepopup', (name + ' mentioned you: ' + text).replace("\"", "\\\"")]) except OSError: try: - subprocess.check_output(['notify-send', '-i', 'dialog-information', name + ' mentioned you on Tent', text]) + subprocess.check_output(['notify-send', '-i', 'dialog-information', name.replace("\"", "\\\"") + ' mentioned you on Tent', text.replace("\"", "\\\"")]) except OSError: pass - @QtCore.pyqtSlot(str) - def openNewMessageWidow(self, string): - new_message_window = Windows.NewPost(self.app) - new_message_window.show() - new_message_window.setAttribute(QtCore.Qt.WA_DeleteOnClose) - self.app.new_message_windows.append(new_message_window) + @QtCore.pyqtSlot() + def openNewMessageWidow(self, text=""): + self.openNewMessageWindowInReplyToStatus("") # FIXME: create a status_string with this content - @QtCore.pyqtSlot(str, str, str, bool) - def openNewMessageWindowInReplyTostatusIdwithStringIsPrivate(self, entity, status_id, string, is_private): - new_message_window = Windows.NewPost(self.app) - new_message_window.inReplyToStatusIdWithString(entity, status_id, string) - new_message_window.setIsPrivate(is_private) + @QtCore.pyqtSlot(str) + def openNewMessageWindowInReplyToStatus(self, status_string): + new_message_window = Windows.NewPost(self.app, status_string) new_message_window.show() new_message_window.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.app.new_message_windows.append(new_message_window) + new_message_window.activateWindow() + new_message_window.setFocus() + new_message_window.show() + new_message_window.raise_() def sendMessage(self, message): text = message.text @@ -212,6 +225,16 @@ class Controller(QtCore.QObject): self.app.timeline.evaluateJavaScript(func) self.app.timeline.show() + @QtCore.pyqtSlot(str, str) + def showConversationViewForPostIdandEntity(self, postId, entity): + custom_after_load = "function HostAppGo() { start('conversation-standalone', function() { bungloo.conversation.showStatus(" + custom_after_load += "'{}', '{}'".format(postId, entity) + custom_after_load += "); }) }" + + conversation = Windows.Timeline(self.app, "conversation", "Conversation", custom_after_load) + self.app.conversation_views += [conversation] + conversation.show() + @QtCore.pyqtSlot(str) def showProfileForEntity(self, entity): func = "bungloo.sidebar.onEntityProfile(); bungloo.entityProfile.showProfileForEntity('{}');".format(entity) @@ -240,6 +263,16 @@ class Controller(QtCore.QObject): msgBox.setInformativeText(message) msgBox.exec_() + @QtCore.pyqtSlot(result=str) + def getCachedProfiles(self): + entities = self.app.timeline.evaluateJavaScript("JSON.stringify(bungloo.cache.profiles);") + return entities.toString() + + @QtCore.pyqtSlot() + def getNewData(self): + func = "bungloo.timeline.getNewData()" + self.app.timeline.evaluateJavaScript(func) + def logout(self, sender): print "logout is not implemented yet" @@ -268,4 +301,35 @@ class Console(QtCore.QObject): if __name__ == "__main__": - Bungloo() + + key = 'BUNGLOO2' + + if len(sys.argv) > 1 and sys.argv[1] == "--help": + print """ +Usage: bungloo [option [text]] + +Options: +--new-message [text] Opens new message window with text +--search text Opens search with text + """ + sys.exit(1) + + if Helper.Helper.is_windows() and not Helper.Helper.is_local(): + import sys + from os import path, environ, makedirs + appdata = path.join(environ["TMP"], key) + if not path.exists(appdata): + makedirs(appdata) + sys.stdout = open(path.join(appdata, key + ".log"), "w") + sys.stderr = open(path.join(appdata, key + "_err.log"), "w") + + app = SingleApplication.SingleApplicationWithMessaging(sys.argv, key) + if app.isRunning(): + print json.dumps(sys.argv[1:]) + app.sendMessage(json.dumps(sys.argv[1:])) + sys.exit(1) + + app.bungloo = Bungloo() + app.connect(app, QtCore.SIGNAL('messageAvailable'), app.bungloo.handleMessage) + + sys.exit(app.exec_()) diff --git a/Linux/Helper.py b/Qt/Helper.py similarity index 78% rename from Linux/Helper.py rename to Qt/Helper.py index c822256..d70b007 100644 --- a/Linux/Helper.py +++ b/Qt/Helper.py @@ -2,17 +2,37 @@ from PyQt4 import QtCore, QtGui, QtWebKit from PyQt4.QtCore import QTimer, QVariant, SIGNAL from PyQt4.QtGui import * -from PyQt4.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply +from PyQt4.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply, QSslSocket from PyQt4.QtWebKit import QWebView +from sys import platform as _platform -import os - -import array +import os, sys, array class Helper: - @classmethod - def get_resource_path(cls): - return os.path.dirname(__file__) + @classmethod + def get_resource_path(cls): + if Helper.is_windows(): + return os.path.dirname(sys.argv[0]) + elif Helper.is_mac(): + return os.path.dirname(sys.argv[0]) + else: + return os.path.dirname(__file__) + + @classmethod + def is_local(cls): + return os.path.basename(sys.argv[0]) == "Bungloo.py" + + @classmethod + def is_mac(cls): + return _platform == "darwin" + + @classmethod + def is_windows(cls): + return os.name == "nt" + + @classmethod + def is_linux(cls): + return not (Helper.is_windows() or Helper.is_mac()) class WebPage(QtWebKit.QWebPage): def __init__(self, parent=0, app=None): @@ -43,6 +63,8 @@ class WebViewCreator(QtWebKit.QWebView): self.customContextMenuRequested.connect(self.context_menu_requested) self.actions = [] + self.page().networkAccessManager().sslErrors.connect(lambda reply, errors: self.handleSslErrors(reply, errors)) + def copy_link(): self.page().triggerAction(QtWebKit.QWebPage.CopyLinkToClipboard) self.action_copy_link = QtGui.QAction('Copy Lin&k', self, triggered=copy_link) @@ -85,14 +107,19 @@ class WebViewCreator(QtWebKit.QWebView): def load_finished(self, ok, callback=None): frame = self.page().mainFrame() if self.is_local: - frame.evaluateJavaScript("var OS_TYPE = 'linux';") + os_type = "linux" + if Helper.is_windows: + os_type = "windows" + elif Helper.is_mac: + os_type = "osx" + frame.evaluateJavaScript("var OS_TYPE = '" + os_type + "';") - js_plugin_path = os.path.expanduser('~/.bungloo/Plugin.js') + js_plugin_path = os.path.expanduser('~/.config/bungloo2/Plugin.js') if os.access(js_plugin_path, os.R_OK): func = "setTimeout(function() { loadJsPlugin('file://localhost/" + js_plugin_path + "') }, 1000);" frame.evaluateJavaScript(func) - css_plugin_path = os.path.expanduser('~/.bungloo/Plugin.css') + css_plugin_path = os.path.expanduser('~/.config/bungloo2/Plugin.css') if os.access(css_plugin_path, os.R_OK): func = "setTimeout(function() { loadCssPlugin('file://localhost/" + css_plugin_path + "') }, 1000);" frame.evaluateJavaScript(func) @@ -100,6 +127,12 @@ class WebViewCreator(QtWebKit.QWebView): if callback: callback(ok) + def handleSslErrors(self, reply, errors): + if Helper.is_windows: # ignore SSL errors on Windows (yes a uggly workaround, don't know how to fix it yet) + for error in errors: + print error.errorString() + reply.ignoreSslErrors(errors) + class NetworkAccessManager(QNetworkAccessManager): @@ -113,6 +146,7 @@ class NetworkAccessManager(QNetworkAccessManager): self.setCookieJar(old_manager.cookieJar()) self.setProxy(old_manager.proxy()) self.setProxyFactory(old_manager.proxyFactory()) + self.sslErrors.connect(lambda reply, errors: old_manager.sslErrors) def createRequest(self, operation, request, data): if request.url().scheme() != "bungloo": diff --git a/Qt/SingleApplication.py b/Qt/SingleApplication.py new file mode 100755 index 0000000..91c8e97 --- /dev/null +++ b/Qt/SingleApplication.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python2 + +# from http://stackoverflow.com/questions/8786136/pyqt-how-to-detect-and-close-ui-if-its-already-running + +from PyQt4 import QtGui, QtCore, QtNetwork +import json + +class SingleApplication(QtGui.QApplication): + def __init__(self, argv, key): + self.bungloo = None + QtGui.QApplication.setGraphicsSystem("raster") + QtGui.QApplication.__init__(self, argv) + self._memory = QtCore.QSharedMemory(self) + self._memory.setKey(key) + if self._memory.attach(): + self._running = True + else: + self._running = False + if not self._memory.create(1): + raise RuntimeError( + self._memory.errorString().toLocal8Bit().data()) + + def isRunning(self): + return self._running + +class SingleApplicationWithMessaging(SingleApplication): + def __init__(self, argv, key): + SingleApplication.__init__(self, argv, key) + self._key = key + self._timeout = 1000 + self._server = QtNetwork.QLocalServer(self) + if not self.isRunning(): + self._server.newConnection.connect(self.handleMessage) + self._server.listen(self._key) + + def handleMessage(self): + socket = self._server.nextPendingConnection() + if socket.waitForReadyRead(self._timeout): + self.emit(QtCore.SIGNAL('messageAvailable'), + QtCore.QString.fromUtf8(socket.readAll().data())) + socket.disconnectFromServer() + else: + QtCore.qDebug(socket.errorString().toLatin1()) + + def sendMessage(self, message): + if self.isRunning(): + socket = QtNetwork.QLocalSocket(self) + socket.connectToServer(self._key, QtCore.QIODevice.WriteOnly) + if not socket.waitForConnected(self._timeout): + print(socket.errorString().toLocal8Bit().data()) + return False + socket.write(unicode(message).encode('utf-8')) + if not socket.waitForBytesWritten(self._timeout): + print(socket.errorString().toLocal8Bit().data()) + return False + socket.disconnectFromServer() + return True + return False + + def event(self, event): + if isinstance(event, QtGui.QFileOpenEvent): + url = str(event.url().toString()) + args = json.dumps([url]) + self.bungloo.handleMessage(args) + return True + +class Window(QtGui.QWidget): + def __init__(self): + QtGui.QWidget.__init__(self) + self.edit = QtGui.QLineEdit(self) + self.edit.setMinimumWidth(300) + layout = QtGui.QVBoxLayout(self) + layout.addWidget(self.edit) + + def handleMessage(self, message): + self.edit.setText(message) + +if __name__ == '__main__': + + import sys + + key = 'FOO_BAR' + + if len(sys.argv) > 1: + app = SingleApplicationWithMessaging(sys.argv, key) + if app.isRunning(): + app.sendMessage(sys.argv[1]) + sys.exit(1) + else: + app = SingleApplication(sys.argv, key) + if app.isRunning(): + print('app is already running') + sys.exit(1) + + window = Window() + app.connect(app, QtCore.SIGNAL('messageAvailable'), + window.handleMessage) + window.show() + + sys.exit(app.exec_()) \ No newline at end of file diff --git a/Linux/Windows.py b/Qt/Windows.py similarity index 74% rename from Linux/Windows.py rename to Qt/Windows.py index 5fe85c3..d18e5ca 100644 --- a/Linux/Windows.py +++ b/Qt/Windows.py @@ -1,5 +1,5 @@ from PyQt4 import QtCore, QtGui, QtWebKit -import Helper, urllib, urllib2 +import Helper, urllib, urllib2, os class Preferences: @@ -9,7 +9,7 @@ class Preferences: # window self.window = QtGui.QMainWindow() - self.window.setWindowTitle("Preferences") + self.window.setWindowTitle("Login") self.window.resize(480, 186) self.window.setMinimumSize(480, 186) self.window.setMaximumSize(480, 186) @@ -21,7 +21,8 @@ class Preferences: image_view.setPixmap(image) image_view.setScaledContents(True) - self.window.setWindowIcon(QtGui.QIcon(image)) + if not Helper.Helper.is_mac(): + self.window.setWindowIcon(QtGui.QIcon(image)) # info text info_text = QtGui.QLabel(self.window) @@ -76,14 +77,17 @@ class Preferences: class Timeline: - def __init__(self, app, action="timeline", title="Bungloo"): + def __init__(self, app, action="timeline", title="Bungloo", custom_after_load=None): self.app = app self.action = action self.title = title + self.custom_after_load = custom_after_load self.window = Helper.RestorableWindow(action, self.app) self.window.setWindowTitle(title) - self.window.setWindowIcon(QtGui.QIcon(self.app.resources_path() + "/images/Icon.png")) + + if not Helper.Helper.is_mac(): + self.window.setWindowIcon(QtGui.QIcon(self.app.resources_path() + "/images/Icon.png")) self.webView = Helper.WebViewCreator(self.app, True, self.window) self.webView.load_local(self.load_finished) @@ -113,6 +117,11 @@ class Timeline: findEntityAction.setStatusTip("Find entity and open its profile view") findEntityAction.triggered.connect(self.app.find_entity_show) + closeAction = QtGui.QAction("&Close Window", self.window) + closeAction.setShortcut("Ctrl+w") + closeAction.setStatusTip("Close this window") + closeAction.triggered.connect(self.window.close) + logOutAction = QtGui.QAction("&Log Out", self.window) logOutAction.setStatusTip("Log out from this entity") logOutAction.triggered.connect(self.app.log_out) @@ -125,6 +134,7 @@ class Timeline: fileMenu = menubar.addMenu("&File") fileMenu.addAction(newPostAction) fileMenu.addAction(findEntityAction) + fileMenu.addAction(closeAction) fileMenu.addSeparator() fileMenu.addAction(logOutAction) fileMenu.addAction(exitAction) @@ -154,12 +164,19 @@ class Timeline: searchAction.setStatusTip("Show Search") searchAction.triggered.connect(self.app.search_show) + nextAction = QtGui.QAction("&Next View", self.window) + nextAction.setShortcut("Ctrl+6") + nextAction.setStatusTip("Show Next") + nextAction.triggered.connect(self.app.next_show) + windowMenu = menubar.addMenu("&View") windowMenu.addAction(timelineAction) windowMenu.addAction(mentionsAction) windowMenu.addAction(conversationAction) windowMenu.addAction(profileAction) windowMenu.addAction(searchAction) + windowMenu.addSeparator() + windowMenu.addAction(nextAction) aboutAction = QtGui.QAction("&About Bungloo", self.window) aboutAction.setStatusTip("Open about page in Webbrowser") @@ -175,8 +192,7 @@ class Timeline: def show(self): self.window.show() - #self.window.raise_() - #QtGui.qApp.setActiveWindow(self.window) + def close(self): self.window.close() @@ -185,6 +201,8 @@ class Timeline: def load_finished(self, widget): script = "function HostAppGo() { start('" + self.action + "'); }" + if self.custom_after_load: + script = self.custom_after_load self.webView.page().mainFrame().evaluateJavaScript(script) def set_window_title(self, title): @@ -218,14 +236,19 @@ class Oauth: self.core.page().mainFrame().evaluateJavaScript(script) def handle_authentication(self, url): + self.app.controller.openURL(url) + return False + self.auth_view = Helper.WebViewCreator(self.app) self.auth_view.setWindowTitle("Authentication") old_manager = self.auth_view.page().networkAccessManager() new_manager = Helper.NetworkAccessManager(old_manager, self.bungloo_callback) new_manager.authenticationRequired.connect(self.authentication_required) + new_manager.sslErrors.connect(lambda reply, errors: self.handleSslErrors(reply, errors)) self.auth_view.page().setNetworkAccessManager(new_manager) self.auth_view.show() + self.auth_view.load_url(url) return False @@ -250,6 +273,13 @@ class Oauth: if hasattr(self, "auth_view"): self.auth_view.hide() + def handleSslErrors(self, reply, errors): + if os.name == "nt": # ignore SSL errors on Windows (yes a uggly workaround, don't know how to fix it yet) + for error in errors: + print error.errorString() + reply.ignoreSslErrors(errors) + + class Login(QtGui.QDialog): def __init__(self): @@ -305,25 +335,30 @@ class FindEntity(QtGui.QDialog): class NewPost(Helper.RestorableWindow): - def __init__(self, app): + def __init__(self, app, status_string): self.app = app + self.status_string = status_string + Helper.RestorableWindow.__init__(self, "newpost", self.app) + self.activateWindow() + self.raise_() - self.setWindowIcon(QtGui.QIcon(self.app.resources_path() + "/images/Icon.png")) + if not Helper.Helper.is_mac(): + self.setWindowIcon(QtGui.QIcon(self.app.resources_path() + "/images/Icon.png")) - self.textInput = QtGui.QPlainTextEdit(self) - self.setCentralWidget(self.textInput) - self.textInput.textChanged.connect(self.onChanged) + self.webView = Helper.WebViewCreator(self.app, True, self) + self.webView.load_local(self.load_finished) + self.setCentralWidget(self.webView) + + self.initUI() + + self.webView.triggerPageAction(QtWebKit.QWebPage.InspectElement) + frame = self.webView.page().mainFrame() + frame.addToJavaScriptWindowObject("new_post_window", self) self.setWindowTitle("New Post") self.resize(300, 150) self.setMinimumSize(100, 100) - self.initUI() - - self.setIsPrivate(False) - self.status_id = None - self.reply_to_entity = None - self.imageFilePath = None def initUI(self): newPostAction = QtGui.QAction("&New Post", self) @@ -372,88 +407,38 @@ class NewPost(Helper.RestorableWindow): aboutAction.setStatusTip("Open about page in Webbrowser") aboutAction.triggered.connect(self.app.open_about) + developerExtrasAction = QtGui.QAction("&Developer Extras", self) + developerExtrasAction.setStatusTip("Activate webkit inspector") + developerExtrasAction.triggered.connect(self.developer_extras) + helpMenu = menubar.addMenu("&Help") helpMenu.addAction(aboutAction) + helpMenu.addAction(developerExtrasAction) - - self.statusBar().showMessage('256') - - self.addButton = QtGui.QToolButton() - self.addButton.setToolTip("Add photo") - self.addButton.clicked.connect(self.openFileDialog) - self.addButton.setAutoRaise(True) - #addIcon = QtGui.QIcon.fromTheme("insert-image", QtGui.QIcon(self.app.resources_path() + "/images/Actions-insert-image-icon.png")) - addIcon = QtGui.QIcon(self.app.resources_path() + "/images/glyphicons_138_picture.png") - self.addButton.setIcon(addIcon) - self.statusBar().addPermanentWidget(self.addButton) - - self.isPrivateButton = QtGui.QToolButton() - self.isPrivateButton.setToolTip("Make private") - self.isPrivateButton.clicked.connect(self.toggleIsPrivate) - self.isPrivateButton.setAutoRaise(True) - #self.isPrivateIcon = QtGui.QIcon(self.app.resources_path() + "/images/Lock-Lock-icon.png") - self.isPrivateIcon = QtGui.QIcon(self.app.resources_path() + "/images/glyphicons_203_lock.png") - #self.isNotPrivateIcon = QtGui.QIcon(self.app.resources_path() + "/images/Lock-Unlock-icon.png") - self.isNotPrivateIcon = QtGui.QIcon(self.app.resources_path() + "/images/glyphicons_204_unlock.png") - self.isPrivateButton.setIcon(self.isNotPrivateIcon) - self.statusBar().addPermanentWidget(self.isPrivateButton) - - self.sendButton = QtGui.QToolButton() - self.sendButton.setToolTip("Send") - self.sendButton.clicked.connect(self.sendMessage) - self.sendButton.setAutoRaise(True) - #sendIcon = QtGui.QIcon.fromTheme("mail-send", QtGui.QIcon(self.app.resources_path() + "/images/send-icon.png")) - sendIcon = QtGui.QIcon(self.app.resources_path() + "/images/glyphicons_123_message_out.png") - self.sendButton.setIcon(sendIcon) - self.statusBar().addPermanentWidget(self.sendButton) - - def setIsPrivate(self, is_private): - self.isPrivate = is_private - icon = self.isNotPrivateIcon - if self.isPrivate: - icon = self.isPrivateIcon - - self.isPrivateButton.setIcon(icon) + def load_finished(self, widget): + callback = "function() { bungloo.newpost.setStatus(\"%s\"); }" % (self.status_string) + script = "function HostAppGo() { start('newpost', " + callback + "); }" + self.webView.page().mainFrame().evaluateJavaScript(script) + self.webView.setFocus() def toggleIsPrivate(self): - self.setIsPrivate(not self.isPrivate) - - def inReplyToStatusIdWithString(self, reply_to, status_id, string): - self.reply_to_entity = reply_to - self.status_id = status_id - self.textInput.setPlainText(string) - - cursor = self.textInput.textCursor() - cursor.movePosition(QtGui.QTextCursor.End, QtGui.QTextCursor.MoveAnchor) - cursor.movePosition(QtGui.QTextCursor.Start, QtGui.QTextCursor.KeepAnchor) - cursor.movePosition(QtGui.QTextCursor.EndOfLine, QtGui.QTextCursor.KeepAnchor) - self.textInput.setTextCursor(cursor) - - def onChanged(self): - count = 256 - len(self.textInput.toPlainText()) - self.statusBar().showMessage(str(count)) + script = "bungloo.newpost.toggleIsPrivate();" + self.webView.page().mainFrame().evaluateJavaScript(script) def sendMessage(self): - count = len(self.textInput.toPlainText()) - if count > 0 and count <= 256: - message = Helper.PostModel() - message.text = unicode(self.textInput.toPlainText().toUtf8(), "utf-8") - message.inReplyTostatusId = self.status_id - message.inReplyToEntity = self.reply_to_entity - message.location = None - message.imageFilePath = self.imageFilePath - message.isPrivate = self.isPrivate - self.app.controller.sendMessage(message) - self.close() - else: - QtGui.qApp.beep() + script = "bungloo.newpost.send()" + self.webView.page().mainFrame().evaluateJavaScript(script) + + def developer_extras(self, widget): + QtWebKit.QWebSettings.globalSettings().setAttribute(QtWebKit.QWebSettings.DeveloperExtrasEnabled, True) def openFileDialog(self): - fileNamePath = QtGui.QFileDialog.getOpenFileName(self, "Choose a image", "", "Images (*.png *.gif *.jpg *.jpeg)") - if len(fileNamePath) > 0: - self.imageFilePath = str(fileNamePath) - else: - self.imageFilePath = None - + print "openFileDialog Not implemented yet" + @QtCore.pyqtSlot() + def closeWindow(self): + self.close() + @QtCore.pyqtSlot() + def beep(self): + QtGui.qApp.beep() \ No newline at end of file diff --git a/WebKit/css/default.css b/WebKit/css/default.css index 4d94b0f..2d314ec 100644 --- a/WebKit/css/default.css +++ b/WebKit/css/default.css @@ -7,16 +7,34 @@ html, body { body { font-family: "Lucida Grande", "Open Sans", "Ubuntu", Tahoma, sans-serif; font-size: 11px; - background: #dedede url(../img/background.png) center center no-repeat; + background: #dedede center center no-repeat; +} + +body#with-sidebar { + background-image: url(../img/background.png); } a { text-decoration: none; color: #00317a; outline: 0; + outline : none; +} + +button { + background: transparent; + border: 0; + margin: 0; + padding: 4px 5px 0 5px; + outline : none; } #sidebar { + display: none; +} + +#with-sidebar #sidebar { + display: block; position: fixed; top: 0; left: 0; @@ -32,6 +50,11 @@ a { text-align: center; } +#sidebar * { + -webkit-touch-callout: none; + -webkit-user-select: none; +} + #siedebar a { color: #5b5b5b; } @@ -59,7 +82,7 @@ a { /*display: none;*/ } -#content { +#with-sidebar #content { margin-left: 62px; } @@ -69,7 +92,7 @@ ol { padding: 0; } -ol li, .error, header.profile { +ol li .post, .error, header.profile { clear: both; padding: 8px; background: #eee; @@ -86,37 +109,33 @@ ol li, .error, header.profile { color: red; } -#content ol > li { - -} - -#content ol > li:first-child { +#content ol > li:first-child > .post { border-top: 0; } -#content ol > li:nth-child(odd), .error, header.profile { +#content ol > li:nth-child(odd) > .post, .error, header.profile, #content #conversation-tree li.odd > .post { background: #fafafa; } -#content ol > li:nth-child(even) { +#content ol > li:nth-child(even) > .post, #content #conversation-tree li.even > .post { background: #f2f2f2; } -#content ol > li:hover { - background: #dedede; +#content ol > li > .post:hover { + background: #dedede !important; } -#content ol > li.highlighteffect { +#content ol > li.highlighteffect > .post { background-color: #FFFBD0; -webkit-transition: background-color 200ms linear; } -#content ol > li.highlighteffect-after { +#content ol > li.highlighteffect-after > .post { -webkit-transition: background-color 1000ms linear; } -#content ol > li:after, header.profile:after { +#content ol > li .post:after, header.profile:after { content: "."; display: block; clear: both; @@ -148,7 +167,7 @@ header.profile h1 + p { margin-bottom: 10px; } -.highlight { +.highlight > .post { border-right: 5px solid #f17779; } @@ -169,6 +188,10 @@ p { word-wrap: break-word; } +p + p { + padding-top: 0.5em; +} + .image { float: left; margin-left: 2px; @@ -214,37 +237,39 @@ p { font-weight: bold; } -li .from { - position: absolute; - top: -1.8em; - right: 10px; - display: none; - padding: 0.3em 0.9em; - -webkit-border-top-left-radius: 8px; - -webkit-border-top-right-radius: 8px; - -webkit-box-shadow: 0 -2px 2px rgba(0, 0, 0, 0.1); - border: 1px solid white; - border-bottom: 0; - background: #ddd; - font-size: 0.9em; -} - -li:hover .from { +li .post:hover .from { display: block; } +li .post .from { + position: absolute; + right: 3.5em; + display: none; + padding: 0.3em 0.9em; + background: #ddd; + font-size: 0.9em; + top: auto; + bottom: -1.8em; + z-index: 2; + -webkit-border-top-left-radius: 0; + -webkit-border-top-right-radius: 0; + -webkit-border-bottom-left-radius: 8px; + -webkit-border-bottom-right-radius: 8px; + -webkit-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.1); + border: 1px solid #b9b9b9; + border-top: 0; +} -li:first-child:hover .from { - top: auto; - bottom: -1.9em; - z-index: 2; - -webkit-border-top-left-radius: 0; - -webkit-border-top-right-radius: 0; - -webkit-border-bottom-left-radius: 8px; - -webkit-border-bottom-right-radius: 8px; - -webkit-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.1); - border: 1px solid #b9b9b9; - border-top: 0; +li:last-child:not(:first-child) .post:hover .from { + top: -1.8em; + bottom: auto; + -webkit-border-top-left-radius: 8px; + -webkit-border-top-right-radius: 8px; + -webkit-border-bottom-left-radius: 0px; + -webkit-border-bottom-right-radius: 0px; + -webkit-box-shadow: 0 -2px 2px rgba(0, 0, 0, 0.1); + border: 1px solid white; + border-bottom: 0; } aside { @@ -261,7 +286,7 @@ aside { visibility: hidden; } -li:hover aside .reply_to, li:hover aside .repost, li:hover aside .remove, li:hover aside .ago:before { +li .post:hover > aside .reply_to, li .post:hover > aside .repost, li .post:hover > aside .remove, li .post:hover > aside .ago:before { visibility: visible; } @@ -288,11 +313,11 @@ li:hover aside .reply_to, li:hover aside .repost, li:hover aside .remove, li:hov background-position: -128px 0; } -li.mentioned { +li.mentioned .post { border-right: 5px solid #00317a; } -.mentions li.mentioned { +.mentions li.mentioned .post { border-right: 0; } @@ -372,12 +397,17 @@ li.mentioned { .name { font-weight: bold; + border-bottom: 1px dotted ; } .message { clear: right; } +.message a:not(.name) { + text-decoration: underline; +} + header.profile button { background: #09F; float: right; @@ -418,10 +448,48 @@ iframe { form.search { text-align: center; padding: 5px 10%; + border-bottom: 1px solid #c9c9c9; } form.search input { width: 100%; padding: 10px; font-size: 1.2em; -} \ No newline at end of file +} + +p.noresult { + padding : 10px; + text-align : center; +} + +.new_post #sidebar, .new_post #content { display: none; } +.new_post { height: 100%; } +#new_post_container { position: absolute; border-collapse: collapse; height: 100%; width: 100%; } +#new_post_container td { position: relative; height: 90%; } +#new_post_container .text td { background: white; } +#new_post_container textarea { resize: none; box-sizing: border-box; position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 0; background: transparent; outline: none; } +#new_post_container div { box-sizing: border-box; position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 0; background: white; color: transparent; padding: 2px; } + +#new_post_container div span { background: #D8DFEA; } +#suggestions { width: 100%; position: absolute; left: 0; bottom: 0; background: #efefef; list-style-type: none; padding: 0; margin: 0; border-top: 1px solid #ccc; } +#suggestions li { border-top: 1px solid #fefefe; border-bottom: #c9c9c9; padding: 0 0.5em; } +#suggestions strong { font-weight: normal; color: #555; } +#suggestions .active { background: #dedede; } +#suggestions .active strong { color: black; } +#status_bar { height: 1em; border-top: 1px solid #ccc; } +#status_bar p { float: right; margin: 0; padding: 0; } +#status_bar span { display: inline-block; margin: 4px 5px 0 5px; } + +#conversation-tree ol { + border-left: 1px solid #c9c9c9; + clear: both; +} + +#conversation-tree ol li { + clear: both !important; + padding-left: 14px; +} + +#conversation-tree ol li .post { + border-left: 1px solid #c9c9c9; +} diff --git a/images/glyphicons_138_picture.png b/WebKit/img/images.png similarity index 100% rename from images/glyphicons_138_picture.png rename to WebKit/img/images.png diff --git a/images/glyphicons_203_lock.png b/WebKit/img/private.png similarity index 100% rename from images/glyphicons_203_lock.png rename to WebKit/img/private.png diff --git a/images/glyphicons_204_unlock.png b/WebKit/img/public.png similarity index 100% rename from images/glyphicons_204_unlock.png rename to WebKit/img/public.png diff --git a/images/glyphicons_123_message_out.png b/WebKit/img/send.png similarity index 100% rename from images/glyphicons_123_message_out.png rename to WebKit/img/send.png diff --git a/WebKit/scripts/controller/Conversation.js b/WebKit/scripts/controller/Conversation.js index b488d32..4ff204d 100644 --- a/WebKit/scripts/controller/Conversation.js +++ b/WebKit/scripts/controller/Conversation.js @@ -1,39 +1,53 @@ define([ "helper/HostApp", "helper/Core", - "helper/Paths", - "lib/URI" + "helper/APICalls", + "lib/URI", + "helper/ConversationNode" ], -function(HostApp, Core, Paths, URI) { +function(HostApp, Core, APICalls, URI, ConversationNode) { - function Conversation() { + function Conversation(standalone) { Core.call(this); + + this.standalone = standalone; this.action = "conversation"; + this.container = document.createElement("div"); + this.container.className = this.action; this.body = document.createElement("ol"); - this.body.className = this.action; + this.container.appendChild(this.body) - document.getElementById("content").appendChild(this.body); - this.hide(); + document.getElementById("content").appendChild(this.container); + if(!this.standalone) this.hide(); + + // Stop loading if ESC is pressed + this.stopLoading = false; + var _this = this; + $(document).keydown(function(e) { + if (e.keyCode == 27) { // Esc + _this.stopLoading = true; + _this.makeTree(); + } + }); } Conversation.prototype = Object.create(Core.prototype); Conversation.prototype.show = function() { - Core.prototype.show.call(this, this.body); + Core.prototype.show.call(this, this.container); } Conversation.prototype.hide = function() { - Core.prototype.hide.call(this, this.body); + Core.prototype.hide.call(this, this.container); } Conversation.addStatus = function(status) { - this.body.appendChild(this.getStatusDOMElement(status)); } @@ -41,108 +55,144 @@ function(HostApp, Core, Paths, URI) { Conversation.prototype.showStatus = function(id, entity) { this.body.innerHTML = ""; + this.rootNode = null; + this.current_post_id = id; + this.current_entity = entity; this.append(id, entity); } + // Hack for OS X + Conversation.prototype.showStatusFromController = function() { + this.showStatus(conversationViewController.postId, conversationViewController.entity); + } + Conversation.prototype.append = function(id, entity, node, add_after) { + if(this.stopLoading) return; + var _this = this; var callback = function(resp) { - var status = JSON.parse(resp.responseText); + var _statuses = JSON.parse(resp.responseText); - var dom_element = _this.getStatusDOMElement(status); + for (var entity in _statuses.profiles) { + if (_statuses.profiles[entity] != null) { + bungloo.cache.profiles[entity] = _statuses.profiles[entity]; + } else { + bungloo.cache.profiles[entity] = {}; + } + } + + var status = _statuses.post; + + var dom_element = _this.getStatusDOMElement(status, _statuses.refs); + var cNode = new ConversationNode(dom_element); + dom_element.cNode = cNode; if (node) { + if(add_after) { // is a child of node + node.parentNode.insertBefore(dom_element, node.nextSibling); + node.cNode.addChild(cNode); + } else { // is a parent of node + node.parentNode.insertBefore(dom_element, node); + cNode.addChild(node.cNode); + } - node.parentNode.insertBefore(dom_element, node); - - } else { + } else { // is start node (doesn't have to be root, can have parents) dom_element.className = "highlight"; _this.body.appendChild(dom_element); - _this.appendMentioned(id, entity, dom_element); + _this.rootNode = cNode; } - for (var i = 0; i < status.mentions.length; i++) { - var mention = status.mentions[i]; - if(mention.post) { - _this.append(mention.post, mention.entity, dom_element); - } - } - } - - function getRemoteStatus(profile) { - var server = profile["https://tent.io/types/info/core/v0.1.0"].servers[0]; - Paths.getURL(URI(server + "/posts/" + id).toString(), "GET", callback, null, false); - } - - var profile = this.cache.profiles.getItem(entity); - - if (entity == HostApp.stringForKey("entity")) { - - var url = URI(Paths.mkApiRootPath("/posts/" + id)); - Paths.getURL(url.toString(), "GET", callback, null); - - } else if(profile) { - - getRemoteStatus(profile); - - } else { - - Paths.findProfileURL(entity, function(profile_url) { - - if (profile_url) { - - var profile = this.cache.profiles.getItem(entity); - if (profile) { - - getRemoteStatus(profile); - - } else { - - Paths.getURL(profile_url, "GET", function(resp) { - - var profile = JSON.parse(resp.responseText) - this.cache.profiles.setItem(entity, profile); - getRemoteStatus(profile); - - }, null, false); // do not send auth-headers + // child posts + _this.appendMentioned(id, entity, dom_element); + + // parent posts + if(status.mentions) { + for (var i = 0; i < status.mentions.length; i++) { + var mention = status.mentions[i]; + if(mention.post) { + // don't load if it is already there + if(!document.getElementById("post-" + mention.post + "-" + _this.action)) { + _this.append(mention.post, mention.entity, dom_element); + } } } - }); + } } + + if(!entity) { + entity = node.status.entity + } + + var url = HostApp.serverUrl("post") + .replace(/\{entity\}/, encodeURIComponent(entity)) + .replace(/\{post\}/, id) + + "?profiles=entity&max_refs=20"; + + APICalls.get(url, { callback: callback }); } Conversation.prototype.appendMentioned = function(id, entity, node) { - var url = URI(Paths.mkApiRootPath("/posts")); - url.addSearch("mentioned_post", id); - url.addSearch("post_types", "https%3A%2F%2Ftent.io%2Ftypes%2Fpost%2Fstatus%2Fv0.1.0"); - var _this = this; var callback = function(resp) { - var statuses = JSON.parse(resp.responseText); + var statuses = JSON.parse(resp.responseText).mentions; + if (statuses) { + for (var i = 0; i < statuses.length; i++) { - for (var i = 0; i < statuses.length; i++) { + var status = statuses[i]; - var status = statuses[i]; - var dom_element = _this.getStatusDOMElement(status); - _this.body.appendChild(dom_element); - - _this.appendMentioned(status.id, status.entity, dom_element); + // don't load if it is already there + var not_already_there = !document.getElementById("post-" + status.post + "-" + _this.action); + if(not_already_there && status.type.startsWith("https://tent.io/types/status/v0")) { + _this.append(status.post, status.entity, node, true); + } + } } } - Paths.getURL(url.toString(), "GET", callback); + var url = HostApp.serverUrl("post") + .replace(/\{entity\}/, encodeURIComponent(entity)) + .replace(/\{post\}/, id); + + APICalls.get(url, { + callback: callback, + accept: "application/vnd.tent.post-mentions.v0+json" + }); } - // /posts?limit=10&mentioned_post=gnqqyt&post_types=https%3A%2F%2Ftent.io%2Ftypes%2Fpost%2Fstatus%2Fv0.1.0,https%3A%2F%2Ftent.io%2Ftypes%2Fpost%2Frepost%2Fv0.1.0 HTTP/1.1" 200 - 0.0582 + Conversation.prototype.makeTree = function() { + var root_ul = document.createElement("ol"); + root_ul.id = "conversation-tree"; + var root_li = this.body.firstChild; + root_ul.appendChild(root_li); + function addChildren(node) { + var ul = document.createElement("ol"); + node.appendChild(ul); + var children = node.cNode.children; + for (var i = 0; i < children.length; i++) { + var child = children[i].dom_node; + ul.appendChild(child); + addChildren(child); + }; + } + addChildren(root_li); + + this.body.parentNode.replaceChild(root_ul, this.body); + this.body = root_ul; + + var lis = this.body.querySelectorAll("li"); + for (var i = 0; i < lis.length; i++) { + lis[i].className += " " + (i % 2 == 0 ? "odd" : "even"); + }; + }; return Conversation; diff --git a/WebKit/scripts/controller/Mentions.js b/WebKit/scripts/controller/Mentions.js index b60de05..8140ba9 100644 --- a/WebKit/scripts/controller/Mentions.js +++ b/WebKit/scripts/controller/Mentions.js @@ -1,113 +1,205 @@ define([ - "helper/HostApp", - "controller/Timeline", - "lib/URI", - "helper/Paths", - "helper/Core" + "helper/HostApp", + "controller/Timeline", + "lib/URI", + "helper/APICalls", + "helper/Core" ], -function(HostApp, Timeline, URI, Paths, Core) { +function(HostApp, Timeline, URI, APICalls, Core) { - function Mentions() { + function Mentions() { - this.is_not_init = false; - this.unread_mentions = 0; + this.is_not_init = false; + this.unread_mentions = 0; - Timeline.call(this); + Timeline.call(this); - this.action = "mentions"; - this.body.className = this.action; - - this.hide(); - } + this.action = "mentions"; + this.container.className = this.action; + + this.hide(); + } - Mentions.prototype = Object.create(Timeline.prototype); + Mentions.prototype = Object.create(Timeline.prototype); - Mentions.prototype.show = function() { - Core.prototype.show.call(this, this.body); - } + Mentions.prototype.show = function() { + Core.prototype.show.call(this, this.container); + } - Mentions.prototype.hide = function() { - Core.prototype.hide.call(this, this.body); - } + Mentions.prototype.hide = function() { + Core.prototype.hide.call(this, this.container); + } - Mentions.prototype.newStatus = function(statuses) { + Mentions.prototype.newStatus = function(statuses, append) { - Timeline.prototype.newStatus.call(this, statuses); + Timeline.prototype.newStatus.call(this, statuses, append); - if(this.is_not_init) { + if(this.is_not_init) { + for (var i = 0; i < statuses.posts.length; i++) { + + var status = statuses.posts[i]; + var name = bungloo.cache.profiles[status.entity] ? bungloo.cache.profiles[status.entity].name : status.entity - this.unread_mentions += statuses.length; - HostApp.unreadMentions(this.unread_mentions); + if(!append && status.type.startsWith("https://tent.io/types/status/v0#")) { + HostApp.notificateUserAboutMention(status.content.text, name, status.id, status.entity); + } + } + } - for (var i = 0; i < statuses.length; i++) { - var status = statuses[i]; + this.is_not_init = true; + } - var name; - var profile = this.cache.profiles.getItem(status.entity); - if(profile) { - name = profile["https://tent.io/types/info/basic/v0.1.0"].name; - } + Mentions.prototype.getNewData = function(add_to_search, append, query) { - HostApp.notificateUserAboutMention(status.content.text, name || status.entity, status.id, status.entity); - }; - } + add_to_search = add_to_search || {}; - this.is_not_init = true; - } + if (!add_to_search["mentions"]) { + add_to_search["mentions"] = HostApp.stringForKey("entity"); + } - Mentions.prototype.getNewData = function(add_to_search) { + Timeline.prototype.getNewData.call(this, add_to_search, append, query); - add_to_search = add_to_search || {}; + this.getLatestMentionRead(); + } - if (!add_to_search["mentioned_entity"]) { - add_to_search["mentioned_entity"] = HostApp.stringForKey("entity"); - } + Mentions.prototype.mentionRead = function(id, entity) { + if (this.unread_mentions > 0) { + this.unread_mentions--; + HostApp.unreadMentions(this.unread_mentions); + } + } - Timeline.prototype.getNewData.call(this, add_to_search); - } + Mentions.prototype.setAllMentionsRead = function() { + this.unread_mentions = 0; + HostApp.unreadMentions(this.unread_mentions); + this.updateLatestMentionRead(); + } - Mentions.prototype.mentionRead = function(id, entity) { - if (this.unread_mentions > 0) { - this.unread_mentions--; - HostApp.unreadMentions(this.unread_mentions); - } - } + Mentions.prototype.updateLatestMentionRead = function() { - Mentions.prototype.setAllMentionsRead = function() { - this.unread_mentions = 0; - HostApp.unreadMentions(this.unread_mentions); - this.updateLatestMentionRead(); - } + var cursor_url = HostApp.serverUrl("posts_feed") + "?types=" + "https://tent.io/types/cursor/v0"; - Mentions.prototype.updateLatestMentionRead = function() { - var status = this.body.firstChild.status; + // find the first real post + for (var i = 0; i < this.body.childNodes.length; i++) { - if (status && status.type == "https://tent.io/types/post/status/v0.1.0") { + var status = this.body.childNodes[i].status; - var url = URI(Paths.mkApiRootPath("/profile/" + encodeURIComponent("https://tent.io/types/info/cursor/v0.1.0"))); - var body = { - "https://tent.io/types/info/cursor/v0.1.0": { - "mentions": { - "https://tent.io/types/post/status/v0.1.0": { - "post_id": status.id, - "post_entity": status.entity - } - } - } - } + if (!status.__repost) { + if (status && status.type.startsWith("https://tent.io/types/status/v0#")) { - var callback = function(resp) { - //debug(resp) - } + // First find out if there is such a cursor or if we need to create it first + APICalls.get(cursor_url, { callback: function(resp) { - Paths.getURL(url.toString(), "PUT", callback, JSON.stringify(body)); - } - } + var posts = JSON.parse(resp.responseText).posts; + var mentions_post = null; + + for (var i = 0; i < posts.length; i++) { + var post = posts[i]; + + if(post.type == "https://tent.io/types/cursor/v0#https://tent.io/rels/status-mentions") { + + mentions_post = post; + + } + }; + + // Now prepare the cursor + + + var data = { + type: "https://tent.io/types/cursor/v0#https://tent.io/rels/status-mentions", + content: {}, + permissions: { + public: false, + }, + refs: [ + { + "post": status.id, + "type": status.type, + "entity": status.entity + } + ] + }; + + // update version if the post exists + if(mentions_post) { + data.version = { + parents: [ + { + version: mentions_post.version.id + } + ] + } + } + + var options = { + content_type: data.type, + accept: 'application/vnd.tent.post.v0+json; type="https://tent.io/types/cursor/v0#https://tent.io/rels/status-mentions"', + callback: function(resp) { + + }}; + + // either update or create the cursor + if(mentions_post) { + var url = HostApp.serverUrl("post") + .replace(/\{entity\}/, encodeURIComponent(HostApp.stringForKey("entity"))) + .replace(/\{post\}/, mentions_post.id) + APICalls.put(url, JSON.stringify(data), options); + } else { + var url = HostApp.serverUrl("posts_feed"); + APICalls.post(url, JSON.stringify(data), options); + } + + }}); + } + + break; + } + } + + } - return Mentions; + Mentions.prototype.getLatestMentionRead = function() { + + var cursor_url = HostApp.serverUrl("posts_feed") + "?types=" + "https://tent.io/types/cursor/v0"; + + APICalls.get(cursor_url, { callback: function(resp) { + + var posts = JSON.parse(resp.responseText).posts; + + for (var i = 0; i < posts.length; i++) { + var post = posts[i]; + + if(post.type == "https://tent.io/types/cursor/v0#https://tent.io/rels/status-mentions") { + + var since = post.version.received_at; + var post_id = post.refs[0].post; + var post_types = [ + "https://tent.io/types/status/v0#reply", + "https://tent.io/types/status/v0#" + ]; + + var uri = URI(HostApp.serverUrl("posts_feed")); + uri.addSearch("types", post_types.join(",")); + uri.addSearch("since", since); + uri.addSearch("mentions", HostApp.stringForKey("entity")); + + APICalls.head(uri.toString(), { callback: function(resp) { + + this.unread_mentions = APICalls.getCount(resp); + HostApp.unreadMentions(this.unread_mentions); + + }}); + } + }; + + }}); + } + + return Mentions; }); \ No newline at end of file diff --git a/WebKit/scripts/controller/NewPost.js b/WebKit/scripts/controller/NewPost.js new file mode 100644 index 0000000..e489041 --- /dev/null +++ b/WebKit/scripts/controller/NewPost.js @@ -0,0 +1,396 @@ +define([ + "helper/APICalls", + "helper/HostApp" +], + +function(APICalls, HostApp) { + + function NewPost() { + + this.profiles = JSON.parse(controller.getCachedProfiles()); + for (var key in this.profiles) { + var item = this.profiles[key]; + if(!item.entity) item.entity = key; + if(!item.name) item.name = key; + } + + this.mentions = []; + document.body.className = "new_post"; + this.is_private = false; + + // Textarea + + this.container = $("
"); + this.textarea = this.container.find("textarea"); + this.highlighter = this.container.find("div"); + + $(document.body).append(this.container); + + var _this = this; + + this.textarea.keyup(function(e) { _this.keyup(e) }); + this.textarea.keydown(function(e) { _this.keydown(e) }); + + this.suggestions = $("
    "); + + $(document.body).append(this.suggestions); + + // Status bar + this.counter = $("256"); + var buttons = $( + "

    " + + //"" + + " " + + "" + + "

    "); + + this.buttons = { + images: buttons.find("#images"), + is_private: buttons.find("#private"), + send: buttons.find("#send") + } + + //this.buttons.images.bind("click", this.addImage.bind(this)); + + this.buttons.is_private.bind("click", function(e) { _this.toggleIsPrivate(e) ; } ); + this.buttons.send.bind("click", function (e) { _this.send(e); }); + + this.container.find("#status_bar").append(this.counter); + this.container.find("#status_bar").append(buttons); + + this.textarea.focus(); + this.setIsPrivate(false); + } + + NewPost.prototype.setStatus = function(status_string) { + if (status_string && status_string.length > 0) { + this.status = JSON.parse(status_string); + this.setIsPrivate(this.status.permissions && !this.status.permissions.public); + this.setMentions(this.status); + } else { + this.status = null; + } + + // FIXME set string, private, mentions, etc. + }; + + NewPost.prototype.setString = function(string) { + this.textarea.val(string); + } + + NewPost.prototype.setMentions = function(status) { + + var mentions = [this.profiles[status.entity]]; + var text = this.profiles[status.entity].name + " "; + var start = text.length; + + if(status.mentions && status.mentions.length > 0) { + + var mentions_text = "" + for (var i = 0; i < status.mentions.length; i++) { + + var entity = status.mentions[i].entity; + + // Sometimes there are mentions without entity, don't know why + if(entity && entity != HostApp.stringForKey("entity")) { + // fix broken profiles + var profile = this.profiles[entity]; + if(!profile) { + profile = {}; + this.profiles[entity] = profile; + } + if(!profile.entity) profile.entity = entity; + if(!profile.name) profile.name = entity; + + // add profile to mentions and textarea + mentions.push(profile); + mentions_text += profile.name; + + // add space after mention + if(i < status.mentions.length) { + mentions_text += " "; + } + } + } + if (mentions_text.length > 0) { + text += "\n\n/cc " + mentions_text; + }; + + } + + this.mentions = mentions; + this.textarea.val(text); + this.parseText(text); + + // Select other mentions so user can start writing and removing them + var end = text.length; + this.textarea.get(0).setSelectionRange(start, end); + } + + NewPost.prototype.setIsPrivate = function(is_private) { + this.is_private = is_private; + if (this.is_private) { + this.buttons.is_private.find("img").attr("src", "img/private.png"); + } else { + this.buttons.is_private.find("img").attr("src", "img/public.png"); + } + } + + NewPost.prototype.toggleIsPrivate = function() { + this.setIsPrivate(!this.is_private); + } + + NewPost.prototype.keyup = function(e) { + if(!e) return; + + var key = e.which; + if(key != 38 && key != 40 && key != 13) { + + this.applyText($(this.textarea).val()); + + } else { + + var lis = this.suggestions.find("li"); + + if (lis.length > 0) { + e.preventDefault(); + var active = this.suggestions.find(".active"); + if(key == 38) { // up + var prev = active.prev(); + if(active.lentgh == 0) { + lis.last().addClass("active"); + } else if(prev) { + active.removeClass("active"); + prev.addClass("active"); + } + } else if(key == 40) { // down + var next = active.next(); + if(active.length == 0) { + lis.first().addClass("active"); + } else if(next) { + active.removeClass("active"); + next.addClass("active"); + } + } else if(key == 13) { // enter + if(active.length > 0) { + this.replaceWithName(this.textarea.val(), this.suggestions.find("li.active").get(0).item); + } + } + } + } + } + + NewPost.prototype.keydown = function(e) { + var key = e.which; + var lis = this.suggestions.find("li"); + if(lis.length > 0 && (key == 38 || key == 40 || key == 13)) { + e.preventDefault(); + } + } + + NewPost.prototype.replaceAll = function(txt, replace, with_this) { + return txt.replace(new RegExp(replace, 'g'), with_this); + } + + NewPost.prototype.replaceWithName = function(txt, with_item) { + var words = txt.match(/(^|\s)\^([^\s]+)/); + var replace = words[2]; + + var original = txt.replace("^" + replace, with_item.name + " "); + this.textarea.val(original); + + this.mentions.push(with_item); + + this.applyText(original); + } + + NewPost.prototype.applyText = function (text) { + var words = text.match(/(^|\s)\^([^\s]+)/); + this.suggestions.html(""); + + if(words) { + var name = words[2]; + for (var key in this.profiles) { + var item = this.profiles[key]; + if((item.name.toLowerCase().indexOf(name.toLowerCase()) != -1) || item.entity.toLowerCase().indexOf(name.toLowerCase()) != -1) { + var li = $("
  • " + item.name + "
  • ") + li.get(0).item = item; + this.suggestions.append(li); + } + } + this.suggestions.find("li:first-child").addClass("active"); + } + + this.parseText(text); + } + + NewPost.prototype.parseText = function(text) { + // parse the text: + // replace all the line braks by
    , and all the double spaces by the html version   + text = this.replaceAll(text,'\n','
    '); + //text = this.replaceAll(text,' ','  '); + + // replace the words by a highlighted version of the words + + var remove = []; + + for (var i=0;i' + name + ''); + } else { + remove.push(this.mentions[i]); + } + } + + for (var i = 0; i < remove.length; i++) { + this.mentions.splice(this.mentions.indexOf(remove[i]), 1); + } + + // re-inject the processed text into the div + this.highlighter.html(text); + + var count = 256 - (this.textarea.val().length + (this.mentions.length * 6)); + this.counter.html(count); + } + + NewPost.prototype.send = function() { + + var count = 256 - (this.textarea.val().length + (this.mentions.length * 6)); + if(count >= 0 && count <= 256) { + this.sendNewMessage(); + return true; + } else { + return false; + } + } + + NewPost.prototype.sendNewMessage = function() { + + var content = this.textarea.val(); + + var data = { + type: "https://tent.io/types/status/v0#", + content: { + text: content + }, + permissions: { + public: !this.is_private + } + }; + + var mentions = []; + for (var i = 0; i < this.mentions.length; i++) { + var mention = this.mentions[i]; + if(this.status && this.status.entity == mention.entity) { + mentions.push({ + entity: this.status.entity, + post: this.status.id, + type: this.status.type + }); + } else { + mentions.push({ + entity: mention.entity + }); + } + } + + data.mentions = mentions; + + // Make tent flavored markdown mentions + for (var i = 0; i < this.mentions.length; i++) { + var mention = this.mentions[i]; + data.content.text = this.replaceAll(data.content.text, mention.name, "^[" + mention.name + "](" + i + ")") + } + + APICalls.post(HostApp.serverUrl("new_post"), JSON.stringify(data), { + content_type: data.type, + accept: 'application/vnd.tent.post.v0+json; type="https://tent.io/types/status/v0#"', + callback: function(resp) { + if (resp.status >= 200 < 300) { + new_post_window.closeWindow(); + controller.getNewData(); + } else { + new_post_window.beep(); + } + } + }); + } +/* + NewPost.prototype.sendNewMessageWithImage = function(content, in_reply_to_status_id, in_reply_to_entity, location, image_data_uri, is_private, callback) { + + var url = URI(APICalls.mkApiRootPath("/posts")); + + var data = { + "type": "https://tent.io/types/post/photo/v0.1.0", + "published_at": parseInt(new Date().getTime() / 1000, 10), + "permissions": { + "public": !is_private + }, + "content": { + "caption": content, + }, + }; + + if (location) { + data["content"]["location"] = { "type": "Point", "coordinates": location } + } + + var mentions = this.parseMentions(content, in_reply_to_status_id, in_reply_to_entity); + if (mentions.length > 0) { + data["mentions"] = mentions; + if (is_private) { + var entities = {}; + for (var i = 0; i < mentions.length; i++) { + var entity = mentions[i]["entity"] + entities[entity] = true; + }; + + data["permissions"]["entities"] = entities; + } + } + + var data_string = JSON.stringify(data); + + var boundary = "TentAttachment----------TentAttachment"; + var post = "--" + boundary + "\r\n"; + + post += 'Content-Disposition: form-data; name="post"; filename="post.json"\r\n'; + post += 'Content-Length: ' + data_string.length + '\r\n'; + post += 'Content-Type: application/vnd.tent.v0+json\r\n'; + post += 'Content-Transfer-Encoding: binary\r\n\r\n'; + post += data_string; + + post += "\r\n--" + boundary + "\r\n"; + + var blob_string = image_data_uri.split(',')[1]; + var mime_type = image_data_uri.split(',')[0].split(':')[1].split(';')[0]; + var ext = "png"; + if (mime_type == "image/jpeg") { + ext = "jpeg"; + } else if (mime_type == "image/gif") { + ext = "gif"; + } + + + post += 'Content-Disposition: form-data; name="photos[0]"; filename="photo.' + ext + '"\r\n'; + post += 'Content-Length: ' + blob_string.length + "\r\n"; + post += 'Content-Type: ' + mime_type + "\r\n"; + post += 'Content-Transfer-Encoding: base64\r\n\r\n'; + post += blob_string; + post += "\r\n--" + boundary + "--\r\n"; + + var newCallback = function(resp) { + if (resp.status == 403) { + var err = JSON.parse(resp.responseText); + HostApp.alertTitleWithMessage(resp.statusText, err.error); + } + callback(resp); + } + + APICalls.postMultipart(url.toString(), newCallback, post, boundary); + } +*/ + + return NewPost; +}) \ No newline at end of file diff --git a/WebKit/scripts/controller/Oauth.js b/WebKit/scripts/controller/Oauth.js index e4c04cc..6ce5019 100644 --- a/WebKit/scripts/controller/Oauth.js +++ b/WebKit/scripts/controller/Oauth.js @@ -1,30 +1,45 @@ define([ "helper/HostApp", - "helper/Paths", + "helper/APICalls", "helper/Hmac" ], -function(HostApp, Paths, Hmac) { +function(HostApp, APICalls, Hmac) { function Oauth() { this.app_info = { - "id": null, - "name": "Bungloo on " + HostApp.osType(), - "description": "A small TentStatus client.", - "url": "http://jabs.nu/bungloo/", - "icon": "http://jabs.nu/bungloo/icon.png", - "redirect_uris": [ - "bungloo://oauthtoken" - ], - "scopes": { - "read_posts": "Uses posts to show them in a list", - "write_posts": "Posts on users behalf", - "read_profile": "Displays your own profile", - "write_profile": "Updating profile and mentions pointer", - "read_followers": "Display a list of people who follow you", - "write_followers": "Be able to block people who follow you", - "read_followings": "Display following list and their older posts in conversations", - "write_followings": "Follow ne entities" + "type": "https://tent.io/types/app/v0#", + "content": { + "name": "Bungloo on " + HostApp.osType(), + "url": "http://jabs.nu/bungloo/", + "description": "A desktop Tent client.", + "redirect_uri": "bungloo://oauthtoken", + "types": { + "read": [ + "https://tent.io/types/meta/v0", + "https://tent.io/types/relationship/v0", + "https://tent.io/types/subscription/v0", + "https://tent.io/types/delete/v0", + "https://tent.io/types/status/v0", + "https://tent.io/types/repost/v0", + "https://tent.io/types/photo/v0", + "https://tent.io/types/cursor/v0", + "https://tent.io/types/basic-profile/v0" + ], + "write": [ + "https://tent.io/types/relationship/v0", + "https://tent.io/types/subscription/v0", + "https://tent.io/types/delete/v0", + "https://tent.io/types/status/v0", + "https://tent.io/types/repost/v0", + "https://tent.io/types/photo/v0", + "https://tent.io/types/cursor/v0" + ] + }, + "scopes": ["permissions"] + }, + "permissions": { + "public": false } }; this.register_data = null; @@ -33,110 +48,121 @@ function(HostApp, Paths, Hmac) { } Oauth.prototype.isAuthenticated = function() { - return HostApp.stringForKey("user_access_token") != null; + return !!HostApp.stringForKey("user_access_token"); } Oauth.prototype.authenticate = function() { var entity = HostApp.stringForKey("entity"); - if (entity && (entity.startsWith("http://") || entity.startsWith("https://"))) { - this.entity = entity; - this.requestProfileURL(this.entity); + if (entity && entity.startsWith("http")) { + if((entity.startsWith("http://") || entity.startsWith("https://"))) { + this.entity = entity; + this.requestProfileURL(this.entity); + } else { + this.entity = "https://" + entity; + HostApp.setStringForKey(this.entity, "entity"); + this.requestProfileURL(this.entity); + } } else { HostApp.authentificationDidNotSucceed("The entity should start with https:// or http://"); } } - Oauth.prototype.apiRoot = function() { - return this.profile["https://tent.io/types/info/core/v0.1.0"]["servers"][0]; - } - Oauth.prototype.requestProfileURL = function (entity) { - var those = this; - Paths.findProfileURL(entity, + var _this = this; + APICalls.findProfileURL(entity, function(profile_url) { if (profile_url && (profile_url.startsWith("http://") || profile_url.startsWith("https://"))) { - those.register(profile_url); + _this.register(profile_url); } else { HostApp.authentificationDidNotSucceed("Could not find profile for: " + entity); } }, function(errorMessage) { // error callback + HostApp.authentificationDidNotSucceed(errorMessage); HostApp.authentificationDidNotSucceed("Could not find profile for: " + entity); } ); } Oauth.prototype.register = function (url) { - var those = this; + var _this = this; - Paths.getURL(url, "GET", function(resp) { + APICalls.get(url, { + no_auth: true, + callback: function(resp) { - those.profile = JSON.parse(resp.responseText); - those.entity = those.profile["https://tent.io/types/info/core/v0.1.0"].entity; - HostApp.setStringForKey(those.entity, "entity") - HostApp.setStringForKey(those.apiRoot(), "api_root"); + _this.profile = JSON.parse(resp.responseText).post; + _this.entity = _this.profile.content.entity; + HostApp.setStringForKey(_this.entity, "entity") + HostApp.setServerUrls(_this.profile.content.servers[0].urls); + APICalls.post(HostApp.serverUrl("new_post"), JSON.stringify(_this.app_info), { + content_type: "https://tent.io/types/app/v0#", + no_auth: true, + callback: function(resp) { + var app_id = JSON.parse(resp.responseText).post.id; + var header_string = resp.getAllResponseHeaders(); + var regexp = /https:\/\/tent.io\/rels\/credentials/i + var url = APICalls.parseHeaderForLink(header_string, regexp); - var callback = function(resp) { - var data = JSON.parse(resp.responseText); - those.authRequest(data); - } - Paths.getURL(Paths.mkApiRootPath("/apps"), "POST", callback, JSON.stringify(those.app_info), false); - }, null, false); + APICalls.get(url, { + content_type: "https://tent.io/types/app/v0#", + no_auth: true, + callback: function(resp) { + var data = JSON.parse(resp.responseText); + _this.authRequest(data.post, app_id); + } + }); + }}); + + }}); } - Oauth.prototype.authRequest = function(register_data) { - // id - // mac_key_id - // mac_key - // mac_algorithm - this.register_data = register_data; - - // Needed for later App Registration Modification - HostApp.setStringForKey(register_data["mac_key"], "app_mac_key"); - HostApp.setStringForKey(register_data["mac_key_id"], "app_mac_key_id"); - HostApp.setStringForKey(register_data["id"], "app_id"); - HostApp.setStringForKey(register_data["mac_algorithm"], "app_mac_algorithm"); - + Oauth.prototype.authRequest = function(credentials, app_id) { + + HostApp.setStringForKey(app_id, "app_id"); + HostApp.setStringForKey(credentials.id, "app_hawk_id"); + HostApp.setStringForKey(credentials.content.hawk_key, "app_hawk_key"); + HostApp.setStringForKey(credentials.content.hawk_algorithm, "app_hawk_algorithm"); + this.state = Hmac.makeid(19); - var auth = "/oauth/authorize?client_id=" + register_data["id"] - + "&redirect_uri=" + this.app_info["redirect_uris"][0] - + "&scope=" + Object.keys(this.app_info["scopes"]).join(",") - + "&state=" + this.state - + "&tent_post_types=all" - + "&tent_profile_info_types=all"; - - HostApp.openAuthorizationURL(this.apiRoot() + auth); + var url = HostApp.serverUrl("oauth_auth") + "?client_id=" + app_id + "&state=" + this.state; + HostApp.openAuthorizationURL(url); } Oauth.prototype.requestAccessToken = function(responseBody) { // /oauthtoken?code=51d0115b04d1ed94001dde751c5b360f&state=aQfH1VEohYsQr86qqyv + // https://app.example.com/oauth?code=K4m2J2bGI9rcICBqmUCYuQ&state=d173d2bb868a - var urlVars = Paths.getUrlVars(responseBody); + var urlVars = APICalls.getUrlVars(responseBody); if(this.state && this.state != "" && urlVars["state"] == this.state) { - var url = Paths.mkApiRootPath("/apps/") + this.register_data["id"] + "/authorizations"; + var url = HostApp.serverUrl("oauth_token"); var requestBody = JSON.stringify({ 'code' : urlVars["code"], - 'token_type' : "mac" + 'token_type': "https://tent.io/oauth/hawk-token" }); var those = this; - var http_method = "POST"; - var callback = function(resp) { - those.requestAccessTokenTicketFinished(resp.responseText); - }; - - var auth_header = Hmac.makeAuthHeader( + var auth_header = Hmac.makeHawkAuthHeader( url, - http_method, - HostApp.stringForKey("app_mac_key"), - HostApp.stringForKey("app_mac_key_id") + "POST", + HostApp.stringForKey("app_hawk_id"), + HostApp.stringForKey("app_hawk_key") ); - Paths.getURL(url, http_method, callback, requestBody, auth_header); + APICalls.post(url, requestBody, { + content_type: "application/json", + auth_header: auth_header, + callback: function(resp) { + debug(url) + debug(requestBody) + debug(auth_header) + debug(resp.responseText) + those.requestAccessTokenTicketFinished(resp.responseText); + }}); } else { console.error("State is not the same: {" + this.state + "} vs {" + urlVars["state"] + "}") @@ -150,16 +176,16 @@ function(HostApp, Paths, Hmac) { var access = JSON.parse(responseBody); HostApp.setStringForKey(access["access_token"], "user_access_token"); - HostApp.setSecret(access["mac_key"]); - HostApp.setStringForKey(access["mac_algorithm"], "user_mac_algorithm"); + HostApp.setSecret(access["hawk_key"]); + HostApp.setStringForKey(access["hawk_algorithm"], "user_hawk_algorithm"); HostApp.setStringForKey(access["token_type"], "user_token_type"); HostApp.loggedIn(); } - Oauth.prototype.logout = function() { + Oauth.prototype.logout = function() { // FIXME - var url = Paths.mkApiRootPath("/apps/" + HostApp.stringForKey("app_id")); + var url = APICalls.mkApiRootPath("/apps/" + HostApp.stringForKey("app_id")); var http_method = "DELETE"; var auth_header = Hmac.makeAuthHeader( url, @@ -168,7 +194,7 @@ function(HostApp, Paths, Hmac) { HostApp.stringForKey("app_mac_key_id") ); - Paths.getURL(url, http_method, function(resp) { + APICalls.http_call(url, http_method, function(resp) { HostApp.setStringForKey(null, "app_mac_key"); HostApp.setStringForKey(null, "app_mac_key_id"); HostApp.setStringForKey(null, "app_id"); diff --git a/WebKit/scripts/controller/Profile.js b/WebKit/scripts/controller/Profile.js index b3913d3..7f922ba 100644 --- a/WebKit/scripts/controller/Profile.js +++ b/WebKit/scripts/controller/Profile.js @@ -1,641 +1,665 @@ define([ - "helper/HostApp", - "helper/Core", - "helper/Paths", - "lib/URI" + "helper/HostApp", + "helper/Core", + "helper/APICalls", + "lib/URI", + "controller/Timeline" ], -function(HostApp, Core, Paths, URI) { +function(HostApp, Core, APICalls, URI, Timeline) { - function Profile() { + function Profile() { + + Timeline.call(this); + clearTimeout(this.reloadIntervall); // FIXME: reload for new data instead + + this.action = "profile"; - Core.call(this); + this.container = document.createElement("div"); + this.container.className = this.action; + document.getElementById("content").appendChild(this.container); - this.action = "profile"; + this.initProfileTemplate(); + this.hide(); + } - this.container = document.createElement("div"); - document.getElementById("content").appendChild(this.container); + Profile.prototype = Object.create(Timeline.prototype); + - this.initProfileTemplate(); - this.hide(); + Profile.prototype.show = function() { + Core.prototype.show.call(this, this.container); + } + + Profile.prototype.hide = function() { + Core.prototype.hide.call(this, this.container); + } + + Profile.prototype.logout = function() { + this.container = ""; + } + + Profile.prototype.showList = function(list) { + $(this.body).hide(); + $(this.followingsBody).hide(); + $(this.followersBody).hide(); + $(list).show(); + } + + Profile.prototype.showEntity = function(a, i) { + var entity = $(a).closest("li").get(0).status.mentions[i].entity; + this.showProfileForEntity(entity); + bungloo.sidebar.onEntityProfile(); + }; + + Profile.prototype.showProfileForEntity = function(entity) { + + if (!entity) { + entity = HostApp.stringForKey("entity"); + } + + this.clear(); + this.entity = entity; + this.following = null; + this.following_id = null; + this.profile_template.entity.innerHTML = this.entity; + this.profile_template.entity.href = this.entity; + + this.getProfile(); + this.getFollowing(); + this.getStatuses(); + } + + Profile.prototype.initProfileTemplate = function() { + + var _this = this; + + var header = document.createElement("header"); + header.className = "profile"; - var _this = this; - setTimeout(function() { _this.showProfileForEntity() }, 5000); // Load users profile on start - } + this.container.appendChild(header); - Profile.prototype = Object.create(Core.prototype); - + this.profile_template = { + avatar: document.createElement("img"), + name: document.createElement("h1"), + entity: document.createElement("a"), + bio: document.createElement("p"), + relationships: document.createElement("td"), + posts: document.createElement("a"), + following: document.createElement("a"), + followed: document.createElement("a"), + birthdate: document.createElement("td"), + location: document.createElement("td"), + gender: document.createElement("td"), + url: document.createElement("a"), + following_button: document.createElement("button"), + mention_button: document.createElement("button") + }; - Profile.prototype.show = function() { - Core.prototype.show.call(this, this.container); - } + header.appendChild(this.profile_template.avatar); + this.profile_template.avatar.src = "img/default-avatar.png"; + + var div = document.createElement("div"); + header.appendChild(div); + + this.profile_template.following_button.onclick = function(e) { + _this.toggleFollow() + } + div.appendChild(this.profile_template.following_button); + + this.profile_template.mention_button.onclick = function() { + HostApp.openNewMessageWidow({entity:_this.entity}); + } + div.appendChild(this.profile_template.mention_button); + this.profile_template.mention_button.innerHTML = "Mention"; + + div.appendChild(this.profile_template.name); + + var p = document.createElement("p"); + p.appendChild(this.profile_template.entity); + div.appendChild(p); + + div.appendChild(this.profile_template.bio); + + var table = document.createElement("table"); + div.appendChild(table); + + function mkLi(name, template) { + var tr = document.createElement("tr"); + var th = document.createElement("th"); + tr.style.display = "none"; + th.innerText = name + ": "; + tr.appendChild(th); + tr.appendChild(template); + table.appendChild(tr); + } + + mkLi("Birth date", this.profile_template.birthdate); + mkLi("Location", this.profile_template.location); + mkLi("Gender", this.profile_template.gender); + + var td = document.createElement("td"); + td.appendChild(this.profile_template.url); + mkLi("Homepage", td); + + mkLi("Relationships", this.profile_template.relationships); + + td = document.createElement("td"); + td.appendChild(this.profile_template.posts); + this.profile_template.posts.href = "#"; + this.profile_template.posts.onclick = function() { _this.showPosts(); return false; }; + mkLi("Posts", td); + + td = document.createElement("td"); + td.appendChild(this.profile_template.following); + this.profile_template.following.href = "#"; + this.profile_template.following.onclick = function() { _this.showFollowings(); return false; }; + mkLi("Following", td); + + td = document.createElement("td"); + td.appendChild(this.profile_template.followed); + this.profile_template.followed.href = "#"; + this.profile_template.followed.onclick = function() { _this.showFollowers(); return false; }; + mkLi("Followed by", td); + + + this.body = document.createElement("ol"); + this.body.className = this.action; + this.container.appendChild(this.body); + + this.followingsBody = document.createElement("ol"); + this.followingsBody.className = this.action + " followings"; + this.container.appendChild(this.followingsBody); + + this.followersBody = document.createElement("ol"); + this.followersBody.className = this.action + " folloewds"; + this.container.appendChild(this.followersBody); + + } + + Profile.prototype.clear = function() { + + this.server = null; + this.before = {id: null, entity: null, loading: false}; + + + this.profile_template.avatar.src = "img/default-avatar.png"; + + this.relationships = { + following_you: false, + followed_by_you: false, + it_is_you: false + } + + this.profile_template.name.innerText = ""; + this.profile_template.entity.innerText = ""; + this.profile_template.bio.innerText = ""; + this.profile_template.relationships.innerText = ""; + this.profile_template.posts.innerText = ""; + this.profile_template.following.innerText = ""; + this.profile_template.followed.innerText = ""; + this.profile_template.birthdate.innerText = ""; + this.profile_template.location.innerText = ""; + this.profile_template.gender.innerText = ""; + this.profile_template.url.innerText = ""; + this.profile_template.url.href = ""; + + this.profile_template.posts.parentNode.parentNode.style.display = "none"; + this.profile_template.following.parentNode.parentNode.style.display = "none"; + this.profile_template.followed.parentNode.parentNode.style.display = "none"; + this.profile_template.birthdate.parentNode.style.display = "none"; + this.profile_template.location.parentNode.style.display = "none"; + this.profile_template.gender.parentNode.style.display = "none"; + this.profile_template.url.parentNode.parentNode.style.display = "none"; + + this.profile_template.following_button.style.display = ""; + this.setFollowingButton(false); + + this.body.innerHTML = ""; + this.followingsBody.innerHTML = ""; + this.followersBody.innerHTML = ""; + + this.showList(this.body); + }; + + Profile.prototype.getProfile = function() { + + var _this = this; + + if (HostApp.stringForKey("entity") == this.entity) { + this.relationships.it_is_you = true; + this.profile_template.following_button.style.display = "none"; + } + + var url = HostApp.serverUrl("posts_feed") + "?types=" + encodeURIComponent("https://tent.io/types/meta/v0") + "&entities=" + encodeURIComponent(this.entity); + APICalls.get(url, { + callback: function(resp) { + var profile = JSON.parse(resp.responseText); + _this.showProfile(profile); + _this.profile = profile; + }}); + } + + Profile.prototype.getFollowing = function() { + if(this.entity != HostApp.stringForKey("entity")) { + + var url = HostApp.serverUrl("posts_feed") + "?mentions=" + encodeURIComponent(this.entity) + "&types=" + encodeURIComponent("https://tent.io/types/subscription/v0#https://tent.io/types/status/v0"); + var _this = this; + + APICalls.get(url, {callback: function(resp) { + + var json = JSON.parse(resp.responseText); + var count = json.posts.length; + + if (count > 0) { + _this.setFollowingButton(true); + _this.following_id = json.posts[0].id; + } else { + _this.setFollowingButton(false); + delete _this.following_id; + } + + }}); + + } else { + + this.setFollowingButton(false); + this.following_id = null; + } + } + + Profile.prototype.showProfile = function(profiles) { + + if(profiles.posts.length < 1) return; + var profile = profiles.posts[0]; + bungloo.cache.profiles[profile.entity] = profile.content.profile; + + var basic = profile.content.profile; + + if (profile && basic) { + + // Find and apply avatar + if(profile.attachments) { + + var digest = null; + for (var i = 0; i < profile.attachments.length; i++) { + var attachment = profile.attachments[i]; + if(attachment.category == "avatar") { + digest = attachment.digest; + break; + } + } + + if(digest) { + var _this = this; + this.profile_template.avatar.onerror = function() { _this.profile_template.avatar.src = 'img/default-avatar.png' }; + var avatar_url = profile.content.servers[0].urls.attachment.replace(/\{entity\}/, encodeURIComponent(profile.entity)); + this.profile_template.avatar.src = avatar_url.replace(/\{digest\}/, digest); + } + } + + this.populate(this.profile_template.name, basic.name); + this.populate(this.profile_template.birthdate, basic.birthdate); + this.populate(this.profile_template.location, basic.location); + this.populate(this.profile_template.gender, basic.gender); + this.populate(this.profile_template.bio, basic.bio); + + if(basic.website) { + + var url = basic.website; + this.profile_template.url.innerText = url; + this.profile_template.url.parentNode.parentNode.style.display = ""; + + if (!url.startsWith("http")) { + url = "http://" + url; + } + + this.profile_template.url.href = url; + } + } + + if (profile) { + this.profile = profile; + + // FIXME + this.getMeta(this.profile); + this.getStatuses(); + } + } + + Profile.prototype.populate = function(t, v) { + if (v) { + t.innerText = v; + t.parentNode.style.display = ""; + t.parentNode.parentNode.style.display = ""; + } + } + + Profile.prototype.getMeta = function(profile) { + + // FIXME! + + var _this = this; +/* + var url = HostApp.serverUrl("posts_feed") + "?entities=" + encodeURIComponent(this.entity) + "&types=" + encodeURIComponent("https://tent.io/types/subscription/v0#"); + APICalls.head(url, { + callback: function(resp) { + _this.populate(_this.profile_template.followed, APICalls.getCount(resp) + " "); + } + }); + + var url = HostApp.serverUrl("posts_feed") + "?entities=" + encodeURIComponent(this.entity) + "&types=" + encodeURIComponent("https://tent.io/types/relationship/v0#following"); + APICalls.head(url, { + callback: function(resp) { + _this.populate(_this.profile_template.following, APICalls.getCount(resp) + " "); + } + }); + + var url = HostApp.serverUrl("posts_feed") + "?entities=" + encodeURIComponent(this.entity) + "&types=" + encodeURIComponent("https://tent.io/types/status/v0#"); + APICalls.head(url, { + callback: function(resp) { + _this.populate(_this.profile_template.posts, APICalls.getCount(resp) + " "); + } + }); +*/ + + // is following you + // FIXME: should use HEAD + var url = HostApp.serverUrl("posts_feed") + "?entities=" + encodeURIComponent(this.entity) + "&types=" + encodeURIComponent("https://tent.io/types/subscription/v0#https://tent.io/types/status/v0") + "&mentions=" + encodeURIComponent(HostApp.stringForKey("entity")); + APICalls.get(url, { + callback: function(resp) { + var json = JSON.parse(resp.responseText); + if (json.posts.length > 0) { + _this.relationships.following_you = true; + } else { + _this.relationships.following_you = false; + } + _this.setRelationships(); + } + }); + + // is followed by you + // FIXME: should use HEAD + var url = HostApp.serverUrl("posts_feed") + "?mentions=" + encodeURIComponent(this.entity) + "&types=" + encodeURIComponent("https://tent.io/types/subscription/v0#https://tent.io/types/status/v0"); + APICalls.get(url, { + callback: function(resp) { + var json = JSON.parse(resp.responseText); + if (json.posts.length > 0) { + _this.relationships.followed_by_you = true; + } else { + _this.relationships.followed_by_you = false; + } + _this.setRelationships(); + } + }); + + return; +/* + + + if (this.entity != HostApp.stringForKey("entity")) { + APICalls.http_call(URI(root_url + "/followers/" + encodeURIComponent(HostApp.stringForKey("entity"))).toString(), "GET", function(resp) { + if (resp.status == 200) { + _this.relationships.following_you = true; + } + _this.setRelationships(); + + }, null, false); + + APICalls.http_call(URI(APICalls.mkApiRootPath("/followings/" + encodeURIComponent(this.entity))), "GET", function(resp) { + if (resp.status == 200) { + _this.relationships.followed_by_you = true; + } + _this.setRelationships(); + }); + + } else { + this.setRelationships(); + } + + + var url = URI(root_url + "/posts/count"); + var post_types = [ + "https://tent.io/types/post/repost/v0.1.0", + "https://tent.io/types/post/status/v0.1.0", + "https://tent.io/types/post/photo/v0.1.0" + ]; + url.addSearch("post_types", post_types.join(",")); + + APICalls.http_call(url.toString(), "GET", function(resp) { + + _this.populate(_this.profile_template.posts, resp.responseText); + }, null, false);*/ + } + + Profile.prototype.setRelationships = function() { + var relation = "none"; + if (HostApp.stringForKey("entity") == this.entity) { + relation = "it's you"; + } else { + if (this.relationships.following_you && !this.relationships.followed_by_you) { + relation = "is following you"; + } else if (this.relationships.following_you && this.relationships.followed_by_you) { + relation = "you both follow each other"; + } else if (!this.relationships.following_you && this.relationships.followed_by_you) { + relation = "being followed by you"; + } + } + this.populate(this.profile_template.relationships, relation); + } + + + Profile.prototype.getStatuses = function() { + this.since_time = null; + Timeline.prototype.getNewData.call(this, {entities: this.entity}); + } + + Profile.prototype.setFollowingButton = function(following) { + + this.following = following; + + if (following) { + this.profile_template.following_button.className = "following"; + this.profile_template.following_button.innerText = "Unfollow"; + } else { + this.profile_template.following_button.className = ""; + this.profile_template.following_button.innerText = "Follow"; + } + } + + Profile.prototype.toggleFollow = function() { + + var _this = this; + + if (this.following_id) { + + this.setFollowingButton(false); + + var url = HostApp.serverUrl("post").replace(/\{entity\}/, encodeURIComponent(HostApp.stringForKey("entity"))).replace(/\{post\}/, this.following_id); + APICalls.delete(url, { callback: function(resp) { + if (resp.status >= 200 && resp.status < 300) { + _this.setFollowingButton(false); + delete _this.following_id; + } else { + _this.setFollowingButton(true); + } + _this.getMeta(); + }}); + + } else { + + this.setFollowingButton(true); + + var url = HostApp.serverUrl("new_post"); + + var data = { + content: { + type: "https://tent.io/types/status/v0" + }, + mentions: [{ + entity: this.entity + }], + type: "https://tent.io/types/subscription/v0#https://tent.io/types/status/v0" + }; + + APICalls.post(url, JSON.stringify(data), { + content_type: data.type, + callback: function(resp) { + if (resp.status >= 200 && resp.status < 300) { + _this.setFollowingButton(true); + var json = JSON.parse(resp.responseText); + _this.following_id = json.post.id; + } else { + _this.setFollowingButton(false); + } + _this.getMeta(); + } + }); + } + } + + Profile.prototype.showPosts = function() { + this.showList(this.body); + } + + Profile.prototype.showFollowings = function() { + + this.showList(this.followingsBody); + this.followingsBody.innerHTML = ""; + + var _this = this; + var callback = function(resp) { + var followings = JSON.parse(resp.responseText); + for (var i = 0; i < followings.length; i++) { + var li = _this.getDOMSmallProfile(followings[i]); + _this.followingsBody.appendChild(li); + } + } + + var url = URI(this.server + "/followings"); + url.addSearch("limit", 200); + APICalls.http_call(url.toString(), "GET", callback, null, false); + } + + Profile.prototype.showFollowers = function() { + + this.showList(this.followersBody); + this.followersBody.innerHTML = ""; + + var _this = this; + var callback = function(resp) { + var followers = JSON.parse(resp.responseText); + for (var i = 0; i < followers.length; i++) { + var li = _this.getDOMSmallProfile(followers[i]); + _this.followersBody.appendChild(li); + } + } + + var url = URI(this.server + "/followers"); + url.addSearch("limit", 200); + APICalls.http_call(url.toString(), "GET", callback, null, false); + } + + Profile.prototype.getDOMSmallProfile = function(profile) { + + var li = document.createElement("li"); + + var image = document.createElement("img"); + image.title = profile.entity; + image.className = "image"; + image.src = 'img/default-avatar.png'; + li.appendChild(image); + image.onclick = function(e) { + HostApp.showProfileForEntity(e.target.title); + return false; + } + + var div = document.createElement("div"); + div.className = "data" + + var h1 = document.createElement("h1"); + var username = document.createElement("a"); + username.title = profile.entity; + username.className = "name"; + username.href = profile.entity; + username.onclick = function(e) { + HostApp.showProfileForEntity(profile.entity); + return false; + } + + h1.appendChild(username) + div.appendChild(h1); + li.appendChild(div); + + var p = document.createElement("p"); + p.className = "message"; + + var entity_tag = document.createElement("a"); + entity_tag.innerText = profile.entity; + entity_tag.href = profile.entity; + entity_tag.title = profile.entity; + + var new_line = document.createElement("br"); + var follows_since = document.createTextNode("follows since "); + var follows_since_time = document.createElement("span"); + follows_since_time.innerText = this.ISODateString(new Date(profile.created_at * 1000)); + follows_since_time.title = follows_since_time.innerText; + follows_since_time.className = "timeago"; + jQuery(follows_since_time).timeago(); + + p.appendChild(entity_tag); + p.appendChild(new_line); + p.appendChild(follows_since); + p.appendChild(follows_since_time); + div.appendChild(p); + + var profile_callback = function(p) { + + var basic = p["https://tent.io/types/info/basic/v0.1.0"]; + + if (p && basic) { + if(basic.name) { + username.title = username.innerText; + username.innerText = basic.name; + } + if(basic.avatar_url) { + image.onerror = function() { image.src = 'img/default-avatar.png'; }; + image.src = basic.avatar_url; + } + } + + } + + var p = this.cache.profiles.getItem(profile.entity); + + if (p && p != "null") { + + profile_callback(p); - Profile.prototype.hide = function() { - Core.prototype.hide.call(this, this.container); - } + } else { + + var _this = this; + APICalls.findProfileURL(profile.entity, function(profile_url) { - Profile.prototype.logout = function() { - this.container = ""; - } + if (profile_url) { + APICalls.http_call(profile_url, "GET", function(resp) { + var p = JSON.parse(resp.responseText); + if (p && p != "null") { + _this.cache.profiles.setItem(profile.entity, p); + profile_callback(p); + } + + }, null, false); // do not send auth-headers + } + }); + } - Profile.prototype.showList = function(list) { - $(this.body).hide(); - $(this.followingsBody).hide(); - $(this.followersBody).hide(); - $(list).show(); - }; - - Profile.prototype.showProfileForEntity = function(entity) { + return li; + } - if (!entity) { - entity = HostApp.stringForKey("entity"); - }; - - this.clear(); - this.entity = entity; - this.following = null; - this.following_id = null; - this.profile_template.entity.innerHTML = this.entity; - this.profile_template.entity.href = this.entity; - - this.getProfile(); - this.getFollowing(); - } - - Profile.prototype.initProfileTemplate = function() { - - var _this = this; - - var header = document.createElement("header"); - header.className = "profile"; - - this.container.appendChild(header); - this.profile_template = { - avatar: document.createElement("img"), - name: document.createElement("h1"), - entity: document.createElement("a"), - bio: document.createElement("p"), - relationships: document.createElement("td"), - posts: document.createElement("a"), - following: document.createElement("a"), - followed: document.createElement("a"), - birthdate: document.createElement("td"), - location: document.createElement("td"), - gender: document.createElement("td"), - url: document.createElement("a"), - following_button: document.createElement("button"), - mention_button: document.createElement("button") - }; - header.appendChild(this.profile_template.avatar); - this.profile_template.avatar.src = "img/default-avatar.png"; - var div = document.createElement("div"); - header.appendChild(div); - - this.profile_template.following_button.onclick = function(e) { - _this.toggleFollow() - } - div.appendChild(this.profile_template.following_button); - - this.profile_template.mention_button.onclick = function() { - var e = _this.entity; - if (e.startsWith("https://")) { - e = e.substr(8, e.length); - } - HostApp.openNewMessageWidow(null, null, "^" + e + " ", false); - } - div.appendChild(this.profile_template.mention_button); - this.profile_template.mention_button.innerHTML = "Mention"; - - div.appendChild(this.profile_template.name); - - var p = document.createElement("p"); - p.appendChild(this.profile_template.entity); - div.appendChild(p); - - div.appendChild(this.profile_template.bio); - - var table = document.createElement("table"); - div.appendChild(table); - - function mkLi(name, template) { - var tr = document.createElement("tr"); - var th = document.createElement("th"); - tr.style.display = "none"; - th.innerText = name + ": "; - tr.appendChild(th); - tr.appendChild(template); - table.appendChild(tr); - } - - mkLi("Birth date", this.profile_template.birthdate); - mkLi("Location", this.profile_template.location); - mkLi("Gender", this.profile_template.gender); - - var td = document.createElement("td"); - td.appendChild(this.profile_template.url); - mkLi("Homepage", td); - - mkLi("Relationships", this.profile_template.relationships); - - td = document.createElement("td"); - td.appendChild(this.profile_template.posts); - this.profile_template.posts.href = "#"; - this.profile_template.posts.onclick = function() { _this.showPosts(); return false; }; - mkLi("Posts", td); - - td = document.createElement("td"); - td.appendChild(this.profile_template.following); - this.profile_template.following.href = "#"; - this.profile_template.following.onclick = function() { _this.showFollowings(); return false; }; - mkLi("Following", td); - - td = document.createElement("td"); - td.appendChild(this.profile_template.followed); - this.profile_template.followed.href = "#"; - this.profile_template.followed.onclick = function() { _this.showFollowers(); return false; }; - mkLi("Followed by", td); - - - this.body = document.createElement("ol"); - this.body.className = this.action; - this.container.appendChild(this.body); - - this.followingsBody = document.createElement("ol"); - this.followingsBody.className = this.action + " followings"; - this.container.appendChild(this.followingsBody); - - this.followersBody = document.createElement("ol"); - this.followersBody.className = this.action + " folloewds"; - this.container.appendChild(this.followersBody); - - } - - Profile.prototype.clear = function() { - - this.server = null; - - this.profile_template.avatar.src = "img/default-avatar.png"; - - this.relationships = { - following_you: false, - followed_by_you: false, - it_is_you: false - } - - this.profile_template.name.innerText = ""; - this.profile_template.entity.innerText = ""; - this.profile_template.bio.innerText = ""; - this.profile_template.relationships.innerText = ""; - this.profile_template.posts.innerText = ""; - this.profile_template.following.innerText = ""; - this.profile_template.followed.innerText = ""; - this.profile_template.birthdate.innerText = ""; - this.profile_template.location.innerText = ""; - this.profile_template.gender.innerText = ""; - this.profile_template.url.innerText = ""; - this.profile_template.url.href = ""; - - this.profile_template.posts.parentNode.parentNode.style.display = "none"; - this.profile_template.following.parentNode.parentNode.style.display = "none"; - this.profile_template.followed.parentNode.parentNode.style.display = "none"; - this.profile_template.birthdate.parentNode.style.display = "none"; - this.profile_template.location.parentNode.style.display = "none"; - this.profile_template.gender.parentNode.style.display = "none"; - this.profile_template.url.parentNode.parentNode.style.display = "none"; - - this.profile_template.following_button.style.display = ""; - this.setFollowingButton(false); - - this.body.innerHTML = ""; - this.followingsBody.innerHTML = ""; - this.followersBody.innerHTML = ""; - - this.showList(this.body); - }; - - Profile.prototype.getProfile = function() { - - var _this = this; - - if (HostApp.stringForKey("entity") == this.entity) { - this.relationships.it_is_you = true; - this.profile_template.following_button.style.display = "none"; - } - - var profile = this.cache.profiles.getItem(this.entity); - - if (profile && profile != "null") { - - this.showProfile(profile); - this.profile = profile; - - } else { - Paths.findProfileURL(this.entity, function(profile_url) { - - if (profile_url) { - - Paths.getURL(profile_url, "GET", function(resp) { - - profile = JSON.parse(resp.responseText); - _this.showProfile(profile); - _this.profile = profile; - - }, null, false); // do not send auth-headers - } - }); - - } - } - - Profile.prototype.getFollowing = function() { - if(this.entity != HostApp.stringForKey("entity")) { - var url = Paths.mkApiRootPath("/followings") + "/" + encodeURIComponent(this.entity); - var _this = this; - Paths.getURL(url, "GET", function(resp) { - if (resp.status >= 200 && resp.status < 400) { - var following = JSON.parse(resp.responseText); - _this.following_id = following.id - _this.setFollowingButton(true); - } else { - _this.setFollowingButton(false); - _this.following_id = null; - } - }) - } else { - this.setFollowingButton(false); - this.following_id = null; - } - } - - Profile.prototype.showProfile = function(profile) { - - var basic = profile["https://tent.io/types/info/basic/v0.1.0"]; - - if (profile && basic) { - - if(basic.avatar_url) { - this.profile_template.avatar.onerror = function() { this.profile_template.avatar.src = 'img/default-avatar.png' }; - this.profile_template.avatar.src = basic.avatar_url; - } - - this.populate(this.profile_template.name, basic.name); - this.populate(this.profile_template.birthdate, basic.birthdate); - this.populate(this.profile_template.location, basic.location); - this.populate(this.profile_template.gender, basic.gender); - this.populate(this.profile_template.bio, basic.bio); - - if(basic.website_url) { - - var url = basic.website_url; - this.profile_template.url.innerText = url; - this.profile_template.url.parentNode.parentNode.style.display = ""; - - if (!url.startsWith("http")) { - url = "http://" + url; - } - - this.profile_template.url.href = url; - } - } - - if (profile) { - this.server = profile["https://tent.io/types/info/core/v0.1.0"]["servers"][0]; - this.getMeta(this.server); - this.getStatuses(this.server); - } - } - - Profile.prototype.populate = function(t, v) { - if (v) { - t.innerText = v; - t.parentNode.style.display = ""; - t.parentNode.parentNode.style.display = ""; - } - } - - Profile.prototype.getMeta = function(root_url) { - - var _this = this; - Paths.getURL(URI(root_url + "/followings/count").toString(), "GET", function(resp) { - - _this.populate(_this.profile_template.following, resp.responseText); - }, null, false); - - Paths.getURL(URI(root_url + "/followers/count").toString(), "GET", function(resp) { - - _this.populate(_this.profile_template.followed, resp.responseText); - }, null, false); - - if (this.entity != HostApp.stringForKey("entity")) { - Paths.getURL(URI(root_url + "/followers/" + encodeURIComponent(HostApp.stringForKey("entity"))).toString(), "GET", function(resp) { - if (resp.status == 200) { - _this.relationships.following_you = true; - } - _this.setRelationships(); - - }, null, false); - - Paths.getURL(URI(Paths.mkApiRootPath("/followings/" + encodeURIComponent(this.entity))), "GET", function(resp) { - if (resp.status == 200) { - _this.relationships.followed_by_you = true; - } - _this.setRelationships(); - }); - - } else { - this.setRelationships(); - } - - var url = URI(root_url + "/posts/count"); - var post_types = [ - "https://tent.io/types/post/repost/v0.1.0", - "https://tent.io/types/post/status/v0.1.0", - "https://tent.io/types/post/photo/v0.1.0" - ]; - url.addSearch("post_types", post_types.join(",")); - - Paths.getURL(url.toString(), "GET", function(resp) { - - _this.populate(_this.profile_template.posts, resp.responseText); - }, null, false); - } - - Profile.prototype.setRelationships = function() { - var relation = "none"; - if (this.relationships.it_is_you) { - relation = "it's you"; - } else { - if (this.relationships.following_you && !this.relationships.followed_by_you) { - relation = "is following you"; - } else if (this.relationships.following_you && this.relationships.followed_by_you) { - relation = "you both follow each other"; - } else if (!this.relationships.following_you && this.relationships.followed_by_you) { - relation = "being followed by you"; - } - } - this.populate(this.profile_template.relationships, relation); - } - - - Profile.prototype.getStatuses = function(root_url) { - var _this = this; - - var url = URI(root_url + "/posts"); - url.addSearch("limit", 20); - - var post_types = [ - "https://tent.io/types/post/repost/v0.1.0", - "https://tent.io/types/post/status/v0.1.0", - "https://tent.io/types/post/photo/v0.1.0" - ]; - url.addSearch("post_types", post_types.join(",")); - - Paths.getURL(url.toString(), "GET", function(resp) { - - var statuses = JSON.parse(resp.responseText); - - _this.newStatus(statuses); - - }, null, false); - } - - - Profile.prototype.newStatus = function(statuses) { - if(statuses != null && statuses.length > 0) { - for(var i = statuses.length-1, c=0; i>=c; --i) { - - var status = statuses[i]; - this.since_id = status.id; - this.since_id_entity = status.entity; - - if (status.type == "https://tent.io/types/post/status/v0.1.0" || status.type == "https://tent.io/types/post/photo/v0.1.0") { - - var new_node = this.getStatusDOMElement(status); - - if(this.body.childNodes.length > 0) { - - if(this.body.childNodes.length > this.max_length) { - - this.body.removeChild(this.body.lastChild); - } - - this.body.insertBefore(new_node, this.body.firstChild); - - } else { - - this.body.appendChild(new_node); - } - - } else if (status.type == "https://tent.io/types/post/delete/v0.1.0") { - - var li = document.getElementById("post-" + status.content.id); - if (li) { - this.body.removeChild(li); - } - } else if (status.type == "https://tent.io/types/post/repost/v0.1.0") { - - this.getRepost(status, this.body.firstChild); - } - - } - } - } - - Profile.prototype.mention = function() { - - } - - Profile.prototype.setFollowingButton = function(following) { - - this.following = following; - - if (following) { - this.profile_template.following_button.className = "following"; - this.profile_template.following_button.innerText = "Unfollow"; - } else { - this.profile_template.following_button.className = ""; - this.profile_template.following_button.innerText = "Follow"; - } - } - - Profile.prototype.toggleFollow = function() { - - var _this = this; - - if (this.following_id) { - - this.setFollowingButton(false); - var url = Paths.mkApiRootPath("/followings/") + this.following_id; - Paths.getURL(url, "DELETE", function(resp) { - if (resp.status >= 200 && resp.status < 300) { - _this.setFollowingButton(false); - _this.following_id = null; - } else { - _this.setFollowingButton(true); - } - }); - - } else { - - this.setFollowingButton(true); - var url = URI(Paths.mkApiRootPath("/followings")); - var data = JSON.stringify({"entity": this.entity }); - - Paths.getURL(url.toString(), "POST", function(resp) { - if (resp.status >= 200 && resp.status < 300) { - _this.following_id = JSON.parse(resp.responseText).id - _this.setFollowingButton(true); - } else { - _this.setFollowingButton(false); - } - }, data); - } - } - - Profile.prototype.showPosts = function() { - this.showList(this.body); - } - - Profile.prototype.showFollowings = function() { - - this.showList(this.followingsBody); - this.followingsBody.innerHTML = ""; - - var _this = this; - var callback = function(resp) { - var followings = JSON.parse(resp.responseText); - for (var i = 0; i < followings.length; i++) { - var li = _this.getDOMSmallProfile(followings[i]); - _this.followingsBody.appendChild(li); - } - } - - var url = URI(this.server + "/followings"); - url.addSearch("limit", 200); - Paths.getURL(url.toString(), "GET", callback, null, false); - } - - Profile.prototype.showFollowers = function() { - - this.showList(this.followersBody); - this.followersBody.innerHTML = ""; - - var _this = this; - var callback = function(resp) { - var followers = JSON.parse(resp.responseText); - for (var i = 0; i < followers.length; i++) { - var li = _this.getDOMSmallProfile(followers[i]); - _this.followersBody.appendChild(li); - } - } - - var url = URI(this.server + "/followers"); - url.addSearch("limit", 200); - Paths.getURL(url.toString(), "GET", callback, null, false); - } - - Profile.prototype.getDOMSmallProfile = function(profile) { - - var li = document.createElement("li"); - - var image = document.createElement("img"); - image.title = profile.entity; - image.className = "image"; - image.src = 'img/default-avatar.png'; - li.appendChild(image); - image.onclick = function(e) { - HostApp.showProfileForEntity(e.target.title); - return false; - } - - var div = document.createElement("div"); - div.className = "data" - - var h1 = document.createElement("h1"); - var username = document.createElement("a"); - username.title = profile.entity; - username.className = "name"; - username.href = profile.entity; - username.onclick = function(e) { - HostApp.showProfileForEntity(profile.entity); - return false; - } - - h1.appendChild(username) - div.appendChild(h1); - li.appendChild(div); - - var p = document.createElement("p"); - p.className = "message"; - - var entity_tag = document.createElement("a"); - entity_tag.innerText = profile.entity; - entity_tag.href = profile.entity; - entity_tag.title = profile.entity; - - var new_line = document.createElement("br"); - var follows_since = document.createTextNode("follows since "); - var follows_since_time = document.createElement("span"); - follows_since_time.innerText = this.ISODateString(new Date(profile.created_at * 1000)); - follows_since_time.title = follows_since_time.innerText; - follows_since_time.className = "timeago"; - jQuery(follows_since_time).timeago(); - - p.appendChild(entity_tag); - p.appendChild(new_line); - p.appendChild(follows_since); - p.appendChild(follows_since_time); - div.appendChild(p); - - var profile_callback = function(p) { - - var basic = p["https://tent.io/types/info/basic/v0.1.0"]; - - if (p && basic) { - if(basic.name) { - username.title = username.innerText; - username.innerText = basic.name; - } - if(basic.avatar_url) { - image.onerror = function() { image.src = 'img/default-avatar.png'; }; - image.src = basic.avatar_url; - } - } - - } - - var p = this.cache.profiles.getItem(profile.entity); - - if (p && p != "null") { - - profile_callback(p); - - } else { - - var _this = this; - Paths.findProfileURL(profile.entity, function(profile_url) { - - if (profile_url) { - Paths.getURL(profile_url, "GET", function(resp) { - var p = JSON.parse(resp.responseText); - if (p && p != "null") { - _this.cache.profiles.setItem(profile.entity, p); - profile_callback(p); - } - - }, null, false); // do not send auth-headers - } - }); - } - - return li; - } - - - return Profile; + return Profile; }); diff --git a/WebKit/scripts/controller/Search.js b/WebKit/scripts/controller/Search.js index 62b19a5..b083362 100644 --- a/WebKit/scripts/controller/Search.js +++ b/WebKit/scripts/controller/Search.js @@ -1,11 +1,11 @@ define([ "helper/HostApp", "helper/Core", - "helper/Paths", + "helper/APICalls", "lib/URI" ], -function(HostApp, Core, Paths, URI) { +function(HostApp, Core, APICalls, URI) { function Search() { @@ -14,7 +14,10 @@ function(HostApp, Core, Paths, URI) { this.action = "search"; + this.offset = 0; + this.container = document.createElement("div"); + this.container.className = this.action; document.getElementById("content").appendChild(this.container); this.body = document.createElement("ol"); @@ -23,11 +26,17 @@ function(HostApp, Core, Paths, URI) { this.form.className = this.action; this.input = document.createElement("input"); this.input.type = "search"; - this.input.placeholder = "Search ..."; + this.input.placeholder = "Search"; this.form.appendChild(this.input); + this.before = {loading: false}; + var _this = this; - this.form.onsubmit = function() { _this.doSearch(_this.input.value); return false; }; + this.form.onsubmit = function() { + _this.offset = 0; + _this.before = {loading: false}; + _this.doSearch(_this.input.value); return false; + }; this.form.action = "#"; this.container.appendChild(this.form); @@ -48,9 +57,11 @@ function(HostApp, Core, Paths, URI) { Core.prototype.hide.call(this, this.container); } - Search.prototype.doSearch = function(query) { + Search.prototype.doSearch = function(query, add_search, append) { - this.body.innerHTML = ""; // remove old results + add_search = add_search || {}; + + if(!append) this.body.innerHTML = ""; // remove old results if (query == "") return; this.input.value = query; @@ -62,45 +73,74 @@ function(HostApp, Core, Paths, URI) { url.addSearch("api_key", api_key); url.addSearch("text", query); + for (key in add_search) { + url.addSearch(key, add_search[key]); + } + var _this = this; - Paths.getURL(url.toString(), "GET", function(resp) { + APICalls.http_call(url.toString(), "GET", function(resp) { var results = JSON.parse(resp.responseText).results; - var statuses = []; - for (var i = 0; i < results.length; i++) { - var result = results[i].source; - var status = { - entity: result.entity, - content: { - text: result.content - }, - published_at: result.published_at, - id: result.public_id, - type: result.post_type, - version: result.post_version, - app: { - url: "http://skate.io", - name: "skate.io" - }, - mentions: [] + if (results && results.length > 0) { + + _this.before.loading = false; + + var statuses = []; + for (var i = 0; i < results.length; i++) { + var result = results[i].source; + var status = { + entity: result.entity, + content: { + text: result.content + }, + published_at: result.published_at, + id: result.public_id, + type: result.post_type, + version: result.post_version, + app: { + url: "http://skate.io", + name: "skate.io" + }, + mentions: [] + } + + statuses.push(status); } - statuses.push(status); - } + for(var i = 0; i < statuses.length; i++) { + var status = statuses[i]; + if (status.type == "https://tent.io/types/post/status/v0.1.0") { - for(var i = 0; i < statuses.length; i++) { - var status = statuses[i]; - if (status.type == "https://tent.io/types/post/status/v0.1.0") { - - var new_node = _this.getStatusDOMElement(status); - _this.body.appendChild(new_node); + var new_node = _this.getStatusDOMElement(status); + _this.body.appendChild(new_node); + } } + } else { + var noresult = document.createElement("p"); + noresult.className = "noresult"; + noresult.textContent = "No Results"; + _this.body.appendChild(noresult); } }, null, false); } + Search.prototype.getMoreStatusPosts = function() { + + if (!this.before.loading) { + + this.offset += 20; + + this.before.loading = true; + var add_search = { + "offset": this.offset + } + + this.doSearch(this.input.value, add_search, true); + } + } + Search.prototype.searchFor = function(query) { this.doSearch(query); bungloo.sidebar.onSearch(); diff --git a/WebKit/scripts/controller/Sidebar.js b/WebKit/scripts/controller/Sidebar.js index 81d5599..4c150ef 100644 --- a/WebKit/scripts/controller/Sidebar.js +++ b/WebKit/scripts/controller/Sidebar.js @@ -1,16 +1,13 @@ define([ "helper/HostApp", - "helper/Paths", - "helper/Cache" + "helper/APICalls", ], -function(HostApp, Paths, Cache) { +function(HostApp, APICalls) { function Sidebar() { - this.cache = new Cache(); - this.body = document.createElement("ul"); this.body.class = "sidebar"; @@ -20,27 +17,39 @@ function(HostApp, Paths, Cache) { this.menu.user = this.createItem("User", function() { _this.onEntity(); return false; }, "img/sidebar/user.png", "img/sidebar/user.png"); this.menu.timeline = this.createItem("Timeline", function() { _this.onTimeline(); return false; }, "img/sidebar/timeline.png", "img/sidebar/timeline_active.png", true); - this.menu.mentions = this.createItem("Mentions", function() { _this.onMentions(); return false; }, "img/sidebar/mentions.png", "img/sidebar/mentions_active.png"); - + this.menu.mentions = this.createItem("Mentions", function() { _this.onMentions(); return false; }, "img/sidebar/mentions.png", "img/sidebar/mentions_active.png"); this.menu.conversation = this.createItem("Conversation", function() { _this.onConversation(); return false; }, "img/sidebar/conversation.png", "img/sidebar/conversation_active.png"); this.menu.entityProfile = this.createItem("Profile", function() { _this.onEntityProfile(); return false; }, "img/sidebar/profile.png", "img/sidebar/profile_active.png"); - this.menu.search = this.createItem("Search", function() { _this.onSearch(); return false; }, "img/sidebar/search.png", "img/sidebar/search_active.png") + // FIXME when skate.io is available again: this.menu.search = this.createItem("Search", function() { _this.onSearch(); return false; }, "img/sidebar/search.png", "img/sidebar/search_active.png") this.body.appendChild(this.menu.user); this.body.appendChild(this.menu.timeline); this.body.appendChild(this.menu.mentions); this.body.appendChild(this.menu.conversation); this.body.appendChild(this.menu.entityProfile); - this.body.appendChild(this.menu.search); + //this.body.appendChild(this.menu.search); this.unreadMentionsSpan = document.createElement("span"); this.unreadMentionsSpan.className = "unread_mentions"; - this.menu.mentions.appendChild(this.unreadMentionsSpan); + this.menu.mentions.getElementsByTagName("a")[0].appendChild(this.unreadMentionsSpan); this.setUnreadMentions(0); + this.menu.conversation.getElementsByTagName("a")[0].ondblclick = function() { + var postId = bungloo.conversation.current_post_id; + var entity = bungloo.conversation.current_entity; + if (postId && entity) { + HostApp.showConversationViewForPostIdandEntity(postId, entity); + } + } + document.getElementById("sidebar").appendChild(this.body); + // initial seting of the class + document.body.className = "body-timeline"; + document.body.id = "with-sidebar"; + this.setEntityAvatar(); + this.setOnScroll(); } Sidebar.prototype.createItem = function(name, callback, src_inactive, src_active, active) { @@ -72,57 +81,39 @@ function(HostApp, Paths, Cache) { var entity = HostApp.stringForKey("entity"); this.menu.user.title = entity; - var img = this.menu.user.getElementsByTagName("img")[0]; - + var avatar = this.menu.user.getElementsByTagName("img")[0]; var _this = this; - var profile_callback = function(p) { + var url = HostApp.serverUrl("posts_feed") + "?types=" + encodeURIComponent("https://tent.io/types/meta/v0") + "&entities=" + encodeURIComponent(entity); + APICalls.get(url, { callback: function(resp) { + var profiles = JSON.parse(resp.responseText); - var basic = p["https://tent.io/types/info/basic/v0.1.0"]; + if(profiles.posts.length < 1) return; + var profile = profiles.posts[0]; + bungloo.cache.profiles[entity] = profile; - if (p && basic) { - if(basic.name) { - _this.menu.user.title = basic.name; - } - if(basic.avatar_url) { + // Find and apply avatar + if(profile.attachments) { - img.onerror = function() { - img.src = "img/sidebar/user.png"; - img.src_inactive = img.src; - img.src_active = img.src; + var digest = null; + for (var i = 0; i < profile.attachments.length; i++) { + var attachment = profile.attachments[i]; + if(attachment.category == "avatar") { + digest = attachment.digest; + break; } + } - img.src = basic.avatar_url; - img.src_inactive = basic.avatar_url; - img.src_active = basic.avatar_url; - + if(digest) { + var _this = this; + avatar.onerror = function() { avatar.src = 'img/default-avatar.png' }; + var avatar_url = profile.content.servers[0].urls.attachment.replace(/\{entity\}/, encodeURIComponent(profile.entity)); + avatar.src = avatar_url.replace(/\{digest\}/, digest); + avatar.src_inactive = avatar.src; + avatar.src_active = avatar.src; } } - - } - - var p = this.cache.profiles.getItem(entity); - - if (p && p != "null") { - - profile_callback(p); - - } else { - - Paths.findProfileURL(entity, function(profile_url) { - - if (profile_url) { - Paths.getURL(profile_url, "GET", function(resp) { - var p = JSON.parse(resp.responseText); - if (p && p != "null") { - _this.cache.profiles.setItem(entity, p); - profile_callback(p); - } - - }, null, false); // do not send auth-headers - } - }); - } + }}); } Sidebar.prototype.removeEntityAvatar = function() { @@ -150,6 +141,10 @@ function(HostApp, Paths, Cache) { } active_part.show(); + this.active_view = active_part; + + // Replace class + document.body.className = "body-" + active_li.className.split("-")[1]; // Show active icon for(var li in this.menu) { @@ -163,6 +158,48 @@ function(HostApp, Paths, Cache) { img.src = img.src_active; } + Sidebar.prototype.showContentForNext = function() { + + var parts = [ + "timeline", + "mentions", + "conversation", + "entityProfile", + "search" + ]; + + for (var i = 0; i < parts.length; i++) { + var part = parts[i]; + var img = this.menu[part].getElementsByTagName("img")[0]; + if (img.src.endsWith(img.src_active)) { + var next = parts[(i+1)%parts.length]; + //we must update unread badges for mentions cf https://github.com/jeena/Bungloo/issues/222 + if(next === "mentions"){ + bungloo.mentions.setAllMentionsRead(); + } + this.showContentFor(bungloo[next], this.menu[next]); + return; + } + } + } + + Sidebar.prototype.showContentForTimeline = function() { + this.showContentFor(bungloo.timeline, this.menu.timeline); + } + + // runs get more posts when scrolling down and + // it is possible for the active view + Sidebar.prototype.setOnScroll = function() { + var _this = this; + window.onscroll = function() { + if (document.body.scrollHeight <= (document.body.scrollTop + window.outerHeight)) { + if (typeof _this.active_view["getMoreStatusPosts"] != "undefined") { + _this.active_view.getMoreStatusPosts(); + } + } + } + } + Sidebar.prototype.setUnreadMentions = function(count) { this.unreadMentionsSpan.innerHTML = count == 0 ? "" : count; if (count > 0) { diff --git a/WebKit/scripts/controller/Timeline.js b/WebKit/scripts/controller/Timeline.js index 4888ee4..da16564 100644 --- a/WebKit/scripts/controller/Timeline.js +++ b/WebKit/scripts/controller/Timeline.js @@ -1,11 +1,11 @@ define([ "helper/Core", - "helper/Paths", + "helper/APICalls", "helper/HostApp", "lib/URI" ], -function(Core, Paths, HostApp, URI) { +function(Core, APICalls, HostApp, URI) { function Timeline() { @@ -14,15 +14,23 @@ function(Core, Paths, HostApp, URI) { this.action = "timeline"; this.reload_blocked = false; + this.posts_limit = 50; this.max_length = 200; this.timeout = 10 * 1000; // every 10 seconds this.since_id = null; this.since_id_entity = null; - this.since_time = 0; + this.since_time = null; + this.pages = {}; + this.next = null; + + this.before = {id: null, entity: null, loading: false}; + + this.container = document.createElement("div"); + this.container.className = this.action; this.body = document.createElement("ol"); - this.body.className = this.action; - document.getElementById("content").appendChild(this.body); + this.container.appendChild(this.body) + document.getElementById("content").appendChild(this.container); var _this = this; this.reloadIntervall = setInterval(function() { _this.getNewData() }, this.timeout); @@ -33,103 +41,149 @@ function(Core, Paths, HostApp, URI) { Timeline.prototype = Object.create(Core.prototype); Timeline.prototype.show = function() { - Core.prototype.show.call(this, this.body); + Core.prototype.show.call(this, this.container); } Timeline.prototype.hide = function() { - Core.prototype.hide.call(this, this.body); + Core.prototype.hide.call(this, this.container); } + Timeline.prototype.newStatus = function(_statuses, append) { - Timeline.prototype.newStatus = function(statuses) { + for (var entity in _statuses.profiles) { + if (_statuses.profiles[entity] != null) { + bungloo.cache.profiles[entity] = _statuses.profiles[entity]; + } else { + bungloo.cache.profiles[entity] = {}; + } + } + + this.pages = _statuses.pages; + if(_statuses.pages.next) this.next = _statuses.pages.next; + + statuses = _statuses.posts; + + this.before.loading = false; if(statuses != null && statuses.length > 0) { + + if (append) statuses = statuses.reverse(); + for(var i = statuses.length-1, c=0; i>=c; --i) { var status = statuses[i]; - this.since_id = status.id; - this.since_id_entity = status.entity; + if(!append) { + this.since_id = status.id; + this.since_id_entity = status.entity; + //this.since_time = status.received_at; + this.since_time = status.version.received_at; + } - if (status.type == "https://tent.io/types/post/status/v0.1.0" || status.type == "https://tent.io/types/post/photo/v0.1.0") { + if (status.type.startsWith("https://tent.io/types/status/v0#")) { - var new_node = this.getStatusDOMElement(status); + var new_node = this.getStatusDOMElement(status, _statuses.refs); + var old_node = document.getElementById(new_node.id); + + if (!old_node) { + if(!append && this.body.childNodes.length > 0) { - if(this.body.childNodes.length > 0) { + if(this.body.childNodes.length > this.max_length) { - if(this.body.childNodes.length > this.max_length) { + this.body.removeChild(this.body.lastChild); + } - this.body.removeChild(this.body.lastChild); + this.body.insertBefore(new_node, this.body.firstChild); + + } else { + + this.body.appendChild(new_node); } - - this.body.insertBefore(new_node, this.body.firstChild); - } else { - - this.body.appendChild(new_node); + debug(new_node.id); + old_node.parentNode.replaceChild(new_node, old_node); } - } else if (status.type == "https://tent.io/types/post/delete/v0.1.0") { + } else if (status.type == "https://tent.io/types/delete/v0#") { - HostApp.notificateViewsAboutDeletedPost(status.content.id, status.entity); + HostApp.notificateViewsAboutDeletedPost(status.refs[0].post, status.entity); - } else if (status.type == "https://tent.io/types/post/repost/v0.1.0") { + } else if (status.type.startsWith("https://tent.io/types/repost/v0#")) { + + this.getRepost(status, append ? this.body.lastChild : this.body.firstChild, append); - this.getRepost(status, this.body.firstChild); } } } } - Timeline.prototype.getNewData = function(add_to_search) { + Timeline.prototype.getNewData = function(add_to_search, append, query) { add_to_search = add_to_search || {}; var those = this; - var url = URI(Paths.mkApiRootPath("/posts")); + var url = HostApp.serverUrl("posts_feed"); - var post_types = [ - "https://tent.io/types/post/repost/v0.1.0", - "https://tent.io/types/post/status/v0.1.0", - "https://tent.io/types/post/delete/v0.1.0", - "https://tent.io/types/post/photo/v0.1.0" - ]; - url.addSearch("post_types", post_types.join(",")); + if(!query) { - url.addSearch("limit", this.max_length); + var uri = URI(url); - if(this.since_id) { - url.addSearch("since_id", this.since_id); - url.addSearch("since_id_entity", this.since_id_entity); - } + var post_types = [ + "https://tent.io/types/status/v0#", + "https://tent.io/types/status/v0#reply", + "https://tent.io/types/repost/v0#https://tent.io/types/status/v0", + "https://tent.io/types/delete/v0#", + //"https://tent.io/types/post/photo/v0.1.0" + ]; + uri.addSearch("types", post_types.join(",")); + //uri.addSearch("sort_by", "published_at"); + uri.addSearch("limit", this.posts_limit); + uri.addSearch("max_refs", 20); + uri.addSearch("profiles", "entity"); + uri.addSearch("sort_by", "version.received_at"); - for (key in add_to_search) { - url.addSearch(key, add_to_search[key]); - } - - var http_method = "GET"; - var callback = function(resp) { - - those.reload_blocked = false; - - try { - - var json = JSON.parse(resp.responseText) - those.newStatus(json); - - } catch (e) { - console.error(url + " JSON parse error"); - throw e; + if(this.since_time) { + uri.addSearch("since", this.since_time); } - } - var data = null; + for (key in add_to_search) { + uri.addSearch(key, add_to_search[key]); + } + + url = uri.toString(); + + } else { + url += query; + } if (HostApp.stringForKey("user_access_token")) { if (!this.reload_blocked) { this.reload_blocked = true; - Paths.getURL(url.toString(), http_method, callback, data); // FIXME: error callback + + APICalls.get(url, { callback: function(resp) { + // FIXME this is getting data when it shouldn't debug(resp.responseText) + + those.reload_blocked = false; + + try { + var json = JSON.parse(resp.responseText); + those.newStatus(json, append); + + } catch (e) { + console.error(url + " JSON parse error"); + throw e; + } + } }); + } + } + } + + Timeline.prototype.getMoreStatusPosts = function() { + if (!this.before.loading) { + if (this.next) { + this.before.loading = true; + this.getNewData({}, true, this.next); } } } diff --git a/WebKit/scripts/helper/APICalls.js b/WebKit/scripts/helper/APICalls.js new file mode 100644 index 0000000..202a7cb --- /dev/null +++ b/WebKit/scripts/helper/APICalls.js @@ -0,0 +1,318 @@ +define([ + "jquery", + "helper/HostApp", + "helper/Hmac", + "helper/Cache" +], + +function(jQuery, HostApp, Hmac, Cache) { + var APICalls = {}; + + APICalls.cache = new Cache(); + + APICalls.getUrlVars = function(url) { + var vars = [], hash; + if(url.indexOf("#") > -1) url = url.slice(0, url.indexOf("#")); + var hashes = url.slice(url.indexOf('?') + 1).split('&'); + for(var i = 0; i < hashes.length; i++) + { + hash = hashes[i].split('='); + vars.push(hash[0]); + vars[hash[0]] = hash[1]; + } + return vars; + } + + APICalls.http_call = function(options) { + + if (typeof options === "string") { + console.error(options + " not implemented yet") + return; + } + + var content_type = null; + + if((options.http_method == "POST" || options.http_method == "PUT") && !options.content_type) { + console.error("No content type for " + options.url); + return; + + } else { + if(options.content_type == "application/json") { + content_type = "application/json"; + } else if(options.content_type) { + content_type = "application/vnd.tent.post.v0+json; charset=UTF-8; type=\"" + options.content_type + "\""; + } + } + + var settings = { + beforeSend: function(xhr) { + if (options.data) xhr.setRequestHeader("Content-Length", options.data.length); + + if (options.accept) xhr.setRequestHeader("Accept", options.accept); + else xhr.setRequestHeader("Accept", "application/vnd.tent.post.v0+json"); + + var user_access_token = HostApp.stringForKey("user_access_token"); + if (!options.auth_header && !options.no_auth && user_access_token) { + var auth_header = Hmac.makeHawkAuthHeader( + options.url, + options.http_method, + user_access_token, + HostApp.secret()//, + //HostApp.stringForKey("app_id") + ); + xhr.setRequestHeader("Authorization", auth_header); + } else if(options.auth_header) { + xhr.setRequestHeader("Authorization", options.auth_header); + } else if(!options.no_auth) { + console.error("No user_access_token yet - " + options.url); + } + xhr.setRequestHeader("Cache-Control", "no-proxy"); + }, + url: options.url, + contentType: content_type, + type: options.http_method, + complete: options.callback, + data: options.data, + processData: false, + error: function(xhr, ajaxOptions, thrownError) { + console.error("HTTP CALL (" + xhr.status + ") " + xhr.statusText + " " + options.http_method + " URL(" + options.url + "): '" + xhr.responseText + "'"); + } + }; + + jQuery.ajax(settings); + } + + APICalls.head = function(url, options) { + var settings = { + url: url, + http_method: "HEAD", + }; + + for (var key in options) { + settings[key] = options[key]; + } + + APICalls.http_call(settings); + } + + APICalls.get = function(url, options) { + var settings = { + url: url, + http_method: "GET", + }; + + for (var key in options) { + settings[key] = options[key]; + } + + APICalls.http_call(settings); + } + + APICalls.post = function(url, data, options) { + var settings = { + url: url, + http_method: "POST", + data: data + }; + + for (var key in options) { + settings[key] = options[key]; + } + + APICalls.http_call(settings); + } + + APICalls.delete = function(url, options) { + var settings = { + url: url, + http_method: "DELETE" + }; + + for (var key in options) { + settings[key] = options[key]; + } + + APICalls.http_call(settings); + } + + APICalls.put = function(url, data, options) { + var settings = { + url: url, + http_method: "PUT", + data: data + }; + + for (var key in options) { + settings[key] = options[key]; + } + + APICalls.http_call(settings); + } + + + APICalls.postMultipart = function(url, callback, data, boundary, accepts) { + + accepts = accepts || "application/vnd.tent.v0+json"; + + jQuery.ajax({ + + beforeSend: function(xhr) { + xhr.setRequestHeader("Accept", accepts); + + if (data) xhr.setRequestHeader("Content-Length", data.length); + + var user_access_token = HostApp.stringForKey("user_access_token"); + + if (user_access_token) { + + auth_header = Hmac.makeAuthHeader( + url, + "POST", + HostApp.secret(), + user_access_token + ); + + xhr.setRequestHeader("Authorization", auth_header); + } + }, + url: url, + contentType: "multipart/form-data;boundary=" + boundary, + type: "POST", + complete: callback, + data: data, + processData: false, + error: function(xhr, ajaxOptions, thrownError) { + console.error("postMultipart (" + xhr.status + ")" + xhr.statusText + " (" + url + "): '" + xhr.responseText + "'"); + } + }); + } + + APICalls.findProfileURL = function(entity, callback, errorCallback) { + var profile_url = APICalls.cache.profile_urls.getItem(entity); + + if (profile_url && profile_url != "null") { + + callback(profile_url); + + } else { + + jQuery.ajax({ + url: entity, + type: "HEAD", + complete: function(resp) { + if(resp) { + var headers = resp.getAllResponseHeaders(); + + var profile_urls = APICalls.parseHeaderForProfiles(headers); + var profile_url = null; + if(profile_urls.length > 0) { + var profile_url = profile_urls[0]; + if (!profile_url.startsWith("http")) { + profile_url = entity + profile_url; + } + } + + if (profile_url) { + APICalls.cache.profile_urls.setItem(entity, profile_url); + callback(profile_url); + } else { + APICalls.http_call(entity, "GET", function(resp) { + + if (resp.status >= 200 && resp.status < 300) { + var doc = document.implementation.createHTMLDocument(""); + doc.documentElement.innerHTML = resp.responseText; + var links = $(doc).find("link[rel='https://tent.io/rels/meta-post']"); + + if (links.length > 0) { + var href = links.get(0).href; + APICalls.cache.profile_urls.setItem(entity, href); + if (!href.startsWith("http")) { + href = entity + href; + } + callback(href); + + } else { + if(errorCallback) errorCallback(entity + " has no profile URL"); + } + } else { + if(errorCallback) errorCallback(entity + " has no profile URL"); + } + + }, null, false, false); + + //if(errorCallback) errorCallback(entity + " has no profile URL"); + } + } + }, + error: function(xhr, ajaxOptions, thrownError) { + console.error("findProfileURL " + xhr.statusText + " (" + entity + "): " + xhr.responseText); + if (errorCallback) errorCallback(xhr.statusText + " - " + xhr.responseText) + } + }); + } + } + + APICalls.mkApiRootPath = function(path) { + + var api_root = HostApp.stringForKey("api_root"); + + if((api_root.substring(api_root.length - 1, api_root.length) != "/") && (path.substring(0, 1) != "/")) { + api_root += "/"; + } else if((api_root.substring(api_root.length - 1, api_root.length) == "/") && (path.substring(0, 1) == "/")) { + api_root = api_root.substring(0, api_root.length -1); + } + return api_root + path; + } + + APICalls.parseHeaderForProfiles = function(header_string) { + var regexp = /https:\/\/tent.io\/rels\/meta-post/i; + return APICalls.parseHeaderForLink(header_string, regexp); + } + + APICalls.parseHeader = function(header_string) { + var header_strings = header_string.split(/\n/); + var headers = {}; + for (var i = 0; i < header_strings.length; i++) { + var hs = header_strings[i].split(/:(.+)?/); + headers[hs[0]] = hs[1]; + } + return headers; + } + + APICalls.getCount = function(resp) { + var count = 0; + var headers = APICalls.parseHeader(resp.getAllResponseHeaders()); + if(headers["Count"]) count = parseInt(headers["Count"], 10); + return count; + } + + APICalls.parseHeaderForLink = function(header_string, match) { + var headers = header_string.split(/\n/); + var links = []; + for (var i = 0; i < headers.length; i++) { + var header = headers[i]; + if (header.match(/^Link:(.*)/i)) { + links.push(header.replace(/\r/, "").substr(5).trim()); + } + } + + var items = []; + for (var i = 0; i < links.length; i++) { + items = items.concat(links[i].split(",")); + } + var things = []; + for (var i = 0; i < items.length; i++) { + var item = items[i]; + if (item.match(match)) { + var n = item.match(/<([^>]*)>/); + if (n) { + things.push(n[1]); + } + } + } + + return things; + } + + return APICalls; +}); \ No newline at end of file diff --git a/WebKit/scripts/helper/Cache.js b/WebKit/scripts/helper/Cache.js index eb79fe7..2b35364 100644 --- a/WebKit/scripts/helper/Cache.js +++ b/WebKit/scripts/helper/Cache.js @@ -40,12 +40,12 @@ function(URI, CacheStorage, require) { } } - var url = URI(require("helper/Paths").mkApiRootPath("/followings")); + var url = URI(require("helper/APICalls").mkApiRootPath("/followings")); if (this.followings_before_id) { url.addSearch("before_id", this.followings_before_id); } - require("helper/Paths").getURL(url, "GET", callback); + require("helper/APICalls").getURL(url, "GET", callback); } Cache.prototype.periodicallyGetFollowings = function() { diff --git a/WebKit/scripts/helper/ConversationNode.js b/WebKit/scripts/helper/ConversationNode.js new file mode 100644 index 0000000..64c882c --- /dev/null +++ b/WebKit/scripts/helper/ConversationNode.js @@ -0,0 +1,25 @@ +define([ + +], + +function() { + + + function ConversationNode(dom_node) { + this.dom_node = dom_node; + this.parent = null; + this.children = []; + } + + ConversationNode.prototype.addChild = function(node) { + this.children.push(node); + node.parent = this; + }; + + ConversationNode.prototype.toString = function() { + return "{ \"" + this.dom_node.status.entity + "\": [" + this.children.toString() + "]}"; + }; + + + return ConversationNode; +}); \ No newline at end of file diff --git a/WebKit/scripts/helper/Core.js b/WebKit/scripts/helper/Core.js index 27a3f54..1a4f25b 100644 --- a/WebKit/scripts/helper/Core.js +++ b/WebKit/scripts/helper/Core.js @@ -1,16 +1,16 @@ define([ "jquery", - "helper/Paths", + "helper/APICalls", "lib/URI", "helper/HostApp", - "helper/Cache", - "lib/Timeago" + "lib/Markdown", + "lib/Timeago", + "lib/SingleDoubleClick" ], -function(jQuery, Paths, URI, HostApp, Cache) { +function(jQuery, APICalls, URI, HostApp, Markdown) { function Core() { - this.cache = new Cache(); this.saveScrollTop = 0; } @@ -37,7 +37,11 @@ function(jQuery, Paths, URI, HostApp, Cache) { var a = document.createElement("a"); - var item = document.createElement("li"); + var li = document.createElement("li"); + + var item = document.createElement("div"); + item.className = "post"; + li.appendChild(item); var aside = document.createElement("aside"); item.appendChild(aside); @@ -68,6 +72,7 @@ function(jQuery, Paths, URI, HostApp, Cache) { image.className = "image"; image.src = "img/default-avatar.png"; image.onmousedown = function(e) { e.preventDefault(); }; + image.onerror = function() { this.src = 'img/default-avatar.png' }; item.appendChild(image); var image_username = a.cloneNode(); @@ -122,8 +127,7 @@ function(jQuery, Paths, URI, HostApp, Cache) { head.appendChild(reposted_by) - - var message = document.createElement("p"); + var message = document.createElement("div"); message.className = "message"; data.appendChild(message); @@ -143,6 +147,7 @@ function(jQuery, Paths, URI, HostApp, Cache) { from.appendChild(source) this.template = { + li: li, item: item, reply_to: reply_to, is_private: is_private, @@ -161,14 +166,14 @@ function(jQuery, Paths, URI, HostApp, Cache) { return jQuery.extend(true, {}, this.template);; } - Core.prototype.getStatusDOMElement = function(status) { + Core.prototype.getStatusDOMElement = function(status, refs) { var _this = this; var template = this.getTemplate(); - template.item.id = "post-" + status.id; - template.item.status = status; + template.li.id = "post-" + status.id + "-" + this.action; + template.li.status = status; if (HostApp.stringForKey("entity") == status.entity && typeof status.__repost == "undefined") { template.remove.onclick = function() { @@ -184,10 +189,15 @@ function(jQuery, Paths, URI, HostApp, Cache) { template.remove.style.display = "none"; } + if (HostApp.stringForKey("entity") == status.entity) { + template.li.className += " own"; + } + template.reply_to.onclick = function() { var mentions = []; - var status_mentions = status.mentions.slice(0); + var status_mentions = []; + if(status.mentions) status_mentions = status.mentions.slice(0); if (typeof status.__repost != "undefined") { status_mentions.push({entity:status.__repost.entity}); @@ -198,17 +208,18 @@ function(jQuery, Paths, URI, HostApp, Cache) { mentions.push(mention); } - _this.replyTo(status.entity, status.id, mentions, (status && status.permissions && !status.permissions.public)); + _this.replyTo(status); return false; } template.repost.onclick = function() { $(template.repost).hide(); - _this.repost(status.id, status.entity); + _this.repost(status); return false; } - template.username.innerText = status.entity; + if(bungloo.cache.profiles[status.entity] && bungloo.cache.profiles[status.entity].name) template.username.innerText = bungloo.cache.profiles[status.entity].name; + else template.username.innerText = status.entity; template.username.href = status.entity; template.username.title = status.entity; template.username.onclick = function() { @@ -216,47 +227,12 @@ function(jQuery, Paths, URI, HostApp, Cache) { return false; } + if(bungloo.cache.profiles[status.entity] && bungloo.cache.profiles[status.entity].avatar_digest) { + template.image.src = HostApp.serverUrl("attachment").replace(/\{entity\}/, encodeURIComponent(status.entity)).replace(/\{digest\}/, bungloo.cache.profiles[status.entity].avatar_digest); + } + template.image.onclick = template.username.onclick; - var profile_callback = function(p) { - - var basic = p["https://tent.io/types/info/basic/v0.1.0"]; - - if (p && basic) { - if(basic.name) { - template.username.title = template.username.innerText; - template.username.innerText = basic.name; - } - if(basic.avatar_url) { - template.image.onerror = function() { template.image.src = 'img/default-avatar.png' }; - template.image.src = basic.avatar_url; - } - } - - } - - var p = this.cache.profiles.getItem(status.entity); - - if (p && p != "null") { - - profile_callback(p); - - } else { - - Paths.findProfileURL(status.entity, function(profile_url) { - - if (profile_url) { - Paths.getURL(profile_url, "GET", function(resp) { - var p = JSON.parse(resp.responseText); - if (p && p != "null") { - _this.cache.profiles.setItem(status.entity, p); - profile_callback(p); - } - - }, null, false); // do not send auth-headers - } - }); - } if (status && status.permissions && !status.permissions.public) { template.is_private.style.display = ''; @@ -264,7 +240,7 @@ function(jQuery, Paths, URI, HostApp, Cache) { var text = ""; - if (status.type == "https://tent.io/types/post/photo/v0.1.0") { + if (status.type == "https://tent.io/types/post/photo/v0.1.0") { // FIXME text = status.content.caption; } else { if (status.content && status.content.text) { @@ -274,8 +250,6 @@ function(jQuery, Paths, URI, HostApp, Cache) { this.parseForMedia(text, template.images); - text = text.escapeHTML().replace(/\n/g, "
    "); - var entities = [status.entity]; if (status.mentions) { status.mentions.map(function (mention) { @@ -284,43 +258,37 @@ function(jQuery, Paths, URI, HostApp, Cache) { } template.message.innerHTML = this.replaceURLWithHTMLLinks(text, entities, template.message); - - // adding show search on click hash - $(template.message).find("a.hash").click(function(e) { - bungloo.search.searchFor("#" + e.target.innerHTML); - return false; - }); + this.afterChangingTextinMessageHTML(template.message) - if (status.type == "https://tent.io/types/post/photo/v0.1.0") { - - for (var i = 0; i < status.attachments.length; i++) { - // closure needed for the callback - (function() { - - var attachment = status.attachments[i]; - - var img = new Image(); - - img.className = "photo"; - template.images.appendChild(img); - - var callback = function(resp) { - img.src = "data:" + attachment.type + ";base64," + resp.responseText; + if(status.refs) { + for (var i = 0; i < status.refs.length; i++) { + var ref = status.refs[i]; + if(ref.type == "https://tent.io/types/photo/v0#") { + if(refs) { + for (var j = 0; j < refs.length; j++) { + var r = refs[j]; + if(ref.post == r.id) { + for (var k = 0; k < r.attachments.length; k++) { + var attachment = r.attachments[k]; + var a = document.createElement("a"); + var img = document.createElement("img"); + img.src = HostApp.serverUrl("attachment") + .replace(/\{entity\}/, encodeURIComponent(r.entity)) + .replace(/\{digest\}/, attachment.digest); + a.appendChild(img); + a.href = img.src; + template.images.appendChild(a); + } + } + } } - - if (status.entity == HostApp.stringForKey("entity")) { - var url = Paths.mkApiRootPath("/posts/" + status.id + "/attachments/" + attachment.name); - Paths.getURL(url, "GET", callback, null, null, attachment.type); - } else { - var url = Paths.mkApiRootPath("/posts/" + encodeURIComponent(status.entity) + "/" + status.id + "/attachments/" + attachment.name); - Paths.getURL(url, "GET", callback, null, null, attachment.type); - } - })(); - } + } + } } this.findMentions(template.message, status.mentions); +/* for (var i = 0; i < status.mentions.length; i++) { var mention = status.mentions[i]; if (mention.entity == HostApp.stringForKey("entity")) { @@ -328,27 +296,31 @@ function(jQuery, Paths, URI, HostApp, Cache) { break; } } - - var published_at = typeof status.__repost == "undefined" ? status.published_at : status.__repost.published_at; +*/ + var published_at = typeof status.__repost == "undefined" ? status.version.published_at : status.__repost.published_at; var time = document.createElement("abbr"); - time.innerText = this.ISODateString(new Date(published_at * 1000)); + time.innerText = this.ISODateString(new Date(published_at)); time.title = time.innerText; time.className = "timeago"; jQuery(time).timeago(); template.ago.appendChild(time); template.ago.href = "#" - template.ago.onclick = function() { + + $(template.ago).single_double_click(function () { HostApp.showConversation(status.id, status.entity); return false; - } + }, function () { + HostApp.showConversationViewForPostIdandEntity(status.id, status.entity); + return false; + }); - // {"type":"Point","coordinates":[57.10803113,12.25854746]} - if (status.content && status.content.location && (typeof status.content.location.type == "undefined" || status.content.location.type == "Point")) { - var lat = status.content.location.coordinates[0]; - var lng = status.content.location.coordinates[1]; + if (status.content && status.content.location) { + var lat = status.content.location.latitude; + var lng = status.content.location.longitude; + + if (typeof lat != "undefined" && typeof lng != "undefined") { - if (typeof lat != "undefined" && typeof lng != "undefined" && lat > 0 && lng > 0) { var href = this.mapHref(lat, lng); template.geo.href = href; template.geo.style.display = ""; @@ -363,18 +335,20 @@ function(jQuery, Paths, URI, HostApp, Cache) { template.source.innerHTML = status.__repost.app.name; template.source.title = status.__repost.app.url; } else { - template.source.href = status.app.url; - template.source.innerHTML = status.app.name; - template.source.title = status.app.url; + if(status.app) { + template.source.href = status.app.url; + template.source.innerHTML = status.app.name; + template.source.title = status.app.url; + } } - return template.item; + return template.li; } - Core.prototype.getRepost = function(repost, before_node) { + Core.prototype.getRepost = function(repost, before_node, append) { - var post = document.getElementById("post-" + repost.content.id); + var post = document.getElementById("post-" + repost.refs[0].post + "-" + this.action); if (post) { @@ -412,7 +386,7 @@ function(jQuery, Paths, URI, HostApp, Cache) { $(post).find(".reposted_by").show(); var li = $("
  • "); - li.attr("id", "post-" + repost.id) + li.attr("id", "post-" + repost.id + "-" + this.action) var a = $(""); a.attr("href", repost.entity); @@ -427,100 +401,112 @@ function(jQuery, Paths, URI, HostApp, Cache) { return false; }); - var _this = this; - Paths.findProfileURL(repost.entity, function(profile_url) { - if (profile_url) { - Paths.getURL(profile_url, "GET", function(resp) { - if (resp.status >= 200 && resp.status < 400) { - var _p = JSON.parse(resp.responseText); - _this.cache.profiles.setItem(repost.entity, _p); - - var basic = _p["https://tent.io/types/info/basic/v0.1.0"]; - if (basic && basic.name) { - a.html(basic.name); - } - - } - }, null, false); // do not send auth-headers - } - }); + var name = bungloo.cache.profiles[repost.entity] ? bungloo.cache.profiles[repost.entity].name : repost.entity; + a.html(name); } else { + + var entity = repost.refs[0].entity ? repost.refs[0].entity : HostApp.stringForKey("entity"); + var id = repost.refs[0].post; + + var url = HostApp.serverUrl("post") + .replace(/\{entity\}/, encodeURIComponent(entity)) + .replace(/\{post\}/, id) + + "?profiles=entity"; + + var _this = this; + + APICalls.get(url, { callback: function(resp) { + + if (resp.status >= 200 && resp.status < 300 && before_node) { + var _statuses = JSON.parse(resp.responseText); + + for (var entity in _statuses.profiles) { + if (_statuses.profiles[entity] != null) { + bungloo.cache.profiles[entity] = _statuses.profiles[entity]; + } else { + bungloo.cache.profiles[entity] = {}; + } + } + + var status = _statuses.post; + + status.__repost = repost; + var li = _this.getStatusDOMElement(status); + if(!document.getElementById(li.id)) before_node.parentNode.insertBefore(li, before_node); + _this.getRepost(repost, before_node); // call this recursive because we now have the repost + } + + + }}); + + /* + var _this = this; var callback = function(resp) { if (resp.status >= 200 && resp.status < 300 && before_node) { var status = JSON.parse(resp.responseText); status.__repost = repost; var li = _this.getStatusDOMElement(status); - before_node.parentNode.insertBefore(li, before_node); + if(!document.getElementById(li.id)) before_node.parentNode.insertBefore(li, before_node); _this.getRepost(repost, before_node); // call this recursive because we now have the repost } } - Paths.findProfileURL(repost.content.entity, function(profile_url) { + APICalls.findProfileURL(repost.content.entity, function(profile_url) { if (profile_url) { - Paths.getURL(profile_url, "GET", function(resp) { + APICalls.http_call(profile_url, "GET", function(resp) { var profile = JSON.parse(resp.responseText); var server = profile["https://tent.io/types/info/core/v0.1.0"].servers[0]; - Paths.getURL(URI(server + "/posts/" + repost.content.id).toString(), "GET", callback, null, false); + APICalls.http_call(URI(server + "/posts/" + repost.content.id).toString(), "GET", callback, null, false); }, null, false); // do not send auth-headers } - }); + });*/ } } - Core.prototype.sendNewMessage = function(content, in_reply_to_status_id, in_reply_to_entity, location, image_data_uri, is_private, callback) { + Core.prototype.repost = function(status, callback) { + var type = status.type; + var id = status.id; + var entity = status.entity; + var url = HostApp.serverUrl("new_post"); + var data = { + type: "https://tent.io/types/repost/v0#" + type.split("#")[0], + refs: [ + { + post: id, + entity: entity + } + ], + mentions: [ + { + post: id, + type: type, + entity: entity + } - if (image_data_uri) { + ] + } - this.sendNewMessageWithImage(content, in_reply_to_status_id, in_reply_to_entity, location, image_data_uri, is_private, callback); - - } else { - - var url = URI(Paths.mkApiRootPath("/posts")); - - var http_method = "POST"; - - var data = { - "type": "https://tent.io/types/post/status/v0.1.0", - "published_at": parseInt(new Date().getTime() / 1000, 10), - "permissions": { - "public": !is_private - }, - "content": { - "text": content, - }, - }; - - if (location) { - data["content"]["location"] = { "type": "Point", "coordinates": location } - } - - var mentions = this.parseMentions(content, in_reply_to_status_id, in_reply_to_entity); - - if (mentions.length > 0) { - data["mentions"] = mentions; - if (is_private) { - var entities = {}; - for (var i = 0; i < mentions.length; i++) { - var entity = mentions[i]["entity"] - entities[entity] = true; - }; - - data["permissions"]["entities"] = entities; + APICalls.post(url, JSON.stringify(data), { + content_type: data.type, + accept: 'application/vnd.tent.post.v0+json; type="https://tent.io/types/repost/v0#"', + callback: function(resp) { + if (resp.status >= 200 < 300) { + controller.getNewData(); + if(callback) callback(resp); + } else { + debug(resp) } } - Paths.getURL(url.toString(), http_method, callback, JSON.stringify(data)); - } - } + }) - - Core.prototype.repost = function(id, entity, callback) { - var url = URI(Paths.mkApiRootPath("/posts")); + /* + var url = URI(APICalls.mkApiRootPath("/posts")); var data = { "type": "https://tent.io/types/post/repost/v0.1.0", @@ -546,88 +532,19 @@ function(jQuery, Paths, URI, HostApp, Cache) { _this.highlight(id); } - Paths.getURL(url.toString(), "POST", new_callback, JSON.stringify(data)); - } - - Core.prototype.sendNewMessageWithImage = function(content, in_reply_to_status_id, in_reply_to_entity, location, image_data_uri, is_private, callback) { - - var url = URI(Paths.mkApiRootPath("/posts")); - - var data = { - "type": "https://tent.io/types/post/photo/v0.1.0", - "published_at": parseInt(new Date().getTime() / 1000, 10), - "permissions": { - "public": !is_private - }, - "content": { - "caption": content, - }, - }; - - if (location) { - data["content"]["location"] = { "type": "Point", "coordinates": location } - } - - var mentions = this.parseMentions(content, in_reply_to_status_id, in_reply_to_entity); - if (mentions.length > 0) { - data["mentions"] = mentions; - if (is_private) { - var entities = {}; - for (var i = 0; i < mentions.length; i++) { - var entity = mentions[i]["entity"] - entities[entity] = true; - }; - - data["permissions"]["entities"] = entities; - } - } - - var data_string = JSON.stringify(data); - - var boundary = "TentAttachment----------TentAttachment"; - var post = "--" + boundary + "\r\n"; - - post += 'Content-Disposition: form-data; name="post"; filename="post.json"\r\n'; - post += 'Content-Length: ' + data_string.length + '\r\n'; - post += 'Content-Type: application/vnd.tent.v0+json\r\n'; - post += 'Content-Transfer-Encoding: binary\r\n\r\n'; - post += data_string; - - post += "\r\n--" + boundary + "\r\n"; - - var blob_string = image_data_uri.split(',')[1]; - var mime_type = image_data_uri.split(',')[0].split(':')[1].split(';')[0]; - var ext = "png"; - if (mime_type == "image/jpeg") { - ext = "jpeg"; - } else if (mime_type == "image/gif") { - ext = "gif"; - } - - - post += 'Content-Disposition: form-data; name="photos[0]"; filename="photo.' + ext + '"\r\n'; - post += 'Content-Length: ' + blob_string.length + "\r\n"; - post += 'Content-Type: ' + mime_type + "\r\n"; - post += 'Content-Transfer-Encoding: base64\r\n\r\n'; - post += blob_string; - post += "\r\n--" + boundary + "--\r\n"; - - var newCallback = function(resp) { - if (resp.status == 403) { - var err = JSON.parse(resp.responseText); - HostApp.alertTitleWithMessage(resp.statusText, err.error); - } - callback(resp); - } - - Paths.postMultipart(url.toString(), newCallback, post, boundary); + APICalls.http_call(url.toString(), "POST", new_callback, JSON.stringify(data));*/ } Core.prototype.remove = function(id, callback, type) { type = type || "post"; if (confirm("Really delete this " + type + "?")) { - var url = URI(Paths.mkApiRootPath("/posts/" + id)); - Paths.getURL(url.toString(), "DELETE", callback); + + var entity = HostApp.stringForKey("entity"); + var url = HostApp.serverUrl("post") + .replace(/\{entity\}/, encodeURIComponent(entity)) + .replace(/\{post\}/, id); + + APICalls.delete(url, { callback: callback }); } } @@ -679,13 +596,15 @@ function(jQuery, Paths, URI, HostApp, Cache) { if (e.substring(0,7) != "http://" && e.substring(0,8) != "https://") { e = "https://" + e; } - for (var j = 0; j < mentions.length; j++) { - var m = mentions[j]; - if(m.entity.startsWith(e)) { - mentions_in_text.push({ - entity: m.entity, - text: name - }); + if(mentions) { + for (var j = 0; j < mentions.length; j++) { + var m = mentions[j]; + if(m && m.entity && m.entity.startsWith(e)) { + mentions_in_text.push({ + entity: m.entity, + text: name + }); + } } } } @@ -714,12 +633,8 @@ function(jQuery, Paths, URI, HostApp, Cache) { + "" ); - // adding show profile on click node.innerHTML = new_text; - $(node).find("a.name").click(function(e) { - HostApp.showProfileForEntity(e.target.title); - return false; - }); + _this.afterChangingTextinMessageHTML(node); // adding comma between names when there is only // a space in between. @@ -732,25 +647,17 @@ function(jQuery, Paths, URI, HostApp, Cache) { } } - var p = _this.cache.profiles.getItem(mention.entity); - if (p) { - - profile(p); - - } else { - - Paths.findProfileURL(mention.entity, function(profile_url) { - if (profile_url) { - Paths.getURL(profile_url, "GET", function(resp) { - if (resp.status >= 200 && resp.status < 400) { - var p = JSON.parse(resp.responseText); - _this.cache.profiles.setItem(mention.entity, p); - profile(p) - } - }, null, false); // do not send auth-headers - } - }); - } + APICalls.findProfileURL(mention.entity, function(profile_url) { + if (profile_url) { + APICalls.http_call(profile_url, "GET", function(resp) { + if (resp.status >= 200 && resp.status < 400) { + var p = JSON.parse(resp.responseText); + _this.cache.profiles.setItem(mention.entity, p); + profile(p) + } + }, null, false); // do not send auth-headers + } + }); })(mention); } @@ -797,27 +704,8 @@ function(jQuery, Paths, URI, HostApp, Cache) { } Core.prototype.replaceURLWithHTMLLinks = function(text, entities, message_node) { - - var callback = function(url) { - - var result; - - if (entities && entities.some(function(x) { return x == url })) { - result = url; - } else { - - result = url; - if (url.startsWith("http://") || url.startsWith("https://")) { - result = '' + url + ''; - } - } - - return result; - } - - var hash = /(^|\s)(#)(\w+)/ig; - - return URI.withinString(text, callback).replace(hash, "$1$2$3"); + return Markdown.toHTML( text, 'Tent', { footnotes: entities } ) + .replace(/\^ 0) string += "\n\n/cc" + ms; - - HostApp.openNewMessageWidow(entity, status_id, string, is_private); + Core.prototype.replyTo = function(status) { + HostApp.openNewMessageWidow(status); } Core.prototype.postDeleted = function(post_id, entity) { - var li = document.getElementById("post-" + post_id); + var li = document.getElementById("post-" + post_id + "-" + this.action); if (li) { if (li.parentNode == this.body) { this.body.removeChild(li); @@ -942,22 +819,25 @@ function(jQuery, Paths, URI, HostApp, Cache) { } Core.prototype.mapHref = function(lat, lng) { - return "http://www.openstreetmap.org/?mlat=" + lat + "&mlon=" + lng + "&zoom=12"; + return "http://www.openstreetmap.org/?mlat=" + lat.toString() + "&mlon=" + lng.toString() + "&zoom=12"; } Core.prototype.mapSrc = function(lat, lng) { - var width = $("p.message").width(); - return "http://staticmap.openstreetmap.de/staticmap.php?center=" + lat + "," + lng + "&zoom=3&size=" + width + "x75&markers=" + lat + "," + lng + ",red-pushpin"; + var width = $("div:visible div.message").width(); + return "http://staticmap.openstreetmap.de/staticmap.php?center=" + lat.toString() + "," + lng.toString() + "&zoom=3&size=" + width + "x75&markers=" + lat + "," + lng + ",red-pushpin"; } Core.prototype.addMap = function(lat, lng, images) { - var a = document.createElement("a"); - a.className = "map"; - a.href = this.mapHref(lat, lng); - var img = document.createElement("img"); - img.src = this.mapSrc(lat, lng); - a.appendChild(img); - images.appendChild(a); + var self = this; + setTimeout(function(){ + var a = document.createElement("a"); + a.className = "map"; + a.href = self.mapHref(lat, lng); + var img = document.createElement("img"); + img.src = self.mapSrc(lat, lng); + a.appendChild(img); + images.appendChild(a); + }, 200); } Core.prototype.addYouTube = function(id, images) { @@ -997,6 +877,22 @@ function(jQuery, Paths, URI, HostApp, Cache) { $(images).append(''); } + Core.prototype.afterChangingTextinMessageHTML = function(message_node) { + // adding show search on click hash + /* + $(message_node).find("a.hash").click(function(e) { + + if(bungloo.search) bungloo.search.searchFor(e.target.innerHTML); + return false; + }); + */ + // adding show profile on click + /* + $(message_node).find("a.name").click(function(e) { + HostApp.showProfileForEntity(e.target.title); + return false; + });*/ + } return Core; diff --git a/WebKit/scripts/helper/Hmac.js b/WebKit/scripts/helper/Hmac.js index b22a2f3..be4db38 100644 --- a/WebKit/scripts/helper/Hmac.js +++ b/WebKit/scripts/helper/Hmac.js @@ -7,7 +7,7 @@ function(URI, CryptoJS) { var Hmac = {}; - Hmac.makeAuthHeader = function(url, http_method, mac_key, mac_key_id) { + Hmac.makeHawkAuthHeader = function(url, http_method, hawk_id, key, app_id) { url = URI(url); var nonce = Hmac.makeid(8); @@ -18,26 +18,47 @@ function(URI, CryptoJS) { port = url.protocol() == "https" ? "443" : "80"; } - var normalizedRequestString = "" - + time_stamp + '\n' - + nonce + '\n' - + http_method + '\n' - + url.path() + url.search() + url.hash() + '\n' - + url.hostname() + '\n' - + port + '\n' - + '\n' ; + var normalizedRequestString = "hawk.1.header\n" // header + + time_stamp + '\n' // ts + + nonce + '\n' // nonce + + http_method.toUpperCase() + '\n' // method + + url.path() + url.search() + url.hash() + '\n' // request uri + + url.hostname().toLowerCase() + '\n' // host + + port + '\n' // port + + '\n' // Hmac.calculatePayloadHash(payload) + '\n' // hash // FIXME implement payload validation + + '\n' // ext (we don't use it) - var hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, mac_key); + var app = ""; + + if(app_id) { + app = ', app="' + app_id + "'"; + normalizedRequestString += app_id + "\n" + // app + '\n'; // dlg should be empty + } + + var hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, key); hmac.update(normalizedRequestString); var hash = hmac.finalize(); var mac = hash.toString(CryptoJS.enc.Base64); - return 'MAC id="' + mac_key_id + + return 'Hawk id="' + hawk_id + + '", mac="' + mac + '", ts="' + time_stamp + - '", nonce="' + nonce + - '", mac="' + mac + '"'; + '", nonce="' + nonce + '"' + + app } + Hmac.calculatePayloadHash = function (payload) { + if (!payload) return ""; + + var hash = CryptoJS.algo.SHA256.create(); + hash.update('hawk.1.payload\n'); + hash.update('application/vnd.tent.post.v0+json\n'); + hash.update(payload || ''); + hash.update('\n'); + return hash.finalize().toString(CryptoJS.enc.Base64); + }, + Hmac.makeid = function(len) { var text = ""; var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; diff --git a/WebKit/scripts/helper/HostApp.js b/WebKit/scripts/helper/HostApp.js index 50bcbe8..9811fda 100644 --- a/WebKit/scripts/helper/HostApp.js +++ b/WebKit/scripts/helper/HostApp.js @@ -37,6 +37,14 @@ define(function() { } } + HostApp.setServerUrls = function(server_urls) { + HostApp.setStringForKey(JSON.stringify(server_urls), "server_urls"); + } + + HostApp.serverUrl = function(key) { + return JSON.parse(HostApp.stringForKey("server_urls"))[key]; + } + HostApp.openURL = function(url) { if (OS_TYPE == "mac") { @@ -77,12 +85,12 @@ define(function() { } } - HostApp.openNewMessageWidow = function(entity, status_id, string, is_private) { + HostApp.openNewMessageWidow = function(status) { if (OS_TYPE == "mac") { - controller.openNewMessageWindowInReplyTo_statusId_withString_isPrivate_(entity, status_id, string, is_private); + controller.openNewMessageWindowInReplyToStatus_(JSON.stringify(status)); } else { - controller.openNewMessageWindowInReplyTostatusIdwithStringIsPrivate(entity, status_id, string, is_private); + controller.openNewMessageWindowInReplyToStatus(JSON.stringify(status).escapeSpecialChars()); } } @@ -95,6 +103,14 @@ define(function() { } } + HostApp.showConversationViewForPostIdandEntity = function(id, entity) { + if (OS_TYPE == "mac") { + controller.showConversationViewForPostId_andEntity_(id, entity); + } else { + controller.showConversationViewForPostIdandEntity(id, entity); + } + } + HostApp.showProfileForEntity = function(entity) { if (OS_TYPE == "mac") { @@ -129,7 +145,10 @@ define(function() { } HostApp.osType = function() { - return OS_TYPE == "mac" ? "OS X" : "Linux"; + var os_name = "OS X"; + if (OS_TYPE == "windows") os_name = "Windows"; + if (OS_TYPE == "linux") os_name = "Linux" + return os_name; } HostApp.notificateViewsAboutDeletedPost = function(postId, entity) { diff --git a/WebKit/scripts/helper/Paths.js b/WebKit/scripts/helper/Paths.js index 5f477a7..af1fb75 100644 --- a/WebKit/scripts/helper/Paths.js +++ b/WebKit/scripts/helper/Paths.js @@ -25,7 +25,7 @@ function(jQuery, HostApp, Hmac, Cache) { Paths.getURL = function(url, http_method, callback, data, auth_header, accepts) { - if(accepts !== false) accepts = accepts || "application/vnd.tent.v0+json; charset=utf-8"; + if(accepts !== false) accepts = accepts || "application/vnd.tent.post.v0+json"; var options = { @@ -56,7 +56,7 @@ function(jQuery, HostApp, Hmac, Cache) { } }, url: url, - contentType: "application/vnd.tent.v0+json", + contentType: 'application/vnd.tent.post.v0+json; type="https://tent.io/types/app/v0#"', type: http_method, complete: callback, data: data, @@ -65,7 +65,7 @@ function(jQuery, HostApp, Hmac, Cache) { console.error("getURL (" + xhr.status + ")" + xhr.statusText + " " + http_method + " (" + url + "): '" + xhr.responseText + "'"); } } - + jQuery.ajax(options); } @@ -127,7 +127,7 @@ function(jQuery, HostApp, Hmac, Cache) { if(profile_urls.length > 0) { var profile_url = profile_urls[0]; if (!profile_url.startsWith("http")) { - profile_url = entity + "/profile"; + profile_url = entity + profile_url; } } @@ -140,13 +140,13 @@ function(jQuery, HostApp, Hmac, Cache) { if (resp.status >= 200 && resp.status < 300) { var doc = document.implementation.createHTMLDocument(""); doc.documentElement.innerHTML = resp.responseText; - var links = $(doc).find("link[rel='https://tent.io/rels/profile']"); + var links = $(doc).find("link[rel='https://tent.io/rels/meta-post']"); if (links.length > 0) { var href = links.get(0).href; Paths.cache.profile_urls.setItem(entity, href); if (!href.startsWith("http")) { - href = entity + "/profile"; + href = entity + href; } callback(href); @@ -184,6 +184,11 @@ function(jQuery, HostApp, Hmac, Cache) { } Paths.parseHeaderForProfiles = function(header_string) { + var regexp = /https:\/\/tent.io\/rels\/meta-post/i; + return Paths.parseHeaderForLink(header_string, regexp); + } + + Paths.parseHeaderForLink = function(header_string, match) { var headers = header_string.split(/\n/); var links = []; for (var i = 0; i < headers.length; i++) { @@ -197,18 +202,18 @@ function(jQuery, HostApp, Hmac, Cache) { for (var i = 0; i < links.length; i++) { items = items.concat(links[i].split(",")); } - var profiles = []; + var things = []; for (var i = 0; i < items.length; i++) { var item = items[i]; - if (item.match(/https:\/\/tent.io\/rels\/profile/i)) { + if (item.match(match)) { var n = item.match(/<([^>]*)>/); if (n) { - profiles.push(n[1]); + things.push(n[1]); } } } - return profiles; + return things; } return Paths; diff --git a/WebKit/scripts/lib/Markdown.js b/WebKit/scripts/lib/Markdown.js new file mode 100644 index 0000000..bbe9077 --- /dev/null +++ b/WebKit/scripts/lib/Markdown.js @@ -0,0 +1,7 @@ +define([ + "lib/vendor/tent-markdown" +], + +function() { + return window.markdown; +}); \ No newline at end of file diff --git a/WebKit/scripts/lib/SingleDoubleClick.js b/WebKit/scripts/lib/SingleDoubleClick.js new file mode 100644 index 0000000..70c248f --- /dev/null +++ b/WebKit/scripts/lib/SingleDoubleClick.js @@ -0,0 +1,31 @@ +define([ + "jquery" +], + +function(jQuery) { + +// Author: Jacek Becela +// Source: http://gist.github.com/399624 +// License: MIT + +jQuery.fn.single_double_click = function(single_click_callback, double_click_callback, timeout) { + return this.each(function(){ + var clicks = 0, self = this; + jQuery(this).click(function(event){ + clicks++; + if (clicks == 1) { + setTimeout(function(){ + if(clicks == 1) { + single_click_callback.call(self, event); + } else { + double_click_callback.call(self, event); + } + clicks = 0; + }, timeout || 300); + } + return false; // added by jeena so it doesn't follow links + }); + }); +} + +}) \ No newline at end of file diff --git a/WebKit/scripts/lib/vendor/tent-markdown.js b/WebKit/scripts/lib/vendor/tent-markdown.js new file mode 100644 index 0000000..34013e2 --- /dev/null +++ b/WebKit/scripts/lib/vendor/tent-markdown.js @@ -0,0 +1,1219 @@ +/* + Adapted from https://github.com/twitter/twitter-text-js + + Copyright 2011 Twitter, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this work except in compliance with the License. + You may obtain a copy of the License below, or at: + + http://www.apache.org/licenses/LICENSE-2.0 +*/ + +(function(expose) { + + twttr = { txt: { regexen: {} } } + + // Builds a RegExp + function regexSupplant(regex, flags) { + flags = flags || ""; + if (typeof regex !== "string") { + if (regex.global && flags.indexOf("g") < 0) { + flags += "g"; + } + if (regex.ignoreCase && flags.indexOf("i") < 0) { + flags += "i"; + } + if (regex.multiline && flags.indexOf("m") < 0) { + flags += "m"; + } + + regex = regex.source; + } + + return new RegExp(regex.replace(/#\{(\w+)\}/g, function(match, name) { + var newRegex = twttr.txt.regexen[name] || ""; + if (typeof newRegex !== "string") { + newRegex = newRegex.source; + } + return newRegex; + }), flags); + } + + twttr.txt.regexSupplant = regexSupplant; + + // simple string interpolation + function stringSupplant(str, values) { + return str.replace(/#\{(\w+)\}/g, function(match, name) { + return values[name] || ""; + }); + } + + var fromCode = String.fromCharCode; + var INVALID_CHARS = [ + fromCode(0xFFFE), + fromCode(0xFEFF), // BOM + fromCode(0xFFFF) // Special + ]; + + twttr.txt.regexen.invalid_chars_group = regexSupplant(INVALID_CHARS.join("")); + + twttr.txt.stringSupplant = stringSupplant; + + twttr.txt.stringSupplant = stringSupplant + + var UNICODE_SPACES = [ + fromCode(0x0020), // White_Space # Zs SPACE + fromCode(0x0085), // White_Space # Cc + fromCode(0x00A0), // White_Space # Zs NO-BREAK SPACE + fromCode(0x1680), // White_Space # Zs OGHAM SPACE MARK + fromCode(0x180E), // White_Space # Zs MONGOLIAN VOWEL SEPARATOR + fromCode(0x2028), // White_Space # Zl LINE SEPARATOR + fromCode(0x2029), // White_Space # Zp PARAGRAPH SEPARATOR + fromCode(0x202F), // White_Space # Zs NARROW NO-BREAK SPACE + fromCode(0x205F), // White_Space # Zs MEDIUM MATHEMATICAL SPACE + fromCode(0x3000) // White_Space # Zs IDEOGRAPHIC SPACE + ]; + + twttr.txt.regexen.spaces_group = regexSupplant(UNICODE_SPACES.join("")); + twttr.txt.regexen.spaces = regexSupplant("[" + UNICODE_SPACES.join("") + "]"); + twttr.txt.regexen.invalid_chars_group = regexSupplant(INVALID_CHARS.join("")); + twttr.txt.regexen.punct = /\!'#%&'\(\)*\+,\\\-\.\/:;<=>\?@\[\]\^_{|}~\$/; + + // URL related regex collection + twttr.txt.regexen.validUrlPrecedingChars = regexSupplant(/(?:[^A-Za-z0-9@@$###{invalid_chars_group}]|^)/); + twttr.txt.regexen.invalidUrlWithoutProtocolPrecedingChars = /[-_.\/]$/; + twttr.txt.regexen.invalidDomainChars = stringSupplant("#{punct}#{spaces_group}#{invalid_chars_group}", twttr.txt.regexen); + twttr.txt.regexen.validDomainChars = regexSupplant(/[^#{invalidDomainChars}]/); + twttr.txt.regexen.validSubdomain = regexSupplant(/(?:(?:#{validDomainChars}(?:[_-]|#{validDomainChars})*)?#{validDomainChars}\.)/); + twttr.txt.regexen.validDomainName = regexSupplant(/(?:(?:#{validDomainChars}(?:-|#{validDomainChars})*)?#{validDomainChars}\.)/); + twttr.txt.regexen.validGTLD = regexSupplant(/(?:(?:aero|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|xxx|local)(?=[^0-9a-zA-Z]|$))/); + twttr.txt.regexen.validCCTLD = regexSupplant(/(?:(?:ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw)(?=[^0-9a-zA-Z]|$))/); + twttr.txt.regexen.validPunycode = regexSupplant(/(?:xn--[0-9a-z]+)/); + twttr.txt.regexen.validDomain = regexSupplant(/(?:#{validSubdomain}*#{validDomainName}(?:#{validGTLD}|#{validCCTLD}|#{validPunycode}))/); + twttr.txt.regexen.validAsciiDomain = regexSupplant(/(?:(?:[-a-z0-9#{latinAccentChars}]+)\.)+(?:#{validGTLD}|#{validCCTLD}|#{validPunycode})/gi); + twttr.txt.regexen.invalidShortDomain = regexSupplant(/^#{validDomainName}#{validCCTLD}$/); + + twttr.txt.regexen.validPortNumber = regexSupplant(/[0-9]+/); + + twttr.txt.regexen.validGeneralUrlPathChars = regexSupplant(/[a-z0-9!\*';:=\+,\.\$\/%#\[\]\-_~|&#{latinAccentChars}]/i); + // Allow URL paths to contain balanced parens + // 1. Used in Wikipedia URLs like /Primer_(film) + // 2. Used in IIS sessions like /S(dfd346)/ + twttr.txt.regexen.validUrlBalancedParens = regexSupplant(/\(#{validGeneralUrlPathChars}+\)/i); + // Valid end-of-path chracters (so /foo. does not gobble the period). + // 1. Allow =&# for empty URL parameters and other URL-join artifacts + twttr.txt.regexen.validUrlPathEndingChars = regexSupplant(/[\+\-a-z0-9=_#\/#{latinAccentChars}]|(?:#{validUrlBalancedParens})/i); + // Allow @ in a url, but only in the middle. Catch things like http://example.com/@user/ + twttr.txt.regexen.validUrlPath = regexSupplant('(?:' + + '(?:' + + '#{validGeneralUrlPathChars}*' + + '(?:#{validUrlBalancedParens}#{validGeneralUrlPathChars}*)*' + + '#{validUrlPathEndingChars}'+ + ')|(?:@#{validGeneralUrlPathChars}+\/)'+ + ')', 'i'); + + twttr.txt.regexen.validUrlQueryChars = /[a-z0-9!?\*'\(\);:&=\+\$\/%#\[\]\-_\.,~|]/i; + twttr.txt.regexen.validUrlQueryEndingChars = /[a-z0-9_&=#\/]/i; + twttr.txt.regexen.extractUrl = regexSupplant( + '(' + // $1 total match + '(#{validUrlPrecedingChars})' + // $2 Preceeding chracter + '(' + // $3 URL + '(https?:\\/\\/)?' + // $4 Protocol (optional) + '(#{validDomain})' + // $5 Domain(s) + '(?::(#{validPortNumber}))?' + // $6 Port number (optional) + '(\\/#{validUrlPath}*)?' + // $7 URL Path + '(\\?#{validUrlQueryChars}*#{validUrlQueryEndingChars})?' + // $8 Query String + ')' + + ')' + , 'gi'); + + twttr.txt.regexen.validTcoUrl = /^https?:\/\/t\.co\/[a-z0-9]+/i; + + twttr.extractUrlsWithIndices = function(text, options) { + if (!options) { + options = {extractUrlsWithoutProtocol: true}; + } + + if (!text || (options.extractUrlsWithoutProtocol ? !text.match(/\./) : !text.match(/:/))) { + return []; + } + + var urls = []; + + while (twttr.txt.regexen.extractUrl.exec(text)) { + var before = RegExp.$2, url = RegExp.$3, protocol = RegExp.$4, domain = RegExp.$5, path = RegExp.$7; + var endPosition = twttr.txt.regexen.extractUrl.lastIndex, + startPosition = endPosition - url.length; + + // if protocol is missing and domain contains non-ASCII characters, + // extract ASCII-only domains. + if (!protocol) { + if (!options.extractUrlsWithoutProtocol + || before.match(twttr.txt.regexen.invalidUrlWithoutProtocolPrecedingChars)) { + continue; + } + var lastUrl = null, + lastUrlInvalidMatch = false, + asciiEndPosition = 0; + domain.replace(twttr.txt.regexen.validAsciiDomain, function(asciiDomain) { + var asciiStartPosition = domain.indexOf(asciiDomain, asciiEndPosition); + asciiEndPosition = asciiStartPosition + asciiDomain.length; + lastUrl = { + url: asciiDomain, + indices: [startPosition + asciiStartPosition, startPosition + asciiEndPosition] + }; + if (!before.match(/^[\^]$/)) { + lastUrlInvalidMatch = asciiDomain.match(twttr.txt.regexen.invalidShortDomain); + } + if (!lastUrlInvalidMatch) { + urls.push(lastUrl); + } + }); + + // no ASCII-only domain found. Skip the entire URL. + if (lastUrl == null) { + continue; + } + + // lastUrl only contains domain. Need to add path and query if they exist. + if (path) { + if (lastUrlInvalidMatch) { + urls.push(lastUrl); + } + lastUrl.url = url.replace(domain, lastUrl.url); + lastUrl.indices[1] = endPosition; + } + } else { + // In the case of t.co URLs, don't allow additional path characters. + if (url.match(twttr.txt.regexen.validTcoUrl)) { + url = RegExp.lastMatch; + endPosition = startPosition + url.length; + } + urls.push({ + url: url, + indices: [startPosition, endPosition] + }); + } + } + + return urls; + }; + + expose.extractUrlsWithIndices = twttr.extractUrlsWithIndices; + +})((function() { + if (typeof exports === "undefined") { + window.twttr = {}; + return window.twttr; + } else { + return exports; + } +})()); +// Released under MIT license +// Copyright (c) 2009-2010 Dominic Baggott +// Copyright (c) 2009-2010 Ash Berlin +// Copyright (c) 2011 Christoph Dorn (http://www.christophdorn.com) + +/*jshint browser:true, devel:true */ + +(function( expose ) { + +var Markdown = expose.Markdown = function(dialect) { + switch (typeof dialect) { + case "undefined": + this.dialect = Markdown.dialects.Gruber; + break; + case "object": + this.dialect = dialect; + break; + default: + if ( dialect in Markdown.dialects ) { + this.dialect = Markdown.dialects[dialect]; + } + else { + throw new Error("Unknown Markdown dialect '" + String(dialect) + "'"); + } + break; + } + this.em_state = []; + this.strong_state = []; + this.debug_indent = ""; +}; + +/** + * parse( markdown, [dialect] ) -> JsonML + * - markdown (String): markdown string to parse + * - dialect (String | Dialect): the dialect to use, defaults to gruber + * + * Parse `markdown` and return a markdown document as a Markdown.JsonML tree. + **/ +expose.parse = function( source, dialect ) { + // dialect will default if undefined + var md = new Markdown( dialect ); + return md.toTree( source ); +}; + +/** + * toHTML( markdown, [dialect] ) -> String + * toHTML( md_tree ) -> String + * - markdown (String): markdown string to parse + * - md_tree (Markdown.JsonML): parsed markdown tree + * + * Take markdown (either as a string or as a JsonML tree) and run it through + * [[toHTMLTree]] then turn it into a well-formated HTML fragment. + **/ +expose.toHTML = function toHTML( source , dialect , options ) { + var input = expose.toHTMLTree( source , dialect , options ); + + return expose.renderJsonML( input ); +}; + +/** + * toHTMLTree( markdown, [dialect] ) -> JsonML + * toHTMLTree( md_tree ) -> JsonML + * - markdown (String): markdown string to parse + * - dialect (String | Dialect): the dialect to use, defaults to gruber + * - md_tree (Markdown.JsonML): parsed markdown tree + * + * Turn markdown into HTML, represented as a JsonML tree. If a string is given + * to this function, it is first parsed into a markdown tree by calling + * [[parse]]. + **/ +expose.toHTMLTree = function toHTMLTree( input, dialect , options ) { + // convert string input to an MD tree + if ( typeof input ==="string" ) input = this.parse( input, dialect ); + + // Now convert the MD tree to an HTML tree + + // remove references from the tree + var attrs = extract_attr( input ), + refs = {}; + + if ( attrs && attrs.references ) { + refs = attrs.references; + } + + var html = convert_tree_to_html( input, refs , options ); + merge_text_nodes( html ); + return html; +}; + +// For Spidermonkey based engines +function mk_block_toSource() { + return "Markdown.mk_block( " + + uneval(this.toString()) + + ", " + + uneval(this.trailing) + + ", " + + uneval(this.lineNumber) + + " )"; +} + +// node +function mk_block_inspect() { + var util = require("util"); + return "Markdown.mk_block( " + + util.inspect(this.toString()) + + ", " + + util.inspect(this.trailing) + + ", " + + util.inspect(this.lineNumber) + + " )"; + +} + +var mk_block = Markdown.mk_block = function(block, trail, line) { + // Be helpful for default case in tests. + if ( arguments.length == 1 ) trail = "\n\n"; + + var s = new String(block); + s.trailing = trail; + // To make it clear its not just a string + s.inspect = mk_block_inspect; + s.toSource = mk_block_toSource; + + if ( line != undefined ) + s.lineNumber = line; + + return s; +}; + +function count_lines( str ) { + var n = 0, i = -1; + while ( ( i = str.indexOf("\n", i + 1) ) !== -1 ) n++; + return n; +} + +// Internal - split source into rough blocks +Markdown.prototype.split_blocks = function splitBlocks( input, startLine ) { + input = input.replace(/(\r\n|\n|\r)/g, "\n"); + // [\s\S] matches _anything_ (newline or space) + var re = /([\s\S]+?)($|\n(?:\s*\n|$)+)/g, + blocks = [], + m; + + var line_no = 1; + + if ( ( m = /^(\s*\n)/.exec(input) ) != null ) { + // skip (but count) leading blank lines + line_no += count_lines( m[0] ); + re.lastIndex = m[0].length; + } + + while ( ( m = re.exec(input) ) !== null ) { + blocks.push( mk_block( m[1], m[2], line_no ) ); + line_no += count_lines( m[0] ); + } + + return blocks; +}; + +/** + * Markdown#processBlock( block, next ) -> undefined | [ JsonML, ... ] + * - block (String): the block to process + * - next (Array): the following blocks + * + * Process `block` and return an array of JsonML nodes representing `block`. + * + * It does this by asking each block level function in the dialect to process + * the block until one can. Succesful handling is indicated by returning an + * array (with zero or more JsonML nodes), failure by a false value. + * + * Blocks handlers are responsible for calling [[Markdown#processInline]] + * themselves as appropriate. + * + * If the blocks were split incorrectly or adjacent blocks need collapsing you + * can adjust `next` in place using shift/splice etc. + * + * If any of this default behaviour is not right for the dialect, you can + * define a `__call__` method on the dialect that will get invoked to handle + * the block processing. + */ +Markdown.prototype.processBlock = function processBlock( block, next ) { + var cbs = this.dialect.block, + ord = cbs.__order__; + + if ( "__call__" in cbs ) { + return cbs.__call__.call(this, block, next); + } + + for ( var i = 0; i < ord.length; i++ ) { + //D:this.debug( "Testing", ord[i] ); + var res = cbs[ ord[i] ].call( this, block, next ); + if ( res ) { + //D:this.debug(" matched"); + if ( !isArray(res) || ( res.length > 0 && !( isArray(res[0]) ) ) ) + this.debug(ord[i], "didn't return a proper array"); + //D:this.debug( "" ); + return res; + } + } + + // Uhoh! no match! Should we throw an error? + return []; +}; + +Markdown.prototype.processInline = function processInline( block ) { + return this.dialect.inline.__call__.call( this, String( block ) ); +}; + +/** + * Markdown#toTree( source ) -> JsonML + * - source (String): markdown source to parse + * + * Parse `source` into a JsonML tree representing the markdown document. + **/ +// custom_tree means set this.tree to `custom_tree` and restore old value on return +Markdown.prototype.toTree = function toTree( source, custom_root ) { + var blocks = source instanceof Array ? source : this.split_blocks( source ); + + // Make tree a member variable so its easier to mess with in extensions + var old_tree = this.tree; + try { + this.tree = custom_root || this.tree || [ "markdown" ]; + + blocks: + while ( blocks.length ) { + var b = this.processBlock( blocks.shift(), blocks ); + + // Reference blocks and the like won't return any content + if ( !b.length ) continue blocks; + + this.tree.push.apply( this.tree, b ); + } + return this.tree; + } + finally { + if ( custom_root ) { + this.tree = old_tree; + } + } +}; + +// Noop by default +Markdown.prototype.debug = function () { + var args = Array.prototype.slice.call( arguments); + args.unshift(this.debug_indent); + if ( typeof print !== "undefined" ) + print.apply( print, args ); + if ( typeof console !== "undefined" && typeof console.log !== "undefined" ) + console.log.apply( null, args ); +} + +Markdown.prototype.loop_re_over_block = function( re, block, cb ) { + // Dont use /g regexps with this + var m, + b = block.valueOf(); + + while ( b.length && (m = re.exec(b) ) != null ) { + b = b.substr( m[0].length ); + cb.call(this, m); + } + return b; +}; + +/** + * Markdown.dialects + * + * Namespace of built-in dialects. + **/ +Markdown.dialects = {}; + +// Build default order from insertion order. +Markdown.buildBlockOrder = function(d) { + var ord = []; + for ( var i in d ) { + if ( i == "__order__" || i == "__call__" ) continue; + ord.push( i ); + } + d.__order__ = ord; +}; + +// Build patterns for inline matcher +Markdown.buildInlinePatterns = function(d) { + var patterns = []; + + for ( var i in d ) { + // __foo__ is reserved and not a pattern + if ( i.match( /^__.*__$/) ) continue; + var l = i.replace( /([\\.*+?|()\[\]{}])/g, "\\$1" ) + .replace( /\n/, "\\n" ); + patterns.push( i.length == 1 ? l : "(?:" + l + ")" ); + } + + patterns = patterns.join("|"); + d.__patterns__ = patterns; + //print("patterns:", uneval( patterns ) ); + + var fn = d.__call__; + d.__call__ = function(text, pattern) { + if ( pattern != undefined ) { + return fn.call(this, text, pattern); + } + else + { + return fn.call(this, text, patterns); + } + }; +}; + +Markdown.DialectHelpers = {}; +Markdown.DialectHelpers.inline_until_char = function( text, want ) { + var consumed = 0, + nodes = []; + + while ( true ) { + if ( text.charAt( consumed ) == want ) { + // Found the character we were looking for + consumed++; + return [ consumed, nodes ]; + } + + if ( consumed >= text.length ) { + // No closing char found. Abort. + return null; + } + + var res = this.dialect.inline.__oneElement__.call(this, text.substr( consumed ) ); + consumed += res[ 0 ]; + // Add any returned nodes. + nodes.push.apply( nodes, res.slice( 1 ) ); + } +} + +var isArray = Array.isArray || function(obj) { + return Object.prototype.toString.call(obj) == "[object Array]"; +}; + +function extract_attr( jsonml ) { + return isArray(jsonml) + && jsonml.length > 1 + && typeof jsonml[ 1 ] === "object" + && !( isArray(jsonml[ 1 ]) ) + ? jsonml[ 1 ] + : undefined; +} + + + +/** + * renderJsonML( jsonml[, options] ) -> String + * - jsonml (Array): JsonML array to render to XML + * - options (Object): options + * + * Converts the given JsonML into well-formed XML. + * + * The options currently understood are: + * + * - root (Boolean): wether or not the root node should be included in the + * output, or just its children. The default `false` is to not include the + * root itself. + */ +expose.renderJsonML = function( jsonml, options ) { + options = options || {}; + // include the root element in the rendered output? + options.root = options.root || false; + + var content = []; + + if ( options.root ) { + content.push( render_tree( jsonml ) ); + } + else { + jsonml.shift(); // get rid of the tag + if ( jsonml.length && typeof jsonml[ 0 ] === "object" && !( jsonml[ 0 ] instanceof Array ) ) { + jsonml.shift(); // get rid of the attributes + } + + while ( jsonml.length ) { + content.push( render_tree( jsonml.shift() ) ); + } + } + + return content.join( "\n\n" ); +}; + +function escapeHTML( text ) { + return text.replace( /&/g, "&" ) + .replace( //g, ">" ) + .replace( /"/g, """ ) + .replace( /'/g, "'" ); +} + +function render_tree( jsonml ) { + // basic case + if ( typeof jsonml === "string" ) { + return escapeHTML( jsonml ); + } + + var tag = jsonml.shift(), + attributes = {}, + content = []; + + if ( jsonml.length && typeof jsonml[ 0 ] === "object" && !( jsonml[ 0 ] instanceof Array ) ) { + attributes = jsonml.shift(); + } + + while ( jsonml.length ) { + content.push( render_tree( jsonml.shift() ) ); + } + + // edge case where tag has been removed at some point (e.g. preprocessTreeNode) + if ( !tag ) { + return content + } + + var tag_attrs = ""; + for ( var a in attributes ) { + tag_attrs += " " + a + '="' + escapeHTML( attributes[ a ] ) + '"'; + } + + // be careful about adding whitespace here for inline elements + if ( tag == "img" || tag == "br" || tag == "hr" ) { + return "<"+ tag + tag_attrs + "/>"; + } + else { + return "<"+ tag + tag_attrs + ">" + content.join( "" ) + ""; + } +} + +function convert_tree_to_html( tree, references, options ) { + var i; + options = options || {}; + + // shallow clone + var jsonml = tree.slice( 0 ); + + if ( typeof options.preprocessTreeNode === "function" ) { + jsonml = options.preprocessTreeNode(jsonml, references); + } + + // Clone attributes if they exist + var attrs = extract_attr( jsonml ); + if ( attrs ) { + jsonml[ 1 ] = {}; + for ( i in attrs ) { + jsonml[ 1 ][ i ] = attrs[ i ]; + } + attrs = jsonml[ 1 ]; + } + + // basic case + if ( typeof jsonml === "string" ) { + return jsonml; + } + + // convert this node + switch ( jsonml[ 0 ] ) { + case "header": + jsonml[ 0 ] = "h" + jsonml[ 1 ].level; + delete jsonml[ 1 ].level; + break; + case "bulletlist": + jsonml[ 0 ] = "ul"; + break; + case "numberlist": + jsonml[ 0 ] = "ol"; + break; + case "listitem": + jsonml[ 0 ] = "li"; + break; + case "para": + jsonml[ 0 ] = "p"; + break; + case "markdown": + jsonml[ 0 ] = "html"; + if ( attrs ) delete attrs.references; + break; + case "code_block": + jsonml[ 0 ] = "pre"; + i = attrs ? 2 : 1; + var code = [ "code" ]; + code.push.apply( code, jsonml.splice( i, jsonml.length - i ) ); + jsonml[ i ] = code; + break; + case "inlinecode": + jsonml[ 0 ] = "code"; + break; + case "img": + jsonml[ 1 ].src = jsonml[ 1 ].href; + delete jsonml[ 1 ].href; + break; + case "linebreak": + jsonml[ 0 ] = "br"; + break; + case "link": + jsonml[ 0 ] = "a"; + break; + case "link_ref": + jsonml[ 0 ] = "a"; + + // grab this ref and clean up the attribute node + var ref = references[ attrs.ref ]; + + // if the reference exists, make the link + if ( ref ) { + delete attrs.ref; + + // add in the href and title, if present + attrs.href = ref.href; + if ( ref.title ) { + attrs.title = ref.title; + } + + // get rid of the unneeded original text + delete attrs.original; + } + // the reference doesn't exist, so revert to plain text + else { + return attrs.original; + } + break; + case "img_ref": + jsonml[ 0 ] = "img"; + + // grab this ref and clean up the attribute node + var ref = references[ attrs.ref ]; + + // if the reference exists, make the link + if ( ref ) { + delete attrs.ref; + + // add in the href and title, if present + attrs.src = ref.href; + if ( ref.title ) { + attrs.title = ref.title; + } + + // get rid of the unneeded original text + delete attrs.original; + } + // the reference doesn't exist, so revert to plain text + else { + return attrs.original; + } + break; + } + + // convert all the children + i = 1; + + // deal with the attribute node, if it exists + if ( attrs ) { + // if there are keys, skip over it + for ( var key in jsonml[ 1 ] ) { + i = 2; + } + // if there aren't, remove it + if ( i === 1 ) { + jsonml.splice( i, 1 ); + } + } + + for ( ; i < jsonml.length; ++i ) { + jsonml[ i ] = convert_tree_to_html( jsonml[ i ], references, options ); + } + + return jsonml; +} + + +// merges adjacent text nodes into a single node +function merge_text_nodes( jsonml ) { + // skip the tag name and attribute hash + var i = extract_attr( jsonml ) ? 2 : 1; + + while ( i < jsonml.length ) { + // if it's a string check the next item too + if ( typeof jsonml[ i ] === "string" ) { + if ( i + 1 < jsonml.length && typeof jsonml[ i + 1 ] === "string" ) { + // merge the second string into the first and remove it + jsonml[ i ] += jsonml.splice( i + 1, 1 )[ 0 ]; + } + else { + ++i; + } + } + // if it's not a string recurse + else { + merge_text_nodes( jsonml[ i ] ); + ++i; + } + } +} + +} )( (function() { + if ( typeof exports === "undefined" ) { + window.markdown = {}; + return window.markdown; + } + else { + return exports; + } +} )() ); +// Released under BSD license +// Copyright (c) 2013 Apollic Software, LLC +(function (expose) { + var Preprocesser, forEach; + + (function (Markdown) { + + // Tent markdown flavor (https://github.com/tent/tent.io/issues/180) + Markdown.dialects.Tent = { + block: { + // member name: fn(block, remaining_blocks) -> json markdown tree or undefined + + // Match inline urls + autolink: function autolink( block, next ) { + var urls = expose.extractUrlsWithIndices(block); + + if (!urls.length) { + // no urls matched + return; + } + + var autolink_items = []; + + var item; + for (var i = 0; i < urls.length; i++) { + item = urls[i]; + + if ( block.slice(0, item.indices[1] + 1).match(/\[[^\]]+\]\([^\)]+\)$/) ) { + // markdown link syntax, don't autolink + continue; + } + + if ( block.slice(item.indices[0] - 1, block.length).match(/^\[[^\]]+\]\([^\)]+\)/) ) { + // url inside markdown link display text, don't autolink + continue; + } + + if ( block.match('`') ) { + // check if the url is inside code backticks + + var _indices = [], + _regex = /`/g, + m = null; + while ( m = _regex.exec(block) ) { + _indices.push(m.index); + } + + var skip = false, + _last_index = null; + if ( _indices.length && (_indices.length % 2 === 0) ) { + for (var j = 0; j < _indices.length; j += 2) { + if ( (_indices[j] < item.indices[0]) && (_indices[j+1] > item.indices[1]) ) { + // matched url is inside code backticks, ignore + _last_index = _indices[j+1]; + skip = true; + } + } + } + + if (skip === true) { + // don't autolink + continue; + } + } + + // we're good to process this link + autolink_items.push(item) + } + + if (!autolink_items.length) { + // there's nothing to autolink + return; + } + + // wrap matched urls in links + + var jsonml = ["para"], + _block = block, + item = null, + index_offset = 0, + before = null; + + for (var i = 0; i < autolink_items.length; i++) { + item = autolink_items[i]; + + // process text before url + before = _block.slice(0, item.indices[0] + index_offset); + if (before.length) { + jsonml = jsonml.concat( this.processInline(before) ); + } + + // linkify url + jsonml.push(["link", { href: item.url }, item.url]); + + // discard processed text + // and update index offset + _block = _block.slice(item.indices[1] + index_offset, _block.length) + index_offset -= before.length + (item.indices[1] - item.indices[0]) + } + + // process remaining text + jsonml = jsonml.concat( this.processInline(_block) ); + + return [jsonml]; + }, + + // Taken from Markdown.dialects.Gruber.block.para + para: function para( block, next ) { + // everything's a para! + return [ ["para"].concat( this.processInline( block ) ) ]; + } + }, + + inline: { + // member pattern_or_regex: (text, match, tree) -> [ length, string_or_tree ] + // __x__ members are not patterns + // __call__ is called by Markdown.prototype.processInline() + + /* + * Reserved member functions: + */ + + // Taken from Markdown.dialect.Gruber.inline.__oneElement__ + __oneElement__: function oneElement( text, patterns_or_re, previous_nodes ) { + var m, + res, + lastIndex = 0; + + patterns_or_re = patterns_or_re || this.dialect.inline.__patterns__; + var re = new RegExp( "([\\s\\S]*?)(" + (patterns_or_re.source || patterns_or_re) + ")" ); + + m = re.exec( text ); + if (!m) { + // Just boring text + return [ text.length, text ]; + } + else if ( m[1] ) { + // Some un-interesting text matched. Return that first + return [ m[1].length, m[1] ]; + } + + var res; + if ( m[2] in this.dialect.inline ) { + res = this.dialect.inline[ m[2] ].call( + this, + text.substr( m.index ), m, previous_nodes || [] ); + } + // Default for now to make dev easier. just slurp special and output it. + res = res || [ m[2].length, m[2] ]; + return res; + }, + + // Taken from Markdown.dialect.Gruber.inline.__call__ + __call__: function inline( text, patterns ) { + + var out = [], + res; + + function add(x) { + //D:self.debug(" adding output", uneval(x)); + if ( typeof x == "string" && typeof out[out.length-1] == "string" ) + out[ out.length-1 ] += x; + else + out.push(x); + } + + while ( text.length > 0 ) { + res = this.dialect.inline.__oneElement__.call(this, text, patterns, out ); + text = text.substr( res.shift() ); + forEach(res, add ) + } + + return out; + }, + + /* + * Pattern member functions: + */ + + // Taken from Markdown.dialects.Gruber.inline + // These characters are intersting elsewhere, so have rules for them so that + // chunks of plain text blocks don't include them + "]": function () {}, + "}": function () {}, + + // Taken from Markdown.dialects.Gruber.inline["\\"] + // Modification: change escape chars (removed { } # + - . ! and added ~) + "\\": function escaped( text ) { + // [ length of input processed, node/children to add... ] + // Only esacape: \ ` * _ [ ] ( ) * ~ + if ( text.match( /^\\[\\`\*_\[\]()\~]/ ) ) + return [ 2, text.charAt( 1 ) ]; + else + // Not an esacpe + return [ 1, "\\" ]; + }, + + "*": function bold( text ) { + // Inline content is possible inside `bold text` + var res = Markdown.DialectHelpers.inline_until_char.call( this, text.substr(1), "*" ); + + // Not bold + if ( !res ) return [ 1, "*" ]; + + var consumed = 1 + res[ 0 ], + children = res[ 1 ]; + + + return [consumed, ["strong"].concat(children)] + }, + + "_": function italic( text ) { + // Inline content is possible inside `bold text` + var res = Markdown.DialectHelpers.inline_until_char.call( this, text.substr(1), "_" ); + + // Not bold + if ( !res ) return [ 1, "_" ]; + + var consumed = 1 + res[ 0 ], + children = res[ 1 ]; + + + return [consumed, ["em"].concat(children)] + }, + + "~": function italic( text ) { + // Inline content is possible inside `bold text` + var res = Markdown.DialectHelpers.inline_until_char.call( this, text.substr(1), "~" ); + + // Not bold + if ( !res ) return [ 1, "~" ]; + + var consumed = 1 + res[ 0 ], + children = res[ 1 ]; + + + return [consumed, ["del"].concat(children)] + }, + + // Taken from Markdown.dialects.Gruber.inline["["] + // Modification: Only allow the most basic link syntax. + "[": function link( text ) { + + var orig = String(text); + // Inline content is possible inside `link text` + var res = Markdown.DialectHelpers.inline_until_char.call( this, text.substr(1), "]" ); + + // No closing ']' found. Just consume the [ + if ( !res ) return [ 1, "[" ]; + + var consumed = 1 + res[ 0 ], + children = res[ 1 ], + link, + attrs; + + // At this point the first [...] has been parsed. See what follows to find + // out which kind of link we are (reference or direct url) + text = text.substr( consumed ); + + // [link text](/path/to/img.jpg) + // 1 <--- captures + // This will capture up to the last paren in the block. We then pull + // back based on if there a matching ones in the url + // ([here](/url/(test)) + // The parens have to be balanced + + var m = text.match( /^\(([^"']*)\)/ ); + if ( m ) { + var url = m[1]; + consumed += m[0].length; + + var open_parens = 1; // One open that isn't in the capture + for ( var len = 0; len < url.length; len++ ) { + switch ( url[len] ) { + case "(": + open_parens++; + break; + case ")": + if ( --open_parens == 0) { + consumed -= url.length - len; + url = url.substring(0, len); + } + break; + } + } + + // Process escapes only + url = this.dialect.inline.__call__.call( this, url, /\\/ )[0]; + + attrs = { href: url || "" }; + + link = [ "link", attrs ].concat( children ); + return [ consumed, link ]; + } + + // Just consume the "[" + return [ 1, "[" ]; + }, + + // Taken from Markdown.dialects.Gruber.inline["`"] + // Modification: Only allow a single opening backtick + "`": function inlineCode( text ) { + // Always skip over the opening tick. + var m = text.match( /(`)(([\s\S]*?)\1)/ ); + + if ( m && m[2] ) + return [ m[1].length + m[2].length, [ "inlinecode", m[3] ] ]; + else { + // No closing backtick, it's just text + return [ 1, "`" ]; + } + }, + + // Taken from Markdown.dialects.Gruber.inline[" \n"] + // Modification: Don't require spaces before \n + "\n": function lineBreak( text ) { + return [ 1, [ "linebreak" ] ]; + } + + } + } + + Markdown.buildBlockOrder ( Markdown.dialects.Tent.block ); + Markdown.buildInlinePatterns( Markdown.dialects.Tent.inline ); + + })( expose.Markdown ) + + // Don't mess with Array.prototype. Its not friendly + if ( Array.prototype.forEach ) { + forEach = function( arr, cb, thisp ) { + return arr.forEach( cb, thisp ); + }; + } + else { + forEach = function(arr, cb, thisp) { + for (var i = 0; i < arr.length; i++) { + cb.call(thisp || arr, arr[i], i, arr); + } + } + } + + Preprocesser = function ( options ) { + this.footnotes = options.footnotes || []; + this.preprocessors = [this.expandFootnoteLinkHrefs].concat(options.preprocessors || []); + } + + Preprocesser.prototype.expandFootnoteLinkHrefs = function ( jsonml ) { + // Skip over anything that isn't a link + if (jsonml[0] !== 'link') return jsonml; + + // Skip over links that arn't footnotes + if (!jsonml[1] || !jsonml[1].href || !/^\d+$/.test(jsonml[1].href)) return jsonml; + + // Get href from footnodes array + var index = parseInt(jsonml[1].href); + jsonml[1].href = this.footnotes[index]; + jsonml[1].onclick = "bungloo.entityProfile.showEntity(this, " + index + "); return false;" + jsonml[1].class = "name"; + + // Unlink node if footnote doesn't exist + if (!jsonml[1].href) { + return [null].concat(jsonml.slice(2)); + } + + return jsonml; + } + + Preprocesser.prototype.preprocessTreeNode = function ( jsonml, references ) { + for (var i=0, _len = this.preprocessors.length; i < _len; i++) { + var fn = this.preprocessors[i] + if (!(typeof fn === 'function')) continue; + jsonml = fn.call(this, jsonml, references); + } + return jsonml; + } + + // Pre-process all link nodes to expand the [text](index) footnote syntax to actual links + // and unlink non-existant footnote references. + // Pass options.footnotes = [ href, ... ] to expand footnote links + __toHTML__ = expose.toHTML; + expose.toHTML = function ( source, dialect, options ) { + options = options || {}; + if (dialect === 'Tent') { + if (!(typeof options.preprocessTreeNode === 'function')) { + preprocesser = new Preprocesser( options ); + options.preprocessTreeNode = function () { + return preprocesser.preprocessTreeNode.apply(preprocesser, arguments); + } + } + } + return __toHTML__.call(null, source, dialect, options); + } +})(function () { + if ( typeof exports === "undefined" ) { + window.markdown.extractUrlsWithIndices = window.twttr.extractUrlsWithIndices; + return window.markdown; + } + else { + exports.markdown = require('markdown').markdown; + exports.markdown.extractUrlsWithIndices = require('./link-matcher').extractUrlsWithIndices; + + return exports.markdown; + } +}()) diff --git a/WebKit/scripts/main.js b/WebKit/scripts/main.js index 8d783b9..64fcaca 100644 --- a/WebKit/scripts/main.js +++ b/WebKit/scripts/main.js @@ -7,14 +7,15 @@ var bungloo = { entityProfile: null, conversation: null, search: null, - cache: {} + cache: { profiles: {}}, + newpost: null }; requirejs.config({ baseUrl: 'scripts' }); -function start(view) { +function start(view, callback) { if (view == "oauth") { @@ -24,6 +25,24 @@ function start(view) { }); + } else if (view == "conversation-standalone") { + + require(["controller/Conversation"], function(Conversation) { + + bungloo.conversation = new Conversation(true); + if(callback) callback(); + + }); + + } else if (view == "newpost") { + + require(["controller/NewPost"], function(NewPost) { + + bungloo.newpost = new NewPost(); + if(callback) callback(); + + }); + } else { @@ -44,32 +63,13 @@ function start(view) { bungloo.conversation = new Conversation(); bungloo.search = new Search(); + bungloo.sidebar.showContentForTimeline(); }); } } -String.prototype.startsWith = function(prefix) { - return this.indexOf(prefix) === 0; -} - -String.prototype.endsWith = function(suffix) { - return this.match(suffix+"$") == suffix; -}; - -var __entityMap = { - "&": "&", - "<": "<", - ">": ">" -}; - -String.prototype.escapeHTML = function() { - return String(this).replace(/[&<>]/g, function (s) { - return __entityMap[s]; - }); -} - var console = { log: function(s) { if (OS_TYPE == "mac") { @@ -110,6 +110,14 @@ var console = { function loadJsPlugin(js_url) { if (js_url) { + + requirejs.config({ + baseUrl: 'scripts', + paths: { + plugins: js_url.replace("Plugin.js", '') + } + }); + var js_plugin = document.createElement("script"); js_plugin.type = "text/javascript"; js_plugin.src = js_url; @@ -131,7 +139,7 @@ function loadCssPlugin(css_url) { function debug(string) { if (typeof string != "string") { - string = JSON.stringify(string); + string = JSON.stringify(string, null, ' '); } console.debug(string); @@ -153,4 +161,46 @@ function go() { // wait untill everything is loaded }, 500); } -go(); \ No newline at end of file +go(); + + +// String stuff +String.prototype.startsWith = function(prefix) { + return this.indexOf(prefix) === 0; +} + +String.prototype.endsWith = function(suffix) { + return this.match(suffix+"$") == suffix; +}; + +var __entityMap = { + "&": "&", + "<": "<", + ">": ">" +}; + +String.prototype.escapeHTML = function() { + return String(this).replace(/[&<>]/g, function (s) { + return __entityMap[s]; + }); +} + +String.prototype.hasArabicCharacter = function() { + var arregex = /[\u0600-\u06FF]/; + return arregex.test(this); +} + +String.prototype.escapeSpecialChars = function() { + return this.replace(/[\\]/g, '\\\\') + .replace(/[\"]/g, '\\\"') + .replace(/[\/]/g, '\\/') + .replace(/[\b]/g, '\\b') + .replace(/[\f]/g, '\\f') + .replace(/[\n]/g, '\\n') + .replace(/[\r]/g, '\\r') + .replace(/[\t]/g, '\\t'); +} + +String.prototype.escapeRegExp = function() { + return this.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); +} \ No newline at end of file diff --git a/Windows/deploy.ps1 b/Windows/deploy.ps1 new file mode 100644 index 0000000..f4ec800 --- /dev/null +++ b/Windows/deploy.ps1 @@ -0,0 +1,13 @@ + +mkdir bungloo +Copy-Item ../Qt/* bungloo -Recurse +Copy-Item ../WebKit bungloo -Recurse +Copy-Item ../images bungloo -Recurse +Copy-Item setup.py bungloo +touch bungloo/__init__.py +Copy-Item msvcp90.dll bungloo +cd bungloo +python setup.py py2exe +cd .. +iscc.exe "installer.iss" +rm bungloo \ No newline at end of file diff --git a/Windows/installer.iss b/Windows/installer.iss new file mode 100644 index 0000000..f01a595 --- /dev/null +++ b/Windows/installer.iss @@ -0,0 +1,57 @@ +; Script generated by the Inno Setup Script Wizard. +; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! + +#define MyAppName "Bungloo" +#define MyAppVersion "2.0.0" +#define MyAppPublisher "Jabs Nu" +#define MyAppURL "http://jabs.nu/bungloo" +#define MyAppExeName "Bungloo.exe" + +[Setup] +; NOTE: The value of AppId uniquely identifies this application. +; Do not use the same AppId value in installers for other applications. +; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) +AppId={{5E44EE00-8ECE-40C8-AF6F-70397DD1DBFE} +AppName={#MyAppName} +AppVersion={#MyAppVersion} +;AppVerName={#MyAppName} {#MyAppVersion} +AppPublisher={#MyAppPublisher} +AppPublisherURL={#MyAppURL} +AppSupportURL={#MyAppURL} +AppUpdatesURL={#MyAppURL} +DefaultDirName={pf}\{#MyAppName} +DefaultGroupName={#MyAppName} +AllowNoIcons=yes +LicenseFile=..\LICENSE.txt +OutputBaseFilename=setup +SetupIconFile=..\images\Icon.ico +Compression=lzma +SolidCompression=yes + +[Languages] +Name: "english"; MessagesFile: "compiler:Default.isl" + +[Tasks] +Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked +Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1 + +[Files] +Source: "bungloo\dist\Bungloo.exe"; DestDir: "{app}"; Flags: ignoreversion +Source: "bungloo\dist\library.zip"; DestDir: "{app}"; Flags: ignoreversion +Source: "bungloo\dist\*.pyd"; DestDir: "{app}"; Flags: ignoreversion +Source: "bungloo\dist\*.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "bungloo\dist\w9xpopen.exe"; DestDir: "{app}"; Flags: ignoreversion +Source: "bungloo\dist\images\*"; DestDir: "{app}\images"; Flags: ignoreversion recursesubdirs createallsubdirs +Source: "bungloo\dist\imageformats\*"; DestDir: "{app}\imageformats"; Flags: ignoreversion recursesubdirs createallsubdirs +Source: "bungloo\dist\WebKit\*"; DestDir: "{app}\WebKit"; Flags: ignoreversion recursesubdirs createallsubdirs +; NOTE: Don't use "Flags: ignoreversion" on any shared system files + +[Icons] +Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}" +Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}" +Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon +Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: quicklaunchicon + +[Run] +Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent + diff --git a/Windows/msvcp90.dll b/Windows/msvcp90.dll new file mode 100644 index 0000000..af6cc3d Binary files /dev/null and b/Windows/msvcp90.dll differ diff --git a/Windows/setup.py b/Windows/setup.py new file mode 100644 index 0000000..1d9da92 --- /dev/null +++ b/Windows/setup.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python2 + +import os +from distutils.core import setup +import py2exe + +files = [] +for dirname, dirnames, filenames in os.walk('WebKit'): + for filename in filenames: + files += [(dirname, [os.path.join(dirname, filename)])] + +for dirname, dirnames, filenames in os.walk('images'): + for filename in filenames: + files += [(dirname, [os.path.join(dirname, filename)])] + +imageformats = [] +for dirname, dirnames, filenames in os.walk('C:\\Python27\\Lib\\site-packages\\PyQt4\\plugins\\imageformats'): + for filename in filenames: + imageformats += [os.path.join(dirname, filename)] + +files += [('imageformats', imageformats)] + +setup( + name = "Bungloo", + version = "2.0.0", + author = "Jeena Paradies", + author_email = "spam@jeenaparadies.net", + url = "http://jabs.nu/bungloo", + license = "BSD license", + data_files = files, + windows = [{ + 'script': "Bungloo.py", + 'icon_resources': [(1, 'images/Icon.ico')], + }], + options = { + "py2exe": { + "includes": ["sip", "ssl", "PyQt4.QtCore", "PyQt4.QtGui", "PyQt4.QtNetwork"], + } + } +) diff --git a/images/Actions-insert-image-icon.png b/images/Actions-insert-image-icon.png deleted file mode 100644 index 05adf9a..0000000 Binary files a/images/Actions-insert-image-icon.png and /dev/null differ diff --git a/images/Icon.ico b/images/Icon.ico new file mode 100644 index 0000000..877fbfa Binary files /dev/null and b/images/Icon.ico differ diff --git a/images/Icon16.png b/images/Icon16.png new file mode 100644 index 0000000..765b5c8 Binary files /dev/null and b/images/Icon16.png differ diff --git a/images/Icon248.png b/images/Icon248.png new file mode 100644 index 0000000..83d5450 Binary files /dev/null and b/images/Icon248.png differ diff --git a/images/Icon32.png b/images/Icon32.png new file mode 100644 index 0000000..fed9bfc Binary files /dev/null and b/images/Icon32.png differ diff --git a/images/Icon48.png b/images/Icon48.png new file mode 100644 index 0000000..71dbc57 Binary files /dev/null and b/images/Icon48.png differ diff --git a/images/Lock-Lock-icon.png b/images/Lock-Lock-icon.png deleted file mode 100644 index 45079c9..0000000 Binary files a/images/Lock-Lock-icon.png and /dev/null differ diff --git a/images/Lock-Unlock-icon.png b/images/Lock-Unlock-icon.png deleted file mode 100644 index 627d59f..0000000 Binary files a/images/Lock-Unlock-icon.png and /dev/null differ diff --git a/readme.md b/readme.md index 72227e2..6173013 100644 --- a/readme.md +++ b/readme.md @@ -1,7 +1,7 @@ Bungloo ======= -Bungloo is a slim Tent client for OS X and Linux written in mostly JavaScript. +Bungloo is a slim Tent client for OS X, Linux and Windows written in mostly JavaScript. For more info check out the Wiki page: https://github.com/jeena/Bungloo/wiki @@ -21,3 +21,4 @@ Thanks everyone in the Open Source community! Bungloo is using: - PyQt - http://wiki.python.org/moin/PyQt - Icon - http://www.fasticon.com - Linux monochrome icons - http://glyphicons.com +- py2exe - http://www.py2exe.org