2 * Adium is the legal property of its developers, whose names are listed in the copyright file included
3 * with this source distribution.
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.
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.
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.
17 #import <Adium/AIInterfaceControllerProtocol.h>
18 #import <Adium/AIPreferenceControllerProtocol.h>
19 #import "CBContactLastSeenPlugin.h"
20 #import <AIUtilities/AIDateFormatterAdditions.h>
21 #import <Adium/AIListObject.h>
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"
27 @interface CBContactLastSeenPlugin(PRIVATE)
28 - (void)update:(NSNotification *)notification;
32 * @class CBContactLastSeenPlugin
33 * @brief Component to track and display as a tooltip the last time contacts were seen online
35 @implementation CBContactLastSeenPlugin
42 //Install our tooltip entry
43 [[adium interfaceController] registerContactListTooltipEntry:self secondaryEntry:NO];
45 //Install our observers
46 [[adium notificationCenter] addObserver:self
47 selector:@selector(statusUpdate:)
48 name:CONTACT_SEEN_ONLINE_YES
51 [[adium notificationCenter] addObserver:self
52 selector:@selector(statusUpdate:)
53 name:CONTACT_STATUS_ONLINE_NO
56 [[adium notificationCenter] addObserver:self
57 selector:@selector(statusUpdate:)
58 name:CONTACT_SEEN_ONLINE_NO
66 * @brief Contact status change notification
68 * @param notification A notificaiton with an AIListObject object and an eventID name
70 - (void)statusUpdate:(NSNotification *)notification
72 AIListObject *inObject = [notification object];
74 //Either they are online, or we've come online. Either way, update both their status and the time
75 if ([[notification name] isEqualToString:CONTACT_SEEN_ONLINE_YES]) {
77 [[adium preferenceController] setPreference:AILocalizedString(@"Online",nil)
78 forKey:KEY_LAST_SEEN_STATUS
79 group:PREF_GROUP_LAST_SEEN
82 [[adium preferenceController] setPreference:[NSDate date]
83 forKey:KEY_LAST_SEEN_DATE
84 group:PREF_GROUP_LAST_SEEN
87 //They've signed off, update their status and the time
88 } else if ([[notification name] isEqualToString:CONTACT_STATUS_ONLINE_NO]) {
90 [[adium preferenceController] setPreference:AILocalizedString(@"Signing off",nil)
91 forKey:KEY_LAST_SEEN_STATUS
92 group:PREF_GROUP_LAST_SEEN
96 [[adium preferenceController] setPreference:[NSDate date]
97 forKey:KEY_LAST_SEEN_DATE
98 group:PREF_GROUP_LAST_SEEN
101 //Don't update the status, just the date
102 } else if ([[notification name] isEqualToString:CONTACT_SEEN_ONLINE_NO]) {
104 [[adium preferenceController] setPreference:[NSDate date]
105 forKey:KEY_LAST_SEEN_DATE
106 group:PREF_GROUP_LAST_SEEN
111 #pragma mark Tooltip entry
112 //Tooltip entry ---------------------------------------------------------------------------------------
115 * @brief Tooltip label
117 * @result A label, or nil if no tooltip entry should be shown
119 - (NSString *)labelForObject:(AIListObject *)inObject
121 return AILocalizedString(@"Last Seen","A time interval such as '4 days ago' will be shown after this tooltip identifier");
125 * @brief Tooltip entry
127 * @result The tooltip entry, or nil if no tooltip should be shown
129 - (NSAttributedString *)entryForObject:(AIListObject *)inObject
131 NSString *lastSeenStatus;
132 NSDate *lastSeenDate;
133 NSDateFormatter *sinceDateFormatter;
134 NSAttributedString *entry = nil;
136 //Only display for offline contacts
137 if (![inObject online]) {
139 lastSeenStatus = [[adium preferenceController] preferenceForKey:KEY_LAST_SEEN_STATUS
140 group:PREF_GROUP_LAST_SEEN
143 lastSeenDate = [[adium preferenceController] preferenceForKey:KEY_LAST_SEEN_DATE
144 group:PREF_GROUP_LAST_SEEN
146 if (lastSeenStatus && lastSeenDate) {
147 NSString *timeElapsed;
148 NSString *timeElapsedWithDesignation;
150 sinceDateFormatter = [[[NSDateFormatter alloc] initWithDateFormat:[NSString stringWithFormat:@"%@, %@",
151 [[NSDateFormatter localizedShortDateFormatter] dateFormat],
152 [NSDateFormatter localizedDateFormatStringShowingSeconds:NO showingAMorPM:YES]]
153 allowNaturalLanguage:YES] autorelease];
155 //stringForTimeIntervalSinceDate may return @"" if it's too short of an interval.
156 timeElapsed = [NSDateFormatter stringForTimeIntervalSinceDate:lastSeenDate showingSeconds:NO abbreviated:NO];
157 if (timeElapsed && [timeElapsed length]) {
158 timeElapsedWithDesignation = [NSString stringWithFormat:@"%@ %@\n",
160 [[[NSUserDefaults standardUserDefaults] objectForKey:NSEarlierTimeDesignations] lastObject]];
162 timeElapsedWithDesignation = @"";
165 entry = [[NSAttributedString alloc]
166 initWithString:[NSString stringWithFormat:
169 timeElapsedWithDesignation,
170 [sinceDateFormatter stringForObjectValue:lastSeenDate]]];
174 return [entry autorelease];