Browse Source

Merge branch 'master' of https://github.com/n0shake/Clocker

pull/113/head
Abhishek Banthia 3 years ago
parent
commit
907bfc0a79
  1. 429
      Clocker/Clocker/ja.lproj/Localizable.strings
  2. 424
      Clocker/Clocker/zh-Hant.lproj/Localizable.strings
  3. 13
      Clocker/CoreModelKit/Sources/CoreModelKit/SearchResults.swift
  4. 4
      Clocker/Onboarding/OnboardingSearchController.swift
  5. 6
      Clocker/Overall App/Themer.swift
  6. 5
      Clocker/Panel/ParentPanelController.swift
  7. 9
      Clocker/Panel/Rate Controller/ReviewController.swift
  8. 11
      Clocker/Preferences/App Feedback/AppFeedbackWindowController.swift
  9. 22
      Clocker/Preferences/General/PreferencesViewController.swift
  10. 2
      Clocker/Preferences/Menu Bar/StatusItemHandler.swift
  11. 55
      Clocker/Preferences/OneWindowController.swift
  12. 52
      Clocker/Preferences/Preferences.storyboard
  13. 17
      Readme.md

429
Clocker/Clocker/ja.lproj/Localizable.strings

@ -1,166 +1,357 @@
"About Tab" = "このプログラムについて";
"Add Button Title" = "追加";
"Appearance Tab" = "外観";
"Back" = "戻る";
/*
Localizable.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
*/
"CFBundleDisplayName" = "Clocker";
"Thank you for helping make Clocker even better!" = "Clocker の品質向上にご協力いただきありがとうございます!";
"iRateMessageTitle" = "%@ を評価";
"iRateAppMessage" = "%@ がお気に召したのであれば、評価をして頂けますか? 1分とはかかりません。ご協力ありがとうございます!";
"iRateGameMessage" = "%@ がお気に召したのであれば、評価をして頂けますか? 1分とはかかりません。ご協力ありがとうございます!";
"iRateCancelButton" = "いいえ、結構です";
"iRateRateButton" = "今すぐ評価します";
"iRateRemindButton" = "後で通知する";
"iRateUpdateMessage" = "今すぐアップデートしますか?";
"ClockerVersion" = "バージョン %@";
"CLFeedbackAlertTitle" = "Clocker の品質向上にご協力いただきありがとうございます!";
"app-name" = "Clocker";
"start-at-login" = "ログイン時に開始";
"setup-steps" = "Clocker のセットアップは3ステップのみです";
"Permissions-Header" = "アクセス許可";
"See your next Calendar event here." = "次回のカレンダーイベントはこちらをご覧ください。";
"Click here to start." = "ここをクリックして開始します。";
"Reminders Access" = "リマインダーアクセス";
"Calendar Access" = "カレンダーアクセス";
"Permissions" = "アクセス許可";
/* Permissions */
"Calendar Access Title" = "カレンダーアクセス";
"Calendar Detail" = "個人カレンダーおよび共有カレンダーからの今後のイベントをメニューバーとパネルに表示させることができます。";
"Reminders Detail" = "選択したロケーションのタイムゾーンでリマインダーを設定します。リマインダーはデフォルトのリマインダーアプリに保存されます。";
"Privacy Text" = "この設定はシステム環境設定のプライバシーセクションであとから変更が可能です。";
"Granted Button Text" = "許可されています";
"Denied Button Text" = "拒否されています";
"Grant Button Text" = "許可";
// Welcome Onboarding
"It only takes 3 steps to setup Clocker." = "Clocker のセットアップは3ステップのみです。";
"Get Started" = "はじめに";
// Tab Item Titles
"Preferences Tab" = "設定";
"Appearance Tab" = "外観";
"Calendar Tab" = "カレンダー";
"About Tab" = "このプログラムについて";
"Permissions Tab" = "アクセス許可";
// General Preferences Screen
"Start at Login" = "ログイン時に Clocker を開始";
"Sort by Time Difference" = "時差で並べ替え";
"Sort by Name" = "地名で並べ替え";
"Sort by Label" = "ラベルで並べ替え";
"Search Field Placeholder" = "都市名、州や県、国名を入力してください";
"No Timezone Selected" = "時間帯を選択してください!";
"Max Timezones Selected" = "最大で100の時間帯が設定可能です!";
"Max Search Characters" = "設定可能な文字数は50です!";
"Add Button Title" = "追加";
"Close Button Title" = "閉じる";
// Onboarding
"Open Clocker At Login" = "ログイン時に Clocker を開始";
"Launch Clocker" = "Clocker を起動";
"Click here to start." = "ここをクリックして開始します。";
// Welcome Onboarding
"It only takes 3 steps to set up Clocker." = "Clocker のセットアップは3ステップのみです。";
"Get Started" = "はじめに";
// Permissions
"Calendar Access Title" = "カレンダーアクセス";
"Reminders Access Title" = "リマインダーアクセス";
"Later Config Description" = "これらはシステム環境設定で後から設定できます。";
"Back" = "戻る";
"Continue" = "続ける";
"Clocker is more useful when it can display events from your calendars." = "Clocker is more useful when it can display events from your calendars.";
"Clocker is more useful when it can display events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy." = "Clocker is more useful when it can display events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy.";
"Launch Preferences" = "Launch Preferences";
"Grant Access" = "Grant Access";
"Upcoming events from your personal and shared calendars can be shown in the menubar and the panel." = "Upcoming events from your personal and shared calendars can be shown in the menubar and the panel.";
"Granted" = "Granted";
"Denied" = "Denied";
"Grant" = "Grant";
"Unexpected" = "Unexpected";
// Onboarding Search
"Quick Add Locations" = "場所を簡単に追加";
"More search options in Clocker Preferences." = "More search options in Clocker Preferences.";
"Enter 3 or more characters for locations you'll like to add" = "Enter 3 or more characters for locations you'll like to add";
// Start at Login
"Launch at Login" = "Launch at Login";
"This can be configured later in Clocker Preferences." = "This can be configured later in Clocker Preferences.";
"Should Clocker open automatically on startup?" = "Should Clocker open automatically on startup?";
"ClockerVersion" = "バージョン %@";
"Close Button Title" = "閉じる";
"Contact Information (Optional)" = "Contact Information (Optional)";
"Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!" = "Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!";
"Continue" = "続ける";
"Copied to Clipboard" = "Copied to Clipboard";
// Final Onboarding Screen
"You're all set!" = "You're all set!";
"Thank you for the details." = "Thank you for the details.";
"You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences." = "アプリを起動すると、メニューバーに時計のアイコンが表示されます。ドックのアイコンが表示される場合は、format@@0に進みます。";
"If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!" = "If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!";
// Appearance Tab
"Panel Theme" = "Panel Theme";
"Favourite a timezone to enable menubar display options." = "Favourite a timezone to enable menubar display options.";
"Main Panel Options" = "Main Panel Options";
"Time Format" = "Time Format";
"Day Display Options" = "Day Display Options";
"Show Future Slider" = "Show Future Slider";
"Show Sunrise/Sunset" = "Show Sunrise/Sunset";
/* DST changes */
"Daylights Saving transition will occur in < 24 hours" = "Daylights Saving transition will occur in < 24 hours";
"Denied" = "Denied";
"Denied Button Text" = "拒否されています";
"Display the time in seconds" = "Display the time in seconds";
"Larger Text" = "Larger Text";
/* Review */
"Enjoy using Clocker?" = "Enjoy using Clocker?";
"Enter 3 or more characters for locations you'll like to add" = "Enter 3 or more characters for locations you'll like to add";
"Favourite a timezone to enable menubar display options." = "メニューバーの表示オプションを有効にするには、タイムゾーンをお気に入りとして登録してください。";
/* About View Screen */
"Feedback is always welcome:" = "Feedback is always welcome:";
"Florida" = "Florida";
"Future Slider Range" = "Future Slider Range";
"Get Started" = "はじめに";
"Get Started" = "はじめに";
"Grant" = "Grant";
"Grant Access" = "Grant Access";
"Grant Button Text" = "許可";
"Granted" = "Granted";
"Granted Button Text" = "許可されています";
"Great going." = "Great going.";
"Happy Weekend." = "Happy Weekend.";
"If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"" = "If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"";
"If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!" = "If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!";
"Include Date" = "Include Date";
"Include Day" = "Include Day";
"Include Place Name" = "Include Place Name";
"Menubar Display Options" = "Menubar Display Options";
"Menubar Mode" = "Menubar Mode";
"Preview" = "プレビュー";
"Miscellaneous" = "Miscellaneous";
// Empty View
/* Welcome Onboarding */
"It only takes 3 steps to set up Clocker." = "Clocker のセットアップは3ステップのみです。";
/* Welcome Onboarding */
"It only takes 3 steps to setup Clocker." = "Clocker のセットアップは3ステップのみです。";
"Larger Text" = "Larger Text";
"Later Config Description" = "これらはシステム環境設定で後から設定できます。";
"Launch Clocker" = "Clocker を起動";
"Launch Preferences" = "Launch Preferences";
/* Start at Login */
"Launch at Login" = "Launch at Login";
"Main Panel Options" = "Main Panel Options";
"Max Search Characters" = "設定可能な文字数は50です!";
"Max Timezones Selected" = "最大で100の時間帯が設定可能です!";
"Menubar Display Options" = "メニューバーの表示オプション";
"Menubar Mode" = "メニューバーモード";
"Miscellaneous" = "その他";
"More search options in Clocker Preferences." = "More search options in Clocker Preferences.";
/* UI Tests */
"New Zealand" = "New Zealand";
"No Timezone Selected" = "時間帯を選択してください!";
/* Empty View */
"No places added" = "No places added";
// Panel
/* Panel */
"No upcoming event." = "No upcoming event.";
"You have no events scheduled for tomorrow." = "You have no events scheduled for tomorrow.";
// Review
"Enjoy using Clocker?" = "Enjoy using Clocker?";
// App Feedback
"Tell us what you think!" = "Tell us what you think!";
"Contact Information (Optional)" = "Contact Information (Optional)";
"Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!" = "Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!";
"No upcoming events for today!" = "No upcoming events for today!";
/* Onboarding */
"Open Clocker At Login" = "ログイン時に Clocker を開始";
/* Appearance Tab */
"Panel Theme" = "Panel Theme";
"Permissions" = "アクセス許可";
"Permissions Tab" = "アクセス許可";
"Permissions-Header" = "アクセス許可";
/* Tab Item Titles */
"Preferences Tab" = "設定";
"Preview" = "プレビュー";
"Privacy Text" = "この設定はシステム環境設定のプライバシーセクションであとから変更が可能です。";
/* Onboarding Search */
"Quick Add Locations" = "場所を簡単に追加";
/* Notes Popover */
"Reminder Set" = "Reminder Set";
"Reminders Access" = "リマインダーアクセス";
"Reminders Access Title" = "リマインダーアクセス";
"Reminders Detail" = "選択したロケーションのタイムゾーンでリマインダーを設定します。リマインダーはデフォルトのリマインダーアプリに保存されます。";
"San Francisco" = "San Francisco";
"Search Field Placeholder" = "都市名、州や県、国名を入力してください";
"See your next Calendar event here." = "次回のカレンダーイベントはこちらをご覧ください。";
"Should Clocker open automatically on startup?" = "Should Clocker open automatically on startup?";
// About View Screen
"Feedback is always welcome:" = "Feedback is always welcome:";
// Calendars View
"Upcoming Event View Options" = "Upcoming Event View Options";
"Show Upcoming Event View" = "Show Upcoming Event View";
"Show All Day Meetings" = "Show All Day Meetings";
"Show Future Slider" = "Show Future Slider";
"Show Next Meeting Title in Menubar" = "次のミーティングタイトルをメニューバーに表示する";
"Truncate menubar text longer than" = "Truncate menubar text longer than";
"characters" = "characters";
"Show Sunrise/Sunset" = "Show Sunrise/Sunset";
"Show Upcoming Event View" = "Show Upcoming Event View";
"Show events from" = "Show events from";
"If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"" = "If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"";
// Notes Popover
"Reminder Set" = "Reminder Set";
"Sort by Label" = "ラベルで並べ替え";
"Sort by Name" = "地名で並べ替え";
"Sort by Time Difference" = "時差で並べ替え";
/* General Preferences Screen */
"Start at Login" = "ログイン時に Clocker を開始";
"Successfully set." = "Successfully set.";
// Errors
"You're offline, maybe?" = "オフラインのようです。";
"Try again, maybe?" = "Try again, maybe?";
/* App Feedback */
"Tell us what you think!" = "Tell us what you think!";
"Thank you for helping make Clocker even better!" = "Clocker の品質向上にご協力いただきありがとうございます!";
"Thank you for the details." = "Thank you for the details.";
"The Internet connection appears to be offline." = "The Internet connection appears to be offline.";
// UI Tests
"New Zealand" = "New Zealand";
"Florida" = "Florida";
"San Francisco" = "San Francisco";
// DST changes
"Daylights Saving transition will occur in < 24 hours" = "Daylights Saving transition will occur in < 24 hours";
"This can be configured later in Clocker Preferences." = "This can be configured later in Clocker Preferences.";
"Copied to Clipboard" = "Copied to Clipboard";
"No upcoming events for today!" = "No upcoming events for today!";
"Great going." = "Great going.";
"Happy Weekend." = "Happy Weekend.";
"Time Format" = "Time Format";
"Truncate menubar text longer than" = "Truncate menubar text longer than";
"Try again, maybe?" = "Try again, maybe?";
"Unexpected" = "Unexpected";
/* Calendars View */
"Upcoming Event View Options" = "Upcoming Event View Options";
"Upcoming events from your personal and shared calendars can be shown in the menubar and the panel." = "Upcoming events from your personal and shared calendars can be shown in the menubar and the panel.";
"You have no events scheduled for tomorrow." = "You have no events scheduled for tomorrow.";
"You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences." = "アプリを起動すると、メニューバーに時計のアイコンが表示されます。ドックのアイコンが表示される場合は、format@@0に進みます。";
/* Final Onboarding Screen */
"You're all set!" = "You're all set!";
/* Errors */
"You're offline, maybe?" = "オフラインのようです。";
"app-name" = "Clocker";
"characters" = "characters";
"iRateAppMessage" = "%@ がお気に召したのであれば、評価をして頂けますか? 1分とはかかりません。ご協力ありがとうございます!";
"iRateCancelButton" = "いいえ、結構です";
"iRateGameMessage" = "%@ がお気に召したのであれば、評価をして頂けますか? 1分とはかかりません。ご協力ありがとうございます!";
"iRateMessageTitle" = "%@ を評価";
"iRateRateButton" = "今すぐ評価します";
"iRateRemindButton" = "後で通知する";
"iRateUpdateMessage" = "今すぐアップデートしますか?";
"setup-steps" = "Clocker のセットアップは3ステップのみです";
"start-at-login" = "ログイン時に開始";

