Source/CBContactLastSeenPlugin.m
author Evan Schoenberg
Sat Oct 31 13:13:20 2009 -0500 (2009-10-31)
changeset 2707 6ed082e67639
parent 1946 866f1f27b315
permissions -rw-r--r--
Patch from '''egladil''', with some tweaking by me, to improve out "last seen" monitoring to understand metacontacts and update the values accordingly. Thanks!

Fixes #11652
     1 /* 
     2  * Adium is the legal property of its developers, whose names are listed in the copyright file included
     3  * with this source distribution.
     4  * 
     5  * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
     6  * General Public License as published by the Free Software Foundation; either version 2 of the License,
     7  * or (at your option) any later version.
     8  * 
     9  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
    10  * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
    11  * Public License for more details.
    12  * 
    13  * You should have received a copy of the GNU General Public License along with this program; if not,
    14  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    15  */
    16 
    17 #import <Adium/AIInterfaceControllerProtocol.h>
    18 #import "CBContactLastSeenPlugin.h"
    19 #import <AIUtilities/AIDateFormatterAdditions.h>
    20 #import <Adium/AIListObject.h>
    21 #import <Adium/AIMetaContact.h>
    22 
    23 #define PREF_GROUP_LAST_SEEN	@"Last Seen"
    24 #define KEY_LAST_SEEN_STATUS	@"Last Seen Status"
    25 #define KEY_LAST_SEEN_DATE		@"Last Seen Date"
    26 
    27 /*!
    28  * @class CBContactLastSeenPlugin
    29  * @brief Component to track and display as a tooltip the last time contacts were seen online
    30  */
    31 @implementation CBContactLastSeenPlugin
    32 
    33 /*!
    34  * @brief Install
    35  */
    36 - (void)installPlugin
    37 {
    38     //Install our tooltip entry
    39     [adium.interfaceController registerContactListTooltipEntry:self secondaryEntry:NO];
    40 
    41 	//Observe status changes
    42     [[AIContactObserverManager sharedManager] registerListObjectObserver:self];
    43 }
    44 
    45 - (NSSet *)updateListObject:(AIListObject *)inObject keys:(NSSet *)inModifiedKeys silent:(BOOL)silent
    46 {
    47 	/* Update only for contacts whose online status has changed */
    48 	if ([inObject isKindOfClass:[AIListContact class]]) {
    49 		if ([inModifiedKeys containsObject:@"Online"]) {
    50 			if (inObject.online) {
    51 				//Either they are online, or we've come online. Either way, update both their status and the time
    52 				[inObject setPreference:AILocalizedString(@"Online",nil)
    53 								 forKey:KEY_LAST_SEEN_STATUS
    54 								  group:PREF_GROUP_LAST_SEEN];
    55 				
    56 				[inObject setPreference:[NSDate date]
    57 								 forKey:KEY_LAST_SEEN_DATE
    58 								  group:PREF_GROUP_LAST_SEEN];
    59 				
    60 				
    61 			} else {
    62 				if (!silent) {
    63 					//They've signed off, update their status and the time		
    64 					[inObject setPreference:AILocalizedString(@"Signing off",nil)
    65 									 forKey:KEY_LAST_SEEN_STATUS
    66 									  group:PREF_GROUP_LAST_SEEN];
    67 					
    68 					[inObject setPreference:[NSDate date]
    69 									 forKey:KEY_LAST_SEEN_DATE
    70 									  group:PREF_GROUP_LAST_SEEN];	
    71 				} else {
    72 					/* Don't update the status, as we didn't see them signing off but
    73 					 * rather we signed off (silent updates are grouped ones.)
    74 					 * Just update the date.
    75 					 */
    76 					[inObject setPreference:[NSDate date]
    77 									 forKey:KEY_LAST_SEEN_DATE
    78 									  group:PREF_GROUP_LAST_SEEN];
    79 				}
    80 			}
    81 		}
    82 	}
    83 	
    84 	return nil;	
    85 }
    86 
    87 #pragma mark Tooltip entry
    88 //Tooltip entry ---------------------------------------------------------------------------------------
    89 
    90 /*!
    91  * @brief Tooltip label
    92  *
    93  * @result A label, or nil if no tooltip entry should be shown
    94  */
    95 - (NSString *)labelForObject:(AIListObject *)inObject
    96 {
    97     return AILocalizedString(@"Last Seen","A time interval such as '4 days ago' will be shown after this tooltip identifier");
    98 }
    99 
   100 /*!
   101  * @brief Tooltip entry
   102  *
   103  * @result The tooltip entry, or nil if no tooltip should be shown
   104  */
   105 - (NSAttributedString *)entryForObject:(AIListObject *)inObject
   106 {
   107 	NSString			*lastSeenStatus;
   108 	NSDate				*lastSeenDate;
   109 	NSDateFormatter		*sinceDateFormatter;
   110 	NSAttributedString	*entry = nil;
   111 	
   112 	//Only display for offline contacts
   113 	if (!inObject.online) {
   114 	
   115 		lastSeenStatus = [adium.preferenceController preferenceForKey:KEY_LAST_SEEN_STATUS 
   116 																  group:PREF_GROUP_LAST_SEEN
   117 																 object:inObject];
   118 		
   119 		lastSeenDate = [adium.preferenceController preferenceForKey:KEY_LAST_SEEN_DATE 
   120 																group:PREF_GROUP_LAST_SEEN
   121 															   object:inObject];
   122 		if (lastSeenStatus && lastSeenDate) {
   123 			NSString	*timeElapsed;
   124 			NSString	*timeElapsedWithDesignation;
   125 			
   126 			sinceDateFormatter = [[[NSDateFormatter alloc] init] autorelease];
   127 			[sinceDateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
   128 			[sinceDateFormatter setDateFormat:[NSString stringWithFormat:@"%@, %@",
   129 											   [[NSDateFormatter localizedShortDateFormatter] dateFormat],
   130 											   [NSDateFormatter localizedDateFormatStringShowingSeconds:NO showingAMorPM:YES]]];
   131 			
   132 			//stringForTimeIntervalSinceDate may return @"" if it's too short of an interval.
   133 			timeElapsed = [NSDateFormatter stringForTimeIntervalSinceDate:lastSeenDate showingSeconds:NO abbreviated:NO];
   134 			if (timeElapsed && [timeElapsed length]) {
   135 				timeElapsedWithDesignation = [NSString stringWithFormat:
   136 					AILocalizedString(@"%@ ago", "%@ will be replaced by an amount of time such as '1 day, 4 hours'. This string is used in the 'Last Seen:' information shown when hovering over an offline contact."),
   137 					timeElapsed];
   138 			} else {
   139 				timeElapsedWithDesignation = @"";
   140 			}
   141 			
   142 			
   143 			entry = [[NSAttributedString alloc] 
   144 						initWithString:[NSString stringWithFormat:
   145 							@"%@\n%@%@%@", 
   146 							lastSeenStatus,
   147 							timeElapsedWithDesignation,
   148 							([timeElapsedWithDesignation length] ? @"\n" : @""),
   149 							[sinceDateFormatter stringForObjectValue:lastSeenDate]]]; 
   150 		}
   151 	}
   152 	
   153 	return [entry autorelease];
   154 }
   155 
   156 - (BOOL)shouldDisplayInContactInspector
   157 {
   158 	return YES;
   159 }
   160 
   161 @end