424
Clocker/Clocker/zh-Hant.lproj/Localizable.strings

@ -1,167 +1,357 @@
"About Tab" = "關於";
"Add Button Title" = "新增";
"Appearance Tab" = "外觀";
"Back" = "返回";
/*
Localizable.strings
Clocker
Created by Abhishek Banthia on 3/27/16.
*/
*/
"CFBundleDisplayName" = "Clocker";
"Thank you for helping make Clocker even better!" = "感謝您的幫助,讓 Clocker 變得更好!";
"iRateMessageTitle" = "評價 %@";
"iRateAppMessage" = "如果您喜歡使用 %@ 的話,您是否願意花一點給予評價?不需要一分鐘就能完成。感謝您的支持!";
"iRateGameMessage" = "如果您喜歡遊玩 %@ 的話,您是否願意花一點給予評價?不需要一分鐘就能完成。感謝您的支持!";
"iRateCancelButton" = "不用了,謝謝!";
"iRateRateButton" = "現在評分吧!";
"iRateRemindButton" = "下次再提醒我";
"iRateUpdateMessage" = "立即更新";
"ClockerVersion" = "版本:%@";
"CLFeedbackAlertTitle" = "感謝您的幫助,讓 Clocker 變得更好!";
"app-name" = "Clocker";
"start-at-login" = "在登入時啟動";
"setup-steps" = "設定 Clocker 只需要 3 個步驟";
"Permissions-Header" = "權限";
"See your next Calendar event here." = "在此查看你的下一個日曆活動。";
"Click here to start." = "開始";
"Reminders Access" = "取用提醒事項";
"Calendar Access" = "取用您的行事曆";
"Permissions" = "權限";
/* Permissions */
"Calendar Access Title" = "取用您的行事曆";
"Calendar Detail" = "即將到來的行程會在選單列和面板中顯示。";
"Reminders Detail" = "根據你選擇的位置設定提醒。您的提醒將儲存在預設的提醒事項應用程式。";
"Privacy Text" = "您稍後可以在「系統偏好設定」>「安全性與隱私權」中更改。";
"Granted Button Text" = "允許";
"Denied Button Text" = "拒絕";
"Grant Button Text" = "允許";
// Welcome Onboarding
"It only takes 3 steps to setup Clocker." = "設定 Clocker 只需要 3 個步驟。";
"Get Started" = "開始使用";
// Tab Item Titles
"Preferences Tab" = "偏好設定";
"Appearance Tab" = "外觀";
"Calendar Tab" = "行事曆";
"About Tab" = "關於";
"Permissions Tab" = "權限";
// General Preferences Screen
"Start at Login" = "登入時打開 Clocker";
"Sort by Time Difference" = "按時差排序";
"Sort by Name" = "按名稱排序";
"Sort by Label" = "按標籤排序";
"Search Field Placeholder" = "輸入一個地點的名稱";
"No Timezone Selected" = "請選取一個時區!";
"Max Timezones Selected" = "最多允許 100 個時區!";
"Max Search Characters" = "只允許 50 個字元!";
"Add Button Title" = "新增";
"Close Button Title" = "關閉";
// Onboarding
"Open Clocker At Login" = "在登入時打開 Clocker";
"Launch Clocker" = "啟動 Clocker";
"Click here to start." = "開始";
// Welcome Onboarding
"It only takes 3 steps to set up Clocker." = "設定 Clocker 只需要 3 個步驟。";
"Get Started" = "開始使用";
// Permissions
"Calendar Access Title" = "取用您的行事曆";
"Reminders Access Title" = "取用提醒事項";
"Later Config Description" = "這些可以稍後在「系統偏好設定」中進行設置。";
"Back" = "返回";
"Continue" = "繼續";
"Clocker is more useful when it can display events from your calendars." = "從您的行事曆顯示行程將使 Clocker 更實用。";
"Clocker is more useful when it can display events from your calendars. You can change this setting in System Preferences › Security & Privacy › Privacy." = "從您的行事曆顯示行程將使 Clocker 更實用。您可以在「系統偏好設定」>「安全性與隱私」>「隱私權」更改此設定。";
/* Text for button that takes the user to the System Preferences app. In case the user hasn't given Calendar/Reminders access permission, this button takes you to the System Preferences app where the user can give proper permissions to Clocker. */
"Launch Preferences" = "啟動偏好設定";
"Grant Access" = "允許存取";
"Upcoming events from your personal and shared calendars can be shown in the menubar and the panel." = "即將到來的行程會在選單列和面板中顯示。";
"Granted" = "允許";
"Denied" = "拒絕";
"Grant" = "允許";
"Unexpected" = "無法預期的";
// Onboarding Search
"Quick Add Locations" = "快速加入位置";
"More search options in Clocker Preferences." = "在 Clocker 偏好設定中更多的搜尋選項。";
"Enter 3 or more characters for locations you'll like to add" = "為您想加入的位置輸入 3 個或更多字元";
// Start at Login
"Launch at Login" = "登入時啟動";
"This can be configured later in Clocker Preferences." = "這可以稍後在 Clocker 偏好設定中進行設置。";
"Should Clocker open automatically on startup?" = "啟動時自動打開 Clocker?";
"ClockerVersion" = "版本:%@";
"Close Button Title" = "關閉";
"Contact Information (Optional)" = "聯絡資訊(可留空)";
"Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!" = "聯絡欄為可選填欄位!我們需要更多資訊或協助時,將會透過聯絡資訊聯絡您!";
"Continue" = "繼續";
"Copied to Clipboard" = "Copied to Clipboard";
// Final Onboarding Screen
"You're all set!" = "設定完成。";
"Thank you for the details." = "Thank you for the details.";
"You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences." = "當應用程式啟動時,您將會在選單列看到 Clocker 圖像。如果您想在 Dock 上看到圖像,請前往偏好設定。";
"If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!" = "If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!";
// Appearance Tab
"Panel Theme" = "面板主題";
"Favourite a timezone to enable menubar display options." = "將一時區設為喜好項目以啟用選單列顯示選項。";
"Main Panel Options" = "主要面板選項";
"Time Format" = "時間格式";
"Day Display Options" = "日期顯示選項";
"Show Future Slider" = "顯示未來滑桿";
"Show Sunrise/Sunset" = "顯示日出/日落";
/* DST changes */
"Daylights Saving transition will occur in < 24 hours" = "Daylights Saving transition will occur in < 24 hours";
"Denied" = "拒絕";
"Denied Button Text" = "拒絕";
"Display the time in seconds" = "顯示時間秒數";
"Larger Text" = "文字大小";
/* Review */
"Enjoy using Clocker?" = "喜歡使用 Clocker 嗎?";
"Enter 3 or more characters for locations you'll like to add" = "為您想加入的位置輸入 3 個或更多字元";
"Favourite a timezone to enable menubar display options." = "將一時區設為喜好項目以啟用選單列顯示選項。";
/* About View Screen */
"Feedback is always welcome:" = "Feedback is always welcome:";
"Florida" = "佛羅里達";
"Future Slider Range" = "未來滑桿範圍";
"Get Started" = "開始使用";
"Get Started" = "開始使用";
"Grant" = "允許";
"Grant Access" = "允許存取";
"Grant Button Text" = "允許";
"Granted" = "允許";
"Granted Button Text" = "允許";
"Great going." = "Great going.";
"Happy Weekend." = "Happy Weekend.";
"If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"" = "如果會議標題為「Meeting with Neel」、文字長度限制為 5,選單列中的文字將顯示為「Meeti...」。";
"If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!" = "If you'd like to help us localize the app in your language or receive infrequent app-related updates, please enter your email!";
"Include Date" = "包含日期";
"Include Day" = "包含星期";
"Include Place Name" = "包含位置名稱";
/* Welcome Onboarding */
"It only takes 3 steps to set up Clocker." = "設定 Clocker 只需要 3 個步驟。";
/* Welcome Onboarding */
"It only takes 3 steps to setup Clocker." = "設定 Clocker 只需要 3 個步驟。";
"Larger Text" = "文字大小";
"Later Config Description" = "這些可以稍後在「系統偏好設定」中進行設置。";
"Launch Clocker" = "啟動 Clocker";
/* Text for button that takes the user to the System Preferences app. In case the user hasn't given Calendar/Reminders access permission, this button takes you to the System Preferences app where the user can give proper permissions to Clocker. */
"Launch Preferences" = "啟動偏好設定";
/* Start at Login */
"Launch at Login" = "登入時啟動";
"Main Panel Options" = "主要面板選項";
"Max Search Characters" = "只允許 50 個字元!";
"Max Timezones Selected" = "最多允許 100 個時區!";
"Menubar Display Options" = "選單列顯示選項";
"Menubar Mode" = "選單列模式";
"Preview" = "預覽";
"Miscellaneous" = "其他設定";
// Empty View
"More search options in Clocker Preferences." = "在 Clocker 偏好設定中更多的搜尋選項。";
/* UI Tests */
"New Zealand" = "紐西蘭";
"No Timezone Selected" = "請選取一個時區!";
/* Empty View */
"No places added" = "未加入地點";
// Panel
/* Panel */
"No upcoming event." = "沒有即將到來的行程";
"You have no events scheduled for tomorrow." = "您明天沒有排任何行程。";
// Review
"Enjoy using Clocker?" = "喜歡使用 Clocker 嗎?";
// App Feedback
"Tell us what you think!" = "告訴我們您的想法!";
"Contact Information (Optional)" = "聯絡資訊(可留空)";
"Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!" = "聯絡欄為可選填欄位!我們需要更多資訊或協助時,將會透過聯絡資訊聯絡您!";
"No upcoming events for today!" = "No upcoming events for today!";
/* Onboarding */
"Open Clocker At Login" = "在登入時打開 Clocker";
/* Appearance Tab */
"Panel Theme" = "面板主題";
"Permissions" = "權限";
"Permissions Tab" = "權限";
"Permissions-Header" = "權限";
/* Tab Item Titles */
"Preferences Tab" = "偏好設定";
"Preview" = "預覽";
"Privacy Text" = "您稍後可以在「系統偏好設定」>「安全性與隱私權」中更改。";
/* Onboarding Search */
"Quick Add Locations" = "快速加入位置";
/* Notes Popover */
"Reminder Set" = "Reminder Set";
"Reminders Access" = "取用提醒事項";
"Reminders Access Title" = "取用提醒事項";
"Reminders Detail" = "根據你選擇的位置設定提醒。您的提醒將儲存在預設的提醒事項應用程式。";
"San Francisco" = "舊金山";
"Search Field Placeholder" = "輸入一個地點的名稱";
"See your next Calendar event here." = "在此查看你的下一個日曆活動。";
"Should Clocker open automatically on startup?" = "啟動時自動打開 Clocker?";
// About View Screen
"Feedback is always welcome:" = "Feedback is always welcome:";
// Calendars View
"Upcoming Event View Options" = "即將到來的行程顯示選項";
"Show Upcoming Event View" = "顯示即將到來的行程";
"Show All Day Meetings" = "顯示整日的行程";
"Show Future Slider" = "顯示未來滑桿";
"Show Next Meeting Title in Menubar" = "在選單列中顯示下個行程";
"Truncate menubar text longer than" = "選單列文字長度限制";
"characters" = "字元";
"Show Sunrise/Sunset" = "顯示日出/日落";
"Show Upcoming Event View" = "顯示即將到來的行程";
"Show events from" = "Show events from";
"If meeting title is \"Meeting with Neel\" and truncate length is set to 5, text in menubar will appear as \"Meeti...\"" = "如果會議標題為「Meeting with Neel」、文字長度限制為 5,選單列中的文字將顯示為「Meeti...」。";
// Notes Popover
"Reminder Set" = "Reminder Set";
"Sort by Label" = "按標籤排序";
"Sort by Name" = "按名稱排序";
"Sort by Time Difference" = "按時差排序";
/* General Preferences Screen */
"Start at Login" = "登入時打開 Clocker";
"Successfully set." = "設定成功。";
// Errors
"You're offline, maybe?" = "You're offline, maybe?";
"Try again, maybe?" = "再試一次?";
/* App Feedback */
"Tell us what you think!" = "告訴我們您的想法!";
"Thank you for helping make Clocker even better!" = "感謝您的幫助,讓 Clocker 變得更好!";
"Thank you for the details." = "Thank you for the details.";
"The Internet connection appears to be offline." = "Internet連線已斷開。";
// UI Tests
"New Zealand" = "紐西蘭";
"Florida" = "佛羅里達";
"San Francisco" = "舊金山";
// DST changes
"Daylights Saving transition will occur in < 24 hours" = "Daylights Saving transition will occur in < 24 hours";
"This can be configured later in Clocker Preferences." = "這可以稍後在 Clocker 偏好設定中進行設置。";
"Copied to Clipboard" = "Copied to Clipboard";
"No upcoming events for today!" = "No upcoming events for today!";
"Great going." = "Great going.";
"Happy Weekend." = "Happy Weekend.";
"Time Format" = "時間格式";
"Truncate menubar text longer than" = "選單列文字長度限制";
"Try again, maybe?" = "再試一次?";
"Unexpected" = "無法預期的";
/* Calendars View */
"Upcoming Event View Options" = "即將到來的行程顯示選項";
"Upcoming events from your personal and shared calendars can be shown in the menubar and the panel." = "即將到來的行程會在選單列和面板中顯示。";
"You have no events scheduled for tomorrow." = "您明天沒有排任何行程。";
"You'll see a clock icon in your Menu Bar when you launch the app. If you'd like to see a dock icon, go to Preferences." = "當應用程式啟動時,您將會在選單列看到 Clocker 圖像。如果您想在 Dock 上看到圖像,請前往偏好設定。";
/* Final Onboarding Screen */
"You're all set!" = "設定完成。";
/* Errors */
"You're offline, maybe?" = "You're offline, maybe?";
"app-name" = "Clocker";
"characters" = "字元";
"iRateAppMessage" = "如果您喜歡使用 %@ 的話,您是否願意花一點給予評價?不需要一分鐘就能完成。感謝您的支持!";
"iRateCancelButton" = "不用了,謝謝!";
"iRateGameMessage" = "如果您喜歡玩 %@ 的話,您是否願意花一點時間給予評價?不需一分鐘即可完成。感謝您的支持";
"iRateMessageTitle" = "評價 %@";
"iRateRateButton" = "現在評分吧!";
"iRateRemindButton" = "下次再提醒我";
"iRateUpdateMessage" = "立即更新";
"setup-steps" = "設定 Clocker 只需要 3 個步驟";
"start-at-login" = "在登入時啟動";

13
Clocker/CoreModelKit/Sources/CoreModelKit/SearchResults.swift

@ -2,9 +2,16 @@
import Cocoa
public struct ResultStatus {
public static let okay = "OK"
public static let zeroResults = "ZERO_RESULTS"
public static let requestDenied = "REQUEST_DENIED"
}
public struct SearchResult: Codable {
public let results: [Result]
public let status: String
public let errorMessage: String?
public struct Result: Codable {
public let addressComponents: [AddressComponent]
@ -48,6 +55,12 @@ public struct SearchResult: Codable {
case types
}
}
private enum CodingKeys: String, CodingKey {
case results = "results"
case status = "status"
case errorMessage = "error_message"
}
}
public struct Timezone: Codable {

4
Clocker/Onboarding/OnboardingSearchController.swift

@ -182,7 +182,7 @@ class OnboardingSearchController: NSViewController {
return true
}
if let status = unwrapped["status"] as? String, status == "ZERO_RESULTS" {
if let status = unwrapped["status"] as? String, status == ResultStatus.zeroResults {
setErrorPlaceholders()
return true
}
@ -365,7 +365,7 @@ class OnboardingSearchController: NSViewController {
let searchResults = data.decode()
if searchResults?.status == "ZERO_RESULTS" {
if searchResults?.status == ResultStatus.zeroResults {
self.setInfoLabel("No results! 😔 Try entering the exact name.")
setupForError()
return

6
Clocker/Overall App/Themer.swift

@ -191,7 +191,7 @@ extension Themer {
}
func preferenceImage() -> NSImage {
if let symbolImageForPreference = symbolImage(for: "gear") {
if let symbolImageForPreference = symbolImage(for: "plus") {
return symbolImageForPreference
}
@ -389,6 +389,10 @@ extension Themer {
}
func addImage() -> NSImage {
if let symbolImageForPreference = symbolImage(for: "plus") {
return symbolImageForPreference
}
if #available(macOS 10.14, *) {
switch themeIndex {
case .light, .solarizedLight:

5
Clocker/Panel/ParentPanelController.swift

@ -686,8 +686,7 @@ class ParentPanelController: NSWindowController {
}
@objc private func openPreferencesWindow() {
oneWindow?.showWindow(nil)
NSApp.activate(ignoringOtherApps: true)
oneWindow?.openGeneralPane()
}
@IBAction func dismissNextEventLabel(_: NSButton) {
@ -724,7 +723,7 @@ class ParentPanelController: NSWindowController {
}
private func showPermissionsWindow() {
oneWindow?.openPermissions()
oneWindow?.openPermissionsPane()
NSApp.activate(ignoringOtherApps: true)
}

9
Clocker/Panel/Rate Controller/ReviewController.swift

@ -50,7 +50,7 @@ final class ReviewController {
let lastVersion = storage.object(forKey: Keys.lastVersion) as? String
else { return true }
// Minimum interval between two versions should be 45
// Minimum interval between two versions should be 3 months
let minInterval: TimeInterval = day * 90
// never prompt w/in the same version
@ -60,13 +60,12 @@ final class ReviewController {
}
class func prompt() {
guard let ratingsURL = URL(string: AboutUsConstants.AppStoreLink) else {
return
}
if #available(OSX 10.14, *) {
SKStoreReviewController.requestReview()
} else {
guard let ratingsURL = URL(string: AboutUsConstants.AppStoreLink) else {
return
}
NSWorkspace.shared.open(ratingsURL)
}

11
Clocker/Preferences/App Feedback/AppFeedbackWindowController.swift

@ -309,8 +309,13 @@ extension AppFeedbackWindowController: NSWindowDelegate {
}
func bringPreferencesWindowToFront() {
let oneWindowController = OneWindowController.shared()
oneWindowController.window?.makeKeyAndOrderFront(self)
NSApp.activate(ignoringOtherApps: true)
let windows = NSApplication.shared.windows
let prefWindow = windows.first(where: { window in
return window.identifier == NSUserInterfaceItemIdentifier("Preferences")
})
if let prefW = prefWindow {
prefW.makeKeyAndOrderFront(self)
NSApp.activate(ignoringOtherApps: true)
}
}
}

22
Clocker/Preferences/General/PreferencesViewController.swift

@ -172,8 +172,8 @@ class PreferencesViewController: ParentViewController {
private func darkModeChanges() {
if #available(macOS 10.14, *) {
addTimezoneButton.image = NSImage(named: .addDynamicIcon)
deleteButton.image = NSImage(named: NSImage.Name("Remove Dynamic"))!
addTimezoneButton.image = Themer.shared().addImage()
deleteButton.image = Themer.shared().removeImage()
}
}
@ -481,22 +481,30 @@ extension PreferencesViewController {
return
}
guard let data = response else {
guard let data = response, let searchResults = data.decode() else {
assertionFailure("Data was unexpectedly nil")
return
}
let searchResults = data.decode()
// let searchResults = data.decode()
if searchResults?.status == "ZERO_RESULTS" {
if searchResults.status == ResultStatus.zeroResults {
Logger.info("Zero Results returned")
self.findLocalSearchResultsForTimezones()
self.placeholderLabel.placeholderString = self.searchResultsDataSource.timezoneFilteredArray.isEmpty ? "No results! 😔 Try entering the exact name." : CLEmptyString
self.reloadSearchResults()
self.isActivityInProgress = false
return
} else if searchResults.status == ResultStatus.requestDenied && searchResults.results.isEmpty {
Logger.info("Request denied!")
self.findLocalSearchResultsForTimezones()
self.placeholderLabel.placeholderString = self.searchResultsDataSource.timezoneFilteredArray.isEmpty ? "Update Clocker to get a faster experience 😃" : CLEmptyString
self.reloadSearchResults()
self.isActivityInProgress = false
return
}
self.appendResultsToFilteredArray(searchResults!.results)
self.appendResultsToFilteredArray(searchResults.results)
self.findLocalSearchResultsForTimezones()
self.prepareUIForPresentingResults()
}
@ -669,7 +677,7 @@ extension PreferencesViewController {
return false
}
if let status = unwrapped["status"] as? String, status == "ZERO_RESULTS" {
if let status = unwrapped["status"] as? String, status == ResultStatus.zeroResults {
setErrorPlaceholders()
return true
}

2
Clocker/Preferences/Menu Bar/StatusItemHandler.swift

@ -123,7 +123,7 @@ class StatusItemHandler: NSObject {
self.menubarTimer?.invalidate()
}
NSWorkspace.shared.notificationCenter.addObserver(forName: NSWorkspace.didWakeNotification, object: nil, queue: OperationQueue.main) { notification in
NSWorkspace.shared.notificationCenter.addObserver(forName: NSWorkspace.didWakeNotification, object: nil, queue: OperationQueue.main) { notification in
self.setupStatusItem()
}
}

55
Clocker/Preferences/OneWindowController.swift

@ -16,7 +16,6 @@ class CenteredTabViewController: NSTabViewController {
}
class OneWindowController: NSWindowController {
private static var sharedWindow: OneWindowController!
private var themeDidChangeNotification: NSObjectProtocol?
override func windowDidLoad() {
@ -49,30 +48,7 @@ class OneWindowController: NSWindowController {
private func setupWindow() {
window?.titlebarAppearsTransparent = true
window?.backgroundColor = Themer.shared().mainBackgroundColor()
}
class func shared() -> OneWindowController {
if sharedWindow == nil {
let prefStoryboard = NSStoryboard(name: "Preferences", bundle: nil)
sharedWindow = prefStoryboard.instantiateInitialController() as? OneWindowController
}
return sharedWindow
}
func openPermissions() {
guard let window = window else {
return
}
if !window.isMainWindow || !window.isVisible {
showWindow(nil)
}
guard let tabViewController = contentViewController as? CenteredTabViewController else {
return
}
tabViewController.selectedTabViewItemIndex = 3
window?.identifier = NSUserInterfaceItemIdentifier("Preferences")
}
private func setupToolbarImages() {
@ -100,4 +76,33 @@ class OneWindowController: NSWindowController {
}
}
}
// MARK: Public
func openPermissionsPane() {
openPreferenceTab(at: 3)
NSApp.activate(ignoringOtherApps: true)
}
// Action mapped to the + button in the PanelController. We should always open the General Pane when the + button is clicked.
func openGeneralPane() {
openPreferenceTab(at: 0)
NSApp.activate(ignoringOtherApps: true)
}
private func openPreferenceTab(at index: Int) {
guard let window = window else {
return
}
if !window.isMainWindow || !window.isVisible {
showWindow(nil)
}
guard let tabViewController = contentViewController as? CenteredTabViewController else {
return
}
tabViewController.selectedTabViewItemIndex = index
}
}

52
Clocker/Preferences/Preferences.storyboard

@ -801,7 +801,7 @@
<gridCells>
<gridCell row="3zv-Qe-ePN" column="ARE-A4-4k4" id="fRB-cT-Ydc">
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" preferredMaxLayoutWidth="100" translatesAutoresizingMaskIntoConstraints="NO" id="wtO-uL-QBf">
<rect key="frame" x="109" y="207" width="104" height="18"/>
<rect key="frame" x="98" y="207" width="104" height="18"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="100" id="WNN-Le-h1b"/>
</constraints>
@ -814,7 +814,7 @@
</gridCell>
<gridCell row="3zv-Qe-ePN" column="YBI-pK-gPQ" id="QZh-9h-ecx">
<popUpButton key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="iiG-Xu-4id">
<rect key="frame" x="228" y="202" width="78" height="25"/>
<rect key="frame" x="217" y="202" width="78" height="25"/>
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="5tQ-hE-OyI" id="rzx-jH-Vr6">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
@ -834,7 +834,7 @@
</gridCell>
<gridCell row="YtR-o1-nGp" column="ARE-A4-4k4" id="gzZ-cp-CkC">
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" preferredMaxLayoutWidth="60" translatesAutoresizingMaskIntoConstraints="NO" id="vrm-cg-RMn">
<rect key="frame" x="112" y="167" width="101" height="18"/>
<rect key="frame" x="101" y="167" width="101" height="18"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Panel Theme" id="ZKN-5V-B4D">
<font key="font" size="13" name="Avenir-Light"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -844,7 +844,7 @@
</gridCell>
<gridCell row="YtR-o1-nGp" column="YBI-pK-gPQ" id="kQ8-mu-Ax8">
<popUpButton key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="89w-KN-GJ6">
<rect key="frame" x="228" y="162" width="125" height="25"/>
<rect key="frame" x="217" y="162" width="125" height="25"/>
<popUpButtonCell key="cell" type="push" title="Light" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="xgz-r4-aaD" id="vql-m4-qSG">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" size="13" name="Avenir-Book"/>
@ -865,7 +865,7 @@
</gridCell>
<gridCell row="vjb-Ch-BZs" column="ARE-A4-4k4" id="Tkw-Kt-dMr">
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" preferredMaxLayoutWidth="150" translatesAutoresizingMaskIntoConstraints="NO" id="gFE-hZ-J92">
<rect key="frame" x="29" y="126" width="184" height="18"/>
<rect key="frame" x="18" y="126" width="184" height="18"/>
<constraints>
<constraint firstAttribute="width" constant="180" id="SCi-hT-hxG"/>
</constraints>
@ -878,7 +878,7 @@
</gridCell>
<gridCell row="vjb-Ch-BZs" column="YBI-pK-gPQ" xPlacement="leading" yPlacement="none" id="Fnt-fn-6Wr">
<segmentedControl key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="d4S-hM-MSP">
<rect key="frame" x="229" y="123" width="273" height="24"/>
<rect key="frame" x="218" y="123" width="273" height="24"/>
<segmentedCell key="cell" borderStyle="border" alignment="left" style="rounded" trackingMode="selectOne" id="564-Re-f1d">
<font key="font" size="12" name="Avenir-Light"/>
<segments>
@ -896,7 +896,7 @@
</gridCell>
<gridCell row="ad4-FM-AWq" column="ARE-A4-4k4" id="XeO-qn-EGI">
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" preferredMaxLayoutWidth="120" translatesAutoresizingMaskIntoConstraints="NO" id="4lt-X6-3uU">
<rect key="frame" x="9" y="84" width="204" height="18"/>
<rect key="frame" x="-2" y="84" width="204" height="18"/>
<constraints>
<constraint firstAttribute="width" constant="200" id="hAp-By-Lzj"/>
</constraints>
@ -909,7 +909,7 @@
</gridCell>
<gridCell row="ad4-FM-AWq" column="YBI-pK-gPQ" id="sA0-Dw-yO0">
<segmentedControl key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="9WW-jp-NeO">
<rect key="frame" x="229" y="81" width="81" height="24"/>
<rect key="frame" x="218" y="81" width="81" height="24"/>
<segmentedCell key="cell" borderStyle="border" alignment="left" style="rounded" trackingMode="selectOne" id="CcB-5w-IoG">
<font key="font" size="12" name="Avenir-Light"/>
<segments>
@ -925,7 +925,7 @@
</gridCell>
<gridCell row="yUG-1W-BQ2" column="ARE-A4-4k4" id="M8P-5s-oL4">
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" preferredMaxLayoutWidth="120" translatesAutoresizingMaskIntoConstraints="NO" id="ZWy-WW-6H9">
<rect key="frame" x="50" y="42" width="163" height="18"/>
<rect key="frame" x="39" y="42" width="163" height="18"/>
<constraints>
<constraint firstAttribute="width" constant="159" id="NX0-Bo-SU8"/>
</constraints>
@ -938,7 +938,7 @@
</gridCell>
<gridCell row="yUG-1W-BQ2" column="YBI-pK-gPQ" id="N12-lC-Pe1">
<segmentedControl key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="DCB-IB-UxK">
<rect key="frame" x="229" y="39" width="81" height="24"/>
<rect key="frame" x="218" y="39" width="81" height="24"/>
<segmentedCell key="cell" borderStyle="border" alignment="left" style="rounded" trackingMode="selectOne" id="PZZ-H7-LgV">
<font key="font" size="12" name="Avenir-Light"/>
<segments>
@ -954,7 +954,7 @@
</gridCell>
<gridCell row="fbk-ef-Req" column="ARE-A4-4k4" id="Vth-MP-nfS">
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" preferredMaxLayoutWidth="120" translatesAutoresizingMaskIntoConstraints="NO" id="xwt-pY-1w9">
<rect key="frame" x="9" y="1" width="204" height="18"/>
<rect key="frame" x="-2" y="1" width="204" height="18"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="200" id="7fj-Em-Lyh"/>
</constraints>
@ -967,7 +967,7 @@
</gridCell>
<gridCell row="fbk-ef-Req" column="YBI-pK-gPQ" id="dCk-cz-no0">
<slider key="contentView" verticalHuggingPriority="750" alphaValue="0.59999999999999998" translatesAutoresizingMaskIntoConstraints="NO" id="3cU-IS-3Qu">
<rect key="frame" x="229" y="-6" width="104" height="28"/>
<rect key="frame" x="218" y="-6" width="104" height="28"/>
<sliderCell key="cell" state="on" alignment="left" minValue="4" maxValue="7" doubleValue="4" tickMarkPosition="above" numberOfTickMarks="4" allowsTickMarkValuesOnly="YES" sliderType="linear" id="eAh-k3-cof"/>
<connections>
<action selector="fontSliderChanged:" target="1aL-zR-8L4" id="YAW-aA-5aR"/>
@ -979,11 +979,11 @@
</gridView>
<scrollView borderType="line" autohidesScrollers="YES" horizontalLineScroll="113" horizontalPageScroll="10" verticalLineScroll="113" verticalPageScroll="10" hasHorizontalScroller="NO" hasVerticalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ytg-0u-Mtu">
<rect key="frame" x="70" y="39" width="400" height="100"/>
<clipView key="contentView" ambiguous="YES" id="gnX-f5-31D">
<clipView key="contentView" id="gnX-f5-31D">
<rect key="frame" x="1" y="1" width="398" height="98"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" ambiguous="YES" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" typeSelect="NO" rowHeight="111" rowSizeStyle="automatic" viewBased="YES" id="KbJ-p4-i6E">
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" typeSelect="NO" rowHeight="111" rowSizeStyle="automatic" viewBased="YES" id="KbJ-p4-i6E">
<rect key="frame" x="0.0" y="0.0" width="412" height="113"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="3" height="2"/>
@ -1512,7 +1512,7 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<searchField toolTip="Search a timezone" wantsLayer="YES" focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Dha-h9-Nd0" customClass="ClockerSearchField" customModule="Clocker" customModuleProvider="target">
<rect key="frame" x="8" y="49" width="320" height="23"/>
<rect key="frame" x="8" y="265" width="320" height="23"/>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" focusRingType="none" placeholderString="Enter a city, state, country name" usesSingleLineMode="YES" maximumRecents="5" id="ikU-Tm-0WZ">
<font key="font" size="13" name="Avenir-Light"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@ -1569,13 +1569,13 @@ DQ
</connections>
</button>
<scrollView focusRingType="none" borderType="none" autohidesScrollers="YES" horizontalLineScroll="32" horizontalPageScroll="10" verticalLineScroll="32" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="0wY-ff-FLW">
<rect key="frame" x="8" y="30" width="320" height="9"/>
<rect key="frame" x="8" y="30" width="320" height="225"/>
<clipView key="contentView" drawsBackground="NO" id="rGc-3M-cCq">
<rect key="frame" x="0.0" y="0.0" width="320" height="9"/>
<rect key="frame" x="0.0" y="0.0" width="320" height="225"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" rowHeight="30" rowSizeStyle="automatic" viewBased="YES" id="xkl-2X-ZCb">
<rect key="frame" x="0.0" y="0.0" width="320" height="64"/>
<rect key="frame" x="0.0" y="0.0" width="320" height="225"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
@ -1665,14 +1665,14 @@ DQ
</scroller>
</scrollView>
<progressIndicator wantsLayer="YES" focusRingType="none" horizontalHuggingPriority="750" verticalHuggingPriority="750" maxValue="100" displayedWhenStopped="NO" bezeled="NO" indeterminate="YES" controlSize="small" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="0A5-gp-lay">
<rect key="frame" x="160" y="54" width="16" height="16"/>
<rect key="frame" x="160" y="162" width="16" height="16"/>
<constraints>
<constraint firstAttribute="height" constant="16" id="fgE-77-Vda"/>
<constraint firstAttribute="width" constant="16" id="pwe-em-e0a"/>
</constraints>
</progressIndicator>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="xgb-wU-8RU">
<rect key="frame" x="18" y="24" width="300" height="22"/>
<rect key="frame" x="18" y="132" width="300" height="22"/>
<constraints>
<constraint firstAttribute="height" constant="22" id="zqt-d8-yas"/>
</constraints>
@ -1860,14 +1860,14 @@ DQ
<rect key="frame" x="0.0" y="0.0" width="618" height="52"/>
<subviews>
<button toolTip="Add a timezone" focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="1FY-Nb-ZXb">
<rect key="frame" x="1" y="8" width="40" height="40"/>
<rect key="frame" x="1" y="6" width="40" height="40"/>
<constraints>
<constraint firstAttribute="width" constant="40" id="TJZ-Zv-ft0"/>
<constraint firstAttribute="height" constant="40" id="sK8-9i-bBo"/>
</constraints>
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" image="Add Icon" imagePosition="only" alignment="center" focusRingType="none" imageScaling="proportionallyDown" inset="2" id="AiB-Ig-MFT">
<behavior key="behavior" pushIn="YES" changeContents="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
<font key="font" metaFont="system" size="22"/>
</buttonCell>
<accessibility identifier="AddTimezone"/>
<connections>
@ -1875,10 +1875,10 @@ DQ
</connections>
</button>
<button toolTip="Remove a timezone" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="48a-Zz-oQg">
<rect key="frame" x="41" y="5" width="40" height="40"/>
<rect key="frame" x="41" y="6" width="40" height="40"/>
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" image="Remove" imagePosition="overlaps" alignment="center" state="on" imageScaling="proportionallyDown" inset="2" id="tPs-EW-qXq">
<behavior key="behavior" pushIn="YES" changeContents="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
<font key="font" metaFont="system" size="22"/>
<string key="keyEquivalent" base64-UTF8="YES">
CA
</string>
@ -1933,9 +1933,9 @@ CA
<constraint firstItem="aGE-ap-6NE" firstAttribute="centerY" secondItem="348-wa-XEI" secondAttribute="centerY" id="4Zi-tv-iUg"/>
<constraint firstItem="48a-Zz-oQg" firstAttribute="leading" secondItem="1FY-Nb-ZXb" secondAttribute="trailing" id="AUY-7G-gep"/>
<constraint firstItem="aCf-xC-UkE" firstAttribute="leading" secondItem="aGE-ap-6NE" secondAttribute="trailing" constant="8" id="Axm-NL-Rlj"/>
<constraint firstItem="1FY-Nb-ZXb" firstAttribute="centerY" secondItem="348-wa-XEI" secondAttribute="centerY" constant="-2" id="Iua-hE-fSo"/>
<constraint firstItem="1FY-Nb-ZXb" firstAttribute="centerY" secondItem="348-wa-XEI" secondAttribute="centerY" id="Iua-hE-fSo"/>
<constraint firstAttribute="trailing" secondItem="PbD-dt-goz" secondAttribute="trailing" constant="12" id="K40-ee-cJc"/>
<constraint firstItem="48a-Zz-oQg" firstAttribute="centerY" secondItem="348-wa-XEI" secondAttribute="centerY" constant="1" id="PDX-dP-7OB"/>
<constraint firstItem="48a-Zz-oQg" firstAttribute="centerY" secondItem="348-wa-XEI" secondAttribute="centerY" id="PDX-dP-7OB"/>
<constraint firstItem="aGE-ap-6NE" firstAttribute="leading" secondItem="48a-Zz-oQg" secondAttribute="trailing" constant="40" id="Qy7-CH-mDD"/>
<constraint firstItem="PbD-dt-goz" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="aCf-xC-UkE" secondAttribute="trailing" constant="20" id="S7R-11-bgf"/>
<constraint firstItem="aCf-xC-UkE" firstAttribute="centerY" secondItem="aGE-ap-6NE" secondAttribute="centerY" constant="-1.5" id="d8V-v9-JrU"/>

17
Readme.md

@ -1,6 +1,17 @@
# Clocker
[![Twitter: @clocker_support](https://img.shields.io/badge/contact-@clocker_support-blue.svg?style=flat)](https://twitter.com/clocker_support) [![Build Status](https://travis-ci.org/n0shake/Clocker.svg?branch=master)](https://travis-ci.org/n0shake/Clocker) [![Crowdin](https://badges.crowdin.net/clocker/localized.svg)](https://crowdin.com/project/clocker)
<p align="center">
<a href="https://github.com/n0shake/Clocker/releases/latest">
<img src="https://img.shields.io/badge/download-latest-brightgreen.svg" alt="download">
</a>
<a href="https://crowdin.com/project/clocker">
<img src="https://badges.crowdin.net/clocker/localized.svg" alt="localization">
</a>
<a href="https://twitter.com/clocker_support">
<img src="https://img.shields.io/badge/contact-@clocker_support-blue.svg?style=flat" alt="app support">
</a>
</p>
**Clocker** is an macOS menubar utility designed to help you keep track of your friends in different time zones. It's written using ~~Objective-C~~ Swift 5 and is completely ad-free. If you'd like to help translate Clocker in your language, [here's the invite link](https://crwd.in/clocker).
@ -11,10 +22,6 @@ If you'd like to donate, you can do so [here](https://www.paypal.me/AbhishekBant
brew install --cask clocker
```
or
[![Download on the App Store](https://github.com/n0shake/Clocker/blob/v1.2.1/Clocker/Images/MacAppStore.png)](https://itunes.apple.com/us/app/clocker-menubar-world-clock/id1056643111?mt=12)
# Contributing
**Clocker** is open for pull requests.

Loading…
Cancel
Save