├── add.sh ├── pull.sh ├── init.sh ├── status.sh ├── Bitmessage ├── en.lproj │ ├── InfoPlist.strings │ └── Credits.rtf ├── resources │ ├── icons │ │ ├── Left │ │ │ ├── Left.psd │ │ │ ├── search_active.png │ │ │ ├── BMContacts_active.png │ │ │ ├── search_inactive.png │ │ │ ├── BMContacts_inactive.png │ │ │ ├── BMIdentities_active.png │ │ │ ├── BMIdentities_inactive.png │ │ │ ├── BMSentMessages_active.png │ │ │ ├── BMSentMessages_inactive.png │ │ │ ├── BMReceivedMessages_active.png │ │ │ └── BMReceivedMessages_inactive.png │ │ ├── Misc │ │ │ └── icon_tick.png │ │ ├── Top │ │ │ ├── add_active.png │ │ │ ├── Reply_active.png │ │ │ ├── add_inactive.png │ │ │ ├── delete_active.png │ │ │ ├── send_active.png │ │ │ ├── send_inactive.png │ │ │ ├── Reply_inactive.png │ │ │ ├── compose_active.png │ │ │ ├── delete_inactive.png │ │ │ ├── forward_active.png │ │ │ ├── message_active.png │ │ │ ├── refresh_active.png │ │ │ ├── message_inactive.png │ │ │ ├── refresh_inactive.png │ │ │ └── composeicon_inactive.png │ │ ├── AppIcon │ │ │ ├── icon_16x16.png │ │ │ ├── icon_32x32.png │ │ │ ├── icon_128x128.png │ │ │ ├── icon_16x16@2x.png │ │ │ ├── icon_256x256.png │ │ │ ├── icon_32x32@2x.png │ │ │ ├── icon_512x512.png │ │ │ ├── icon_128x128@2x.png │ │ │ ├── icon_256x256@2x.png │ │ │ └── icon_512x512@2x.png │ │ └── unused_svg_icons │ │ │ ├── icon_add.svg │ │ │ ├── icon_right.svg │ │ │ ├── icon_left.svg │ │ │ ├── litecoin.svg │ │ │ ├── tv.svg │ │ │ ├── mobile.svg │ │ │ ├── computing.svg │ │ │ ├── clothing.svg │ │ │ ├── bitcoin.svg │ │ │ ├── music.svg │ │ │ ├── photography.svg │ │ │ ├── icon_profile.svg │ │ │ └── sports.svg │ ├── fonts │ │ └── Open_Sans │ │ │ ├── OpenSans-Bold.ttf │ │ │ ├── OpenSans-Light.ttf │ │ │ ├── OpenSans-Italic.ttf │ │ │ ├── OpenSans-Regular.ttf │ │ │ ├── OpenSans-Semibold.ttf │ │ │ ├── OpenSans-BoldItalic.ttf │ │ │ ├── OpenSans-ExtraBold.ttf │ │ │ ├── OpenSans-LightItalic.ttf │ │ │ ├── OpenSans-ExtraBoldItalic.ttf │ │ │ ├── OpenSans-SemiboldItalic.ttf │ │ │ └── LICENSE.txt │ ├── themes │ │ └── themes.json │ └── xibs │ │ └── Compose.xib ├── Images.xcassets │ └── AppIcon.appiconset │ │ ├── icon_16x16.png │ │ ├── icon_32x32.png │ │ ├── icon_16x16@2x.png │ │ ├── icon_256x256.png │ │ ├── icon_32x32@2x.png │ │ ├── icon_512x512.png │ │ ├── icon_128x128@2x.png │ │ ├── icon_256x256@2x.png │ │ ├── icon_512x512@2x.png │ │ ├── icon_128x128@2x-1.png │ │ └── Contents.json ├── Bitpost-Prefix.pch ├── main.m ├── Classes │ └── Browser │ │ ├── Controllers │ │ ├── BMAppController.h │ │ ├── Draft │ │ │ ├── BMAddressTextField.h │ │ │ ├── BMAddressCompletor.h │ │ │ ├── BMAddressTextField.m │ │ │ ├── BMDraftController.h │ │ │ ├── BMAddressCompletor.m │ │ │ └── BMDraftController.m │ │ └── BMAppController.m │ │ └── Inspectors │ │ ├── Addressed │ │ ├── BMChannelView.h │ │ ├── BMIdentityView.h │ │ ├── BMContactView.h │ │ ├── BMContactView.m │ │ ├── BMSubscriptionView.m │ │ ├── BMSubscriptionView.h │ │ ├── BMAddressed+NodeView.h │ │ ├── BMIdentityView.m │ │ ├── BMChannelView.m │ │ ├── BMAddressed+NodeView.m │ │ ├── BMAddressedView.h │ │ └── BMAddressedView.m │ │ ├── Message │ │ ├── BMMessage+NodeView.h │ │ ├── BMMessageView.h │ │ ├── BMMessage+NodeView.m │ │ └── BMMessageView.m │ │ ├── BMClient+NodeView.h │ │ ├── NewUser │ │ ├── BMNewUserView.h │ │ └── BMNewUserView.m │ │ └── BMClient+NodeView.m └── Bitpost-Info.plist ├── push.sh ├── BitmessageTests ├── en.lproj │ └── InfoPlist.strings ├── BitpostTests-Info.plist └── BitmessageTests.m ├── DesignNotes ├── inbox │ ├── new.png │ ├── inbox.png │ ├── BM_Inbox.png │ ├── inbox_notes.png │ └── new_notes.png ├── logo │ └── BM_Logo.png ├── search │ ├── search.png │ ├── nomessages.png │ ├── search_notes.png │ └── nomessages_notes.png ├── white │ ├── 6_app_1.jpg │ ├── 1_macbook.jpg │ ├── 5_setup_3.jpg │ └── 8_app_3_0.jpg ├── compose │ ├── compose.png │ ├── composeicon.png │ └── compose_notes.png └── contacts │ ├── contacts.png │ ├── newcontact.png │ ├── editcontacts.png │ ├── BM_AddressBook.png │ ├── contacts_notes.png │ ├── editcontacts_notes.png │ └── newcontact_notes.png ├── Vendor └── fonts │ └── Open_Sans │ ├── OpenSans-Bold.ttf │ ├── OpenSans-Italic.ttf │ ├── OpenSans-Light.ttf │ ├── OpenSans-Regular.ttf │ ├── OpenSans-ExtraBold.ttf │ ├── OpenSans-Semibold.ttf │ ├── OpenSans-BoldItalic.ttf │ ├── OpenSans-LightItalic.ttf │ ├── OpenSans-SemiboldItalic.ttf │ ├── OpenSans-ExtraBoldItalic.ttf │ └── LICENSE.txt ├── CHANGELOG.txt ├── commit.sh ├── .gitignore ├── .gitmodules ├── LICENSE ├── Todo.txt └── README.md /add.sh: -------------------------------------------------------------------------------- 1 | git submodule foreach --recursive git add . 2 | git add . -------------------------------------------------------------------------------- /pull.sh: -------------------------------------------------------------------------------- 1 | git submodule foreach --recursive git pull origin master 2 | -------------------------------------------------------------------------------- /init.sh: -------------------------------------------------------------------------------- 1 | git submodule update --init --recursive 2 | git pull 3 | 4 | -------------------------------------------------------------------------------- /status.sh: -------------------------------------------------------------------------------- 1 | git status 2 | git submodule foreach --recursive git status 3 | -------------------------------------------------------------------------------- /Bitmessage/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /push.sh: -------------------------------------------------------------------------------- 1 | git submodule foreach --recursive git push origin master 2 | git push origin master -------------------------------------------------------------------------------- /BitmessageTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /DesignNotes/inbox/new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/DesignNotes/inbox/new.png -------------------------------------------------------------------------------- /DesignNotes/inbox/inbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/DesignNotes/inbox/inbox.png -------------------------------------------------------------------------------- /DesignNotes/logo/BM_Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/DesignNotes/logo/BM_Logo.png -------------------------------------------------------------------------------- /DesignNotes/inbox/BM_Inbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/DesignNotes/inbox/BM_Inbox.png -------------------------------------------------------------------------------- /DesignNotes/search/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/DesignNotes/search/search.png -------------------------------------------------------------------------------- /DesignNotes/white/6_app_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/DesignNotes/white/6_app_1.jpg -------------------------------------------------------------------------------- /DesignNotes/compose/compose.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/DesignNotes/compose/compose.png -------------------------------------------------------------------------------- /DesignNotes/contacts/contacts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/DesignNotes/contacts/contacts.png -------------------------------------------------------------------------------- /DesignNotes/inbox/inbox_notes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/DesignNotes/inbox/inbox_notes.png -------------------------------------------------------------------------------- /DesignNotes/inbox/new_notes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/DesignNotes/inbox/new_notes.png -------------------------------------------------------------------------------- /DesignNotes/search/nomessages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/DesignNotes/search/nomessages.png -------------------------------------------------------------------------------- /DesignNotes/white/1_macbook.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/DesignNotes/white/1_macbook.jpg -------------------------------------------------------------------------------- /DesignNotes/white/5_setup_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/DesignNotes/white/5_setup_3.jpg -------------------------------------------------------------------------------- /DesignNotes/white/8_app_3_0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/DesignNotes/white/8_app_3_0.jpg -------------------------------------------------------------------------------- /DesignNotes/compose/composeicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/DesignNotes/compose/composeicon.png -------------------------------------------------------------------------------- /DesignNotes/contacts/newcontact.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/DesignNotes/contacts/newcontact.png -------------------------------------------------------------------------------- /DesignNotes/search/search_notes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/DesignNotes/search/search_notes.png -------------------------------------------------------------------------------- /DesignNotes/compose/compose_notes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/DesignNotes/compose/compose_notes.png -------------------------------------------------------------------------------- /DesignNotes/contacts/editcontacts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/DesignNotes/contacts/editcontacts.png -------------------------------------------------------------------------------- /Bitmessage/resources/icons/Left/Left.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/Left/Left.psd -------------------------------------------------------------------------------- /DesignNotes/contacts/BM_AddressBook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/DesignNotes/contacts/BM_AddressBook.png -------------------------------------------------------------------------------- /DesignNotes/contacts/contacts_notes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/DesignNotes/contacts/contacts_notes.png -------------------------------------------------------------------------------- /DesignNotes/search/nomessages_notes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/DesignNotes/search/nomessages_notes.png -------------------------------------------------------------------------------- /Vendor/fonts/Open_Sans/OpenSans-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Vendor/fonts/Open_Sans/OpenSans-Bold.ttf -------------------------------------------------------------------------------- /DesignNotes/contacts/editcontacts_notes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/DesignNotes/contacts/editcontacts_notes.png -------------------------------------------------------------------------------- /DesignNotes/contacts/newcontact_notes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/DesignNotes/contacts/newcontact_notes.png -------------------------------------------------------------------------------- /Vendor/fonts/Open_Sans/OpenSans-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Vendor/fonts/Open_Sans/OpenSans-Italic.ttf -------------------------------------------------------------------------------- /Vendor/fonts/Open_Sans/OpenSans-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Vendor/fonts/Open_Sans/OpenSans-Light.ttf -------------------------------------------------------------------------------- /Vendor/fonts/Open_Sans/OpenSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Vendor/fonts/Open_Sans/OpenSans-Regular.ttf -------------------------------------------------------------------------------- /Bitmessage/resources/icons/Misc/icon_tick.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/Misc/icon_tick.png -------------------------------------------------------------------------------- /Bitmessage/resources/icons/Top/add_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/Top/add_active.png -------------------------------------------------------------------------------- /Vendor/fonts/Open_Sans/OpenSans-ExtraBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Vendor/fonts/Open_Sans/OpenSans-ExtraBold.ttf -------------------------------------------------------------------------------- /Vendor/fonts/Open_Sans/OpenSans-Semibold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Vendor/fonts/Open_Sans/OpenSans-Semibold.ttf -------------------------------------------------------------------------------- /Bitmessage/resources/icons/Top/Reply_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/Top/Reply_active.png -------------------------------------------------------------------------------- /Bitmessage/resources/icons/Top/add_inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/Top/add_inactive.png -------------------------------------------------------------------------------- /Bitmessage/resources/icons/Top/delete_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/Top/delete_active.png -------------------------------------------------------------------------------- /Bitmessage/resources/icons/Top/send_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/Top/send_active.png -------------------------------------------------------------------------------- /Bitmessage/resources/icons/Top/send_inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/Top/send_inactive.png -------------------------------------------------------------------------------- /Vendor/fonts/Open_Sans/OpenSans-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Vendor/fonts/Open_Sans/OpenSans-BoldItalic.ttf -------------------------------------------------------------------------------- /Vendor/fonts/Open_Sans/OpenSans-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Vendor/fonts/Open_Sans/OpenSans-LightItalic.ttf -------------------------------------------------------------------------------- /Bitmessage/resources/icons/AppIcon/icon_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/AppIcon/icon_16x16.png -------------------------------------------------------------------------------- /Bitmessage/resources/icons/AppIcon/icon_32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/AppIcon/icon_32x32.png -------------------------------------------------------------------------------- /Bitmessage/resources/icons/Left/search_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/Left/search_active.png -------------------------------------------------------------------------------- /Bitmessage/resources/icons/Top/Reply_inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/Top/Reply_inactive.png -------------------------------------------------------------------------------- /Bitmessage/resources/icons/Top/compose_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/Top/compose_active.png -------------------------------------------------------------------------------- /Bitmessage/resources/icons/Top/delete_inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/Top/delete_inactive.png -------------------------------------------------------------------------------- /Bitmessage/resources/icons/Top/forward_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/Top/forward_active.png -------------------------------------------------------------------------------- /Bitmessage/resources/icons/Top/message_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/Top/message_active.png -------------------------------------------------------------------------------- /Bitmessage/resources/icons/Top/refresh_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/Top/refresh_active.png -------------------------------------------------------------------------------- /Vendor/fonts/Open_Sans/OpenSans-SemiboldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Vendor/fonts/Open_Sans/OpenSans-SemiboldItalic.ttf -------------------------------------------------------------------------------- /Bitmessage/resources/icons/AppIcon/icon_128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/AppIcon/icon_128x128.png -------------------------------------------------------------------------------- /Bitmessage/resources/icons/AppIcon/icon_16x16@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/AppIcon/icon_16x16@2x.png -------------------------------------------------------------------------------- /Bitmessage/resources/icons/AppIcon/icon_256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/AppIcon/icon_256x256.png -------------------------------------------------------------------------------- /Bitmessage/resources/icons/AppIcon/icon_32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/AppIcon/icon_32x32@2x.png -------------------------------------------------------------------------------- /Bitmessage/resources/icons/AppIcon/icon_512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/AppIcon/icon_512x512.png -------------------------------------------------------------------------------- /Bitmessage/resources/icons/Left/BMContacts_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/Left/BMContacts_active.png -------------------------------------------------------------------------------- /Bitmessage/resources/icons/Left/search_inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/Left/search_inactive.png -------------------------------------------------------------------------------- /Bitmessage/resources/icons/Top/message_inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/Top/message_inactive.png -------------------------------------------------------------------------------- /Bitmessage/resources/icons/Top/refresh_inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/Top/refresh_inactive.png -------------------------------------------------------------------------------- /CHANGELOG.txt: -------------------------------------------------------------------------------- 1 | 2 | version 0.9.8.2 3 | 4 | - fix for highlighting unsent (still doing pow, etc) messages 5 | - added 3rd party license info to UI 6 | - signed tag -------------------------------------------------------------------------------- /Vendor/fonts/Open_Sans/OpenSans-ExtraBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Vendor/fonts/Open_Sans/OpenSans-ExtraBoldItalic.ttf -------------------------------------------------------------------------------- /Bitmessage/resources/fonts/Open_Sans/OpenSans-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/fonts/Open_Sans/OpenSans-Bold.ttf -------------------------------------------------------------------------------- /Bitmessage/resources/fonts/Open_Sans/OpenSans-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/fonts/Open_Sans/OpenSans-Light.ttf -------------------------------------------------------------------------------- /Bitmessage/resources/icons/AppIcon/icon_128x128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/AppIcon/icon_128x128@2x.png -------------------------------------------------------------------------------- /Bitmessage/resources/icons/AppIcon/icon_256x256@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/AppIcon/icon_256x256@2x.png -------------------------------------------------------------------------------- /Bitmessage/resources/icons/AppIcon/icon_512x512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/AppIcon/icon_512x512@2x.png -------------------------------------------------------------------------------- /Bitmessage/resources/icons/Left/BMContacts_inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/Left/BMContacts_inactive.png -------------------------------------------------------------------------------- /Bitmessage/resources/icons/Left/BMIdentities_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/Left/BMIdentities_active.png -------------------------------------------------------------------------------- /Bitmessage/resources/icons/Top/composeicon_inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/Top/composeicon_inactive.png -------------------------------------------------------------------------------- /Bitmessage/resources/fonts/Open_Sans/OpenSans-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/fonts/Open_Sans/OpenSans-Italic.ttf -------------------------------------------------------------------------------- /Bitmessage/resources/fonts/Open_Sans/OpenSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/fonts/Open_Sans/OpenSans-Regular.ttf -------------------------------------------------------------------------------- /Bitmessage/resources/fonts/Open_Sans/OpenSans-Semibold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/fonts/Open_Sans/OpenSans-Semibold.ttf -------------------------------------------------------------------------------- /Bitmessage/resources/icons/Left/BMIdentities_inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/Left/BMIdentities_inactive.png -------------------------------------------------------------------------------- /Bitmessage/resources/icons/Left/BMSentMessages_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/Left/BMSentMessages_active.png -------------------------------------------------------------------------------- /Bitmessage/Images.xcassets/AppIcon.appiconset/icon_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/Images.xcassets/AppIcon.appiconset/icon_16x16.png -------------------------------------------------------------------------------- /Bitmessage/Images.xcassets/AppIcon.appiconset/icon_32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/Images.xcassets/AppIcon.appiconset/icon_32x32.png -------------------------------------------------------------------------------- /Bitmessage/resources/fonts/Open_Sans/OpenSans-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/fonts/Open_Sans/OpenSans-BoldItalic.ttf -------------------------------------------------------------------------------- /Bitmessage/resources/fonts/Open_Sans/OpenSans-ExtraBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/fonts/Open_Sans/OpenSans-ExtraBold.ttf -------------------------------------------------------------------------------- /Bitmessage/resources/icons/Left/BMSentMessages_inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/Left/BMSentMessages_inactive.png -------------------------------------------------------------------------------- /Bitmessage/Images.xcassets/AppIcon.appiconset/icon_16x16@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/Images.xcassets/AppIcon.appiconset/icon_16x16@2x.png -------------------------------------------------------------------------------- /Bitmessage/Images.xcassets/AppIcon.appiconset/icon_256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/Images.xcassets/AppIcon.appiconset/icon_256x256.png -------------------------------------------------------------------------------- /Bitmessage/Images.xcassets/AppIcon.appiconset/icon_32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/Images.xcassets/AppIcon.appiconset/icon_32x32@2x.png -------------------------------------------------------------------------------- /Bitmessage/Images.xcassets/AppIcon.appiconset/icon_512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/Images.xcassets/AppIcon.appiconset/icon_512x512.png -------------------------------------------------------------------------------- /Bitmessage/resources/fonts/Open_Sans/OpenSans-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/fonts/Open_Sans/OpenSans-LightItalic.ttf -------------------------------------------------------------------------------- /Bitmessage/resources/icons/Left/BMReceivedMessages_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/Left/BMReceivedMessages_active.png -------------------------------------------------------------------------------- /Bitmessage/resources/icons/Left/BMReceivedMessages_inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/icons/Left/BMReceivedMessages_inactive.png -------------------------------------------------------------------------------- /Bitmessage/Images.xcassets/AppIcon.appiconset/icon_128x128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/Images.xcassets/AppIcon.appiconset/icon_128x128@2x.png -------------------------------------------------------------------------------- /Bitmessage/Images.xcassets/AppIcon.appiconset/icon_256x256@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/Images.xcassets/AppIcon.appiconset/icon_256x256@2x.png -------------------------------------------------------------------------------- /Bitmessage/Images.xcassets/AppIcon.appiconset/icon_512x512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/Images.xcassets/AppIcon.appiconset/icon_512x512@2x.png -------------------------------------------------------------------------------- /Bitmessage/resources/fonts/Open_Sans/OpenSans-ExtraBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/fonts/Open_Sans/OpenSans-ExtraBoldItalic.ttf -------------------------------------------------------------------------------- /Bitmessage/resources/fonts/Open_Sans/OpenSans-SemiboldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/resources/fonts/Open_Sans/OpenSans-SemiboldItalic.ttf -------------------------------------------------------------------------------- /Bitmessage/Images.xcassets/AppIcon.appiconset/icon_128x128@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoluntaryLabs/Bitpost/HEAD/Bitmessage/Images.xcassets/AppIcon.appiconset/icon_128x128@2x-1.png -------------------------------------------------------------------------------- /Bitmessage/Bitpost-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #ifdef __OBJC__ 8 | #import 9 | #endif 10 | -------------------------------------------------------------------------------- /Bitmessage/en.lproj/Credits.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf190 2 | {\fonttbl\f0\fswiss\fcharset0 Helvetica;} 3 | {\colortbl;\red255\green255\blue255;} 4 | \vieww9600\viewh8400\viewkind0 5 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720 6 | 7 | \f0\fs24 \cf0 \ 8 | } -------------------------------------------------------------------------------- /Bitmessage/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Bitmessage 4 | // 5 | // Created by Steve Dekorte on 2/11/14. 6 | // Copyright (c) 2014 voluntary.net. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, const char * argv[]) 12 | { 13 | return NSApplicationMain(argc, argv); 14 | } 15 | -------------------------------------------------------------------------------- /Bitmessage/Classes/Browser/Controllers/BMAppController.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface BMAppController : NavAppController 5 | 6 | - (IBAction)compose:(id)sender; // just for menu shortcut action 7 | - (IBAction)composeBroadcast:(id)sender; // just for menu shortcut action 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /Bitmessage/Classes/Browser/Inspectors/Addressed/BMChannelView.h: -------------------------------------------------------------------------------- 1 | // 2 | // BMChannelView.h 3 | // Bitmessage 4 | // 5 | // Created by Steve Dekorte on 2/20/14. 6 | // Copyright (c) 2014 voluntary.net. All rights reserved. 7 | // 8 | 9 | #import "BMAddressedView.h" 10 | 11 | @interface BMChannelView : BMAddressedView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Bitmessage/Classes/Browser/Inspectors/Addressed/BMIdentityView.h: -------------------------------------------------------------------------------- 1 | // 2 | // BMIdentityView.h 3 | // Bitmessage 4 | // 5 | // Created by Steve Dekorte on 2/13/14. 6 | // Copyright (c) 2014 voluntary.net. All rights reserved. 7 | // 8 | 9 | #import "BMContactView.h" 10 | 11 | @interface BMIdentityView : BMContactView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Bitmessage/Classes/Browser/Inspectors/Addressed/BMContactView.h: -------------------------------------------------------------------------------- 1 | // 2 | // BMContactView.h 3 | // Bitmessage 4 | // 5 | // Created by Steve Dekorte on 2/13/14. 6 | // Copyright (c) 2014 voluntary.net. All rights reserved. 7 | // 8 | 9 | #import "BMAddressedView.h" 10 | 11 | @interface BMContactView : BMAddressedView 12 | 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Bitmessage/Classes/Browser/Inspectors/Addressed/BMContactView.m: -------------------------------------------------------------------------------- 1 | // 2 | // BMContactView.m 3 | // Bitmessage 4 | // 5 | // Created by Steve Dekorte on 2/13/14. 6 | // Copyright (c) 2014 voluntary.net. All rights reserved. 7 | // 8 | 9 | #import "BMContactView.h" 10 | 11 | @implementation BMContactView 12 | 13 | @end 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Bitmessage/Classes/Browser/Inspectors/Addressed/BMSubscriptionView.m: -------------------------------------------------------------------------------- 1 | // 2 | // BMSubscriptionView.m 3 | // Bitmessage 4 | // 5 | // Created by Steve Dekorte on 2/21/14. 6 | // Copyright (c) 2014 Bitmarkets.org. All rights reserved. 7 | // 8 | 9 | #import "BMSubscriptionView.h" 10 | 11 | @implementation BMSubscriptionView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Bitmessage/Classes/Browser/Inspectors/Addressed/BMSubscriptionView.h: -------------------------------------------------------------------------------- 1 | // 2 | // BMSubscriptionView.h 3 | // Bitmessage 4 | // 5 | // Created by Steve Dekorte on 2/21/14. 6 | // Copyright (c) 2014 Bitmarkets.org. All rights reserved. 7 | // 8 | 9 | #import "BMContactView.h" 10 | 11 | @interface BMSubscriptionView : BMContactView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Bitmessage/Classes/Browser/Inspectors/Addressed/BMAddressed+NodeView.h: -------------------------------------------------------------------------------- 1 | // 2 | // BMAddressed+NodeView.h 3 | // Bitmessage 4 | // 5 | // Created by Steve Dekorte on 4/8/14. 6 | // Copyright (c) 2014 voluntary.net. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BMAddressed (NodeView) 12 | 13 | - (void)message; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Bitmessage/Classes/Browser/Inspectors/Message/BMMessage+NodeView.h: -------------------------------------------------------------------------------- 1 | // 2 | // BMMessage+NodeView.h 3 | // Bitmessage 4 | // 5 | // Created by Steve Dekorte on 2/27/14. 6 | // Copyright (c) 2014 voluntary.net. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BMMessage (NodeView) 12 | 13 | - (NSString *)nodeNote; 14 | 15 | - (void)reply; 16 | - (void)forward; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Bitmessage/Classes/Browser/Inspectors/Addressed/BMIdentityView.m: -------------------------------------------------------------------------------- 1 | // 2 | // BMIdentityView.m 3 | // Bitmessage 4 | // 5 | // Created by Steve Dekorte on 2/13/14. 6 | // Copyright (c) 2014 voluntary.net. All rights reserved. 7 | // 8 | 9 | #import "BMIdentityView.h" 10 | 11 | @implementation BMIdentityView 12 | 13 | - (void)setup 14 | { 15 | [super setup]; 16 | [self.addressField setEditable:NO]; 17 | } 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /commit.sh: -------------------------------------------------------------------------------- 1 | cd submodules 2 | cd BitmessageKit; 3 | cd submodules 4 | cd FoundationCategoriesKit; pwd; git commit . -s; cd .. 5 | cd NavNodeKit; pwd; git commit . -s; cd .. 6 | cd NavKit; pwd; git commit . -s; cd .. 7 | cd SystemInfoKit; pwd; git commit . -s; cd .. 8 | cd TorServerKit; 9 | cd submodules/SystemInfoKit; pwd; git commit . -s; cd ../.. 10 | pwd; git commit . -s; cd .. 11 | 12 | cd .. 13 | pwd; 14 | git commit . -s; 15 | 16 | cd ../.. 17 | pwd; 18 | git commit . -s; 19 | -------------------------------------------------------------------------------- /Bitmessage/Classes/Browser/Inspectors/BMClient+NodeView.h: -------------------------------------------------------------------------------- 1 | // 2 | // BMClient+UI.h 3 | // Bitmessage 4 | // 5 | // Created by Steve Dekorte on 4/17/14. 6 | // Copyright (c) 2014 voluntary.net. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BMClient (NodeView) 12 | 13 | - (void)compose; 14 | - (void)composeBroadcast; 15 | 16 | - (void)composeWithAddress:(NSString *)address; 17 | 18 | /* 19 | - (void)export; 20 | - (void)import; 21 | */ 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Bitmessage/Classes/Browser/Controllers/Draft/BMAddressTextField.h: -------------------------------------------------------------------------------- 1 | // 2 | // BMAddressTextField.h 3 | // Bitmessage 4 | // 5 | // Created by Steve Dekorte on 2/26/14. 6 | // Copyright (c) 2014 voluntary.net. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BMAddressTextField : NSTextField 12 | 13 | @property (assign, nonatomic) unichar eventCharacter; 14 | 15 | - (BOOL)eventIsSpace; 16 | - (BOOL)eventIsDelete; 17 | - (BOOL)eventIsTab; 18 | 19 | - (void)resetEventCharacter; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | .DS_Store 3 | */build/* 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | *.xcworkspace 13 | !default.xcworkspace 14 | xcuserdata 15 | profile 16 | *.moved-aside 17 | DerivedData 18 | .idea/ 19 | *.hmap 20 | *.xccheckout 21 | Bitmessage.xcodeproj/project.xcworkspace/xcuserdata/steve.xcuserdatad/UserInterfaceState.xcuserstate 22 | Bitmessage.xcodeproj/xcuserdata/steve.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist 23 | -------------------------------------------------------------------------------- /Bitmessage/Classes/Browser/Inspectors/Addressed/BMChannelView.m: -------------------------------------------------------------------------------- 1 | // 2 | // BMChannelView.m 3 | // Bitmessage 4 | // 5 | // Created by Steve Dekorte on 2/20/14. 6 | // Copyright (c) 2014 voluntary.net. All rights reserved. 7 | // 8 | 9 | #import "BMChannelView.h" 10 | 11 | @implementation BMChannelView 12 | 13 | - (void)setup 14 | { 15 | [super setup]; 16 | [self.addressField setEditable:NO]; 17 | [self.addressField setDelegate:nil]; 18 | } 19 | 20 | - (void)updateContact 21 | { 22 | //if (self.contact.isValidAddress) 23 | { 24 | [self.contact update]; 25 | } 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /Bitmessage/resources/icons/unused_svg_icons/icon_add.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "BitmessageKit"] 2 | path = submodules/BitmessageKit 3 | url = https://github.com/stevedekorte/BitmessageKit.git 4 | [submodule "NavKit"] 5 | path = submodules/NavKit 6 | url = https://github.com/stevedekorte/NavKit.git 7 | [submodule "NavNodeKit"] 8 | path = submodules/NavNodeKit 9 | url = https://github.com/stevedekorte/NavNodeKit.git 10 | [submodule "FoundationCategoriesKit"] 11 | path = submodules/FoundationCategoriesKit 12 | url = https://github.com/stevedekorte/FoundationCategoriesKit.git 13 | [submodule "submodules/SystemInfoKit"] 14 | path = submodules/SystemInfoKit 15 | url = git@github.com:Voluntarynet/SystemInfoKit.git 16 | -------------------------------------------------------------------------------- /Bitmessage/resources/icons/unused_svg_icons/icon_right.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Bitmessage/Classes/Browser/Inspectors/Message/BMMessageView.h: -------------------------------------------------------------------------------- 1 | // 2 | // BMMessageView.h 3 | // Bitmarket 4 | // 5 | // Created by Steve Dekorte on 2/5/14. 6 | // Copyright (c) 2014 voluntary.net. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface BMMessageView : NavColoredView 13 | 14 | @property (assign, nonatomic) id navView; 15 | @property (strong, nonatomic) NavNode * node; // node keeps a ref to us? 16 | 17 | @property (strong, nonatomic) NSScrollView *scrollView; 18 | @property (strong, nonatomic) NSTextView *textView; 19 | 20 | - (NSString *)selectedContent; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Bitmessage/resources/icons/unused_svg_icons/icon_left.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /BitmessageTests/BitpostTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | net.voluntary.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /BitmessageTests/BitmessageTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // BitmessageTests.m 3 | // BitmessageTests 4 | // 5 | // Created by Steve Dekorte on 2/11/14. 6 | // Copyright (c) 2014 voluntary.net. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BitmessageTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation BitmessageTests 16 | 17 | - (void)setUp 18 | { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown 24 | { 25 | // Put teardown code here. This method is called after the invocation of each test method in the class. 26 | [super tearDown]; 27 | } 28 | 29 | - (void)testExample 30 | { 31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /Bitmessage/Classes/Browser/Inspectors/Addressed/BMAddressed+NodeView.m: -------------------------------------------------------------------------------- 1 | // 2 | // BMAddressed+NodeView.m 3 | // Bitmessage 4 | // 5 | // Created by Steve Dekorte on 4/8/14. 6 | // Copyright (c) 2014 voluntary.net. All rights reserved. 7 | // 8 | 9 | #import "BMAddressed+NodeView.h" 10 | #import "BMDraftController.h" 11 | #import 12 | 13 | @implementation BMAddressed (NodeView) 14 | 15 | 16 | - (void)message 17 | { 18 | BMDraftController *draftController = [BMDraftController openNewDraft]; 19 | 20 | [draftController.to setStringValue:self.address]; 21 | 22 | NSString *from = [[[BMClient.sharedBMClient identities] firstIdentity] address]; 23 | 24 | if (from) 25 | { 26 | [draftController.from setStringValue:from]; 27 | } 28 | 29 | [draftController.subject becomeFirstResponder]; 30 | [draftController open]; 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /Bitmessage/Classes/Browser/Inspectors/NewUser/BMNewUserView.h: -------------------------------------------------------------------------------- 1 | // 2 | // BMNewUserView.h 3 | // Bitmessage 4 | // 5 | // Created by Steve Dekorte on 2/27/14. 6 | // Copyright (c) 2014 voluntary.net. All rights reserved. 7 | // 8 | 9 | #import "BMAddressedView.h" 10 | #import 11 | 12 | @interface BMNewUserView : NavColoredView 13 | 14 | @property (strong, nonatomic) NavTextView *instructionsText; 15 | //@property (strong, nonatomic) NavTextView *usernameField; 16 | //@property (strong, nonatomic) NSView *replacementView; 17 | @property (strong, nonatomic) NSWindow *targetWindow; 18 | @property (strong, nonatomic) NavTextView *addressText; 19 | @property (strong, nonatomic) NavTextView *instructionsText2; 20 | @property (strong, nonatomic) NavButton *okButton; 21 | 22 | @property (strong, nonatomic) NSColor *darkColor; 23 | @property (strong, nonatomic) NSColor *mediumColor; 24 | @property (strong, nonatomic) NSColor *lightColor; 25 | 26 | - (void)open; 27 | 28 | @end 29 | 30 | -------------------------------------------------------------------------------- /Bitmessage/Classes/Browser/Inspectors/Addressed/BMAddressedView.h: -------------------------------------------------------------------------------- 1 | // 2 | // BMAddressedView.h 3 | // Bitmessage 4 | // 5 | // Created by Steve Dekorte on 2/21/14. 6 | // Copyright (c) 2014 voluntary.net. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | 13 | @interface BMAddressedView : NavColoredView 14 | 15 | @property (assign, nonatomic) id navView; 16 | @property (assign, nonatomic) NavNode *node; // node keeps a ref to us? 17 | 18 | @property (strong, nonatomic) NSView *innerView; // contains labels and checkbox 19 | @property (strong, nonatomic) NSTextView *labelField; 20 | @property (strong, nonatomic) NSTextView *addressField; 21 | @property (strong, nonatomic) NSImageView *checkbox; 22 | 23 | @property (assign, nonatomic) BOOL isUpdating; 24 | 25 | - (BMContact *)contact; 26 | 27 | - (void)setup; 28 | - (void)prepareToDisplay; 29 | 30 | - (BOOL)isSynced; 31 | - (void)syncToNode; 32 | - (void)syncFromNode; 33 | 34 | - (void)selectFirstResponder; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /Bitmessage/Classes/Browser/Controllers/Draft/BMAddressCompletor.h: -------------------------------------------------------------------------------- 1 | // 2 | // BMAddressCompletor.h 3 | // Bitmessage 4 | // 5 | // Created by Steve Dekorte on 2/24/14. 6 | // Copyright (c) 2014 voluntary.net. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "BMAddressTextField.h" 11 | 12 | @interface BMAddressCompletor : NSObject 13 | 14 | @property (assign, nonatomic) id delegate; 15 | @property (assign, nonatomic) BOOL isCompleting; 16 | @property (strong, nonatomic) BMAddressTextField *textField; 17 | @property (strong, nonatomic) NSSet *addressLabels; 18 | @property (strong, nonatomic) NSString *lastString; 19 | @property (assign, nonatomic) BOOL shouldComplete; 20 | 21 | 22 | - (void)controlTextDidChange:(NSNotification *)note; 23 | 24 | - (NSArray *)control:(NSControl *)control 25 | textView:(NSTextView *)textView 26 | completions:(NSArray *)words 27 | forPartialWordRange:(NSRange)charRange 28 | indexOfSelectedItem:(NSInteger *)index; 29 | 30 | - (BOOL)isMatched; 31 | - (BOOL)isValid; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Voluntary.net 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /Bitmessage/resources/icons/unused_svg_icons/litecoin.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 13 | 14 | -------------------------------------------------------------------------------- /Bitmessage/resources/icons/unused_svg_icons/tv.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Bitmessage/resources/icons/unused_svg_icons/mobile.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Bitmessage/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "icon_16x16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "icon_16x16@2x.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "icon_32x32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "icon_32x32@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "icon_128x128@2x.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "icon_128x128@2x-1.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "icon_256x256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "icon_256x256@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "icon_512x512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "icon_512x512@2x.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /Bitmessage/resources/icons/unused_svg_icons/computing.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 20 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Bitmessage/resources/icons/unused_svg_icons/clothing.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Bitmessage/resources/icons/unused_svg_icons/bitcoin.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Bitmessage/Classes/Browser/Controllers/Draft/BMAddressTextField.m: -------------------------------------------------------------------------------- 1 | // 2 | // BMAddressTextField.m 3 | // Bitmessage 4 | // 5 | // Created by Steve Dekorte on 2/26/14. 6 | // Copyright (c) 2014 voluntary.net. All rights reserved. 7 | // 8 | // This is needed to get auto complete to behave properly 9 | 10 | #import "BMAddressTextField.h" 11 | 12 | @implementation BMAddressTextField 13 | 14 | - (BOOL)eventIsDelete 15 | { 16 | return self.eventCharacter == NSDeleteCharacter; 17 | //return self.eventCharacter == 127; 18 | } 19 | 20 | - (BOOL)eventIsSpace 21 | { 22 | return self.eventCharacter == 32; 23 | } 24 | 25 | - (BOOL)eventIsTab 26 | { 27 | return self.eventCharacter == NSTabCharacter; 28 | } 29 | 30 | static NSEvent *keyEvent = nil; 31 | 32 | - (void)resetEventCharacter 33 | { 34 | self.eventCharacter = 0; 35 | } 36 | 37 | - (BOOL)becomeFirstResponder 38 | { 39 | BOOL okToChange = [super becomeFirstResponder]; 40 | 41 | [NSNotificationCenter.defaultCenter addObserver:self 42 | selector:@selector(textDidEndEditing:) 43 | name:NSTextDidEndEditingNotification 44 | object:self]; 45 | 46 | if (okToChange) 47 | { 48 | [self setKeyboardFocusRingNeedsDisplayInRect: [self bounds]]; 49 | 50 | if (!keyEvent) 51 | { 52 | keyEvent = [NSEvent addLocalMonitorForEventsMatchingMask:NSKeyDownMask handler:^(NSEvent *event) { 53 | 54 | NSString *characters = [event characters]; 55 | unichar character = [characters characterAtIndex:0]; 56 | self.eventCharacter = character; 57 | //NSLog(@"character = %i", (int)character); 58 | 59 | return event; 60 | } ]; 61 | 62 | } 63 | } 64 | //NSLog(@"become first responder"); 65 | return okToChange; 66 | } 67 | 68 | - (void)textDidEndEditing:(NSNotification *)notification 69 | { 70 | [NSEvent removeMonitor:keyEvent]; 71 | keyEvent = nil; 72 | 73 | NSTextView *textView = [notification object]; 74 | 75 | self.stringValue = textView.string; 76 | } 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /Bitmessage/Classes/Browser/Controllers/Draft/BMDraftController.h: -------------------------------------------------------------------------------- 1 | // 2 | // BMDraftController.h 3 | // Bitmarket 4 | // 5 | // Created by Steve Dekorte on 2/9/14. 6 | // Copyright (c) 2014 voluntary.net. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "BMAddressCompletor.h" 12 | #import "BMAddressTextField.h" 13 | 14 | @interface BMDraftController : NSViewController 15 | 16 | @property (assign, nonatomic) IBOutlet NSButton *sendButton; 17 | 18 | @property (assign, nonatomic) IBOutlet NSTextField *fromLabel; 19 | @property (assign, nonatomic) IBOutlet BMAddressTextField *from; 20 | @property (assign, nonatomic) IBOutlet NSTextField *fromNote; 21 | 22 | 23 | @property (assign, nonatomic) IBOutlet NSTextField *toLabel; 24 | @property (assign, nonatomic) IBOutlet BMAddressTextField *to; 25 | @property (assign, nonatomic) IBOutlet NSTextField *toNote; 26 | 27 | 28 | @property (assign, nonatomic) IBOutlet NSTextField *subjectLabel; 29 | @property (assign, nonatomic) IBOutlet NSTextField *subject; 30 | 31 | 32 | 33 | @property (assign, nonatomic) IBOutlet NSScrollView *scrollView; 34 | @property (assign, nonatomic) IBOutlet NavMarginTextView *bodyText; 35 | 36 | 37 | @property (strong, nonatomic) NavColoredView *bodyArea; 38 | @property (assign, nonatomic) IBOutlet NavColoredView *topBackground; 39 | @property (assign, nonatomic) IBOutlet NavColoredView *fromBackground; 40 | @property (assign, nonatomic) IBOutlet NavColoredView *toBackground; 41 | @property (assign, nonatomic) IBOutlet NavColoredView *subjectBackground; 42 | 43 | @property (strong, nonatomic) BMAddressCompletor *fromCompletor; 44 | @property (strong, nonatomic) BMAddressCompletor *toCompletor; 45 | 46 | @property (assign, nonatomic) BOOL isBroadcast; 47 | 48 | + (BMDraftController *)openNewDraft; 49 | + (BMDraftController *)openNewBroadcast; 50 | 51 | - (IBAction)send:(id)sender; 52 | 53 | - (void)setCursorForReply; 54 | - (void)setCursorOnTo; 55 | - (void)setCursorOnBody; 56 | 57 | - (void)open; 58 | 59 | - (void)updateSendButton; 60 | - (void)setDefaultFrom; 61 | 62 | - (void)setAddressesToLabels; 63 | - (void)addSubjectPrefix:(NSString *)prefix; 64 | 65 | - (void)setBodyString:(NSString *)aString; 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /Todo.txt: -------------------------------------------------------------------------------- 1 | 2 | === important === 3 | 4 | - remove inbox and replace with identities -> identity -> inbox 5 | -- support editing name and address in table cell 6 | 7 | 8 | - delete any message whose toAddress doesn't match an identity, channel or subscription 9 | - some way to choose a default identity 10 | - [feature] separate reply button on channels to reply using channel as fromAddress 11 | 12 | == features ============ 13 | 14 | One shot ids for sending messages to channels (send and then delete id) 15 | 16 | === can be done independently === 17 | 18 | - [UX] menu bar item with unread count 19 | - [UX] make links in messages clickable but with security alert panel 20 | - [feature] support for bitmessage:// links from browsers, etc 21 | 22 | - change "Today" to "2:34pm Today" etc 23 | 24 | ============== 25 | 26 | - [cleanup] move app support files for BitmessageKit framework to their own folder 27 | 28 | - [UX] match channel names in compose window w/o [chan] 29 | 30 | - [cosmetic] use compose icon instead of reply icon on channel 31 | 32 | - [feature] separate channel list from being subscribed so user can toggle subscriptions? 33 | 34 | ======================= 35 | 36 | - [cleaup] move themes.json to navkit? 37 | - [cleaup] move icons to navkit? 38 | 39 | - [cleaup] get rid of themedictionary 40 | 41 | - [UX] move export to action on client 42 | 43 | - [feature] zip export/import? 44 | 45 | - BMChannel and subscriptions should not be BMAddressed 46 | - have them own addresses 47 | - have BMChannels/BMSubscriptions have their own DBs 48 | - list of subs and chans from server only indictation whether they are active 49 | 50 | - [cleanup] cleanup keys.dat backups 51 | - [UX] undo delete 52 | 53 | - channel replies should go to channel, not poster? offer option? 54 | 55 | - [UX] force pastes into compose not to promote to rich text 56 | - [cleanup] cleanup base64 in dicts 57 | - [UX] error panel if can't connect to server - option to quit 58 | 59 | - [UX] scroll to visible on selected child index changes (e.g. editing name of contact) 60 | 61 | - [optimization] merge address requests? 62 | - [optimization] eventually delloc cached nodeViews when not in use? 63 | 64 | - [cosmetic] finish themeing including start page 65 | - [cosmetic] themable alert sounds 66 | - [cosmetic] compose text color changes for quoted text? 67 | -------------------------------------------------------------------------------- /Bitmessage/Bitpost-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ATSApplicationFontsPath 6 | fonts/Open_Sans 7 | BitmessageAPIPort 8 | 8452 9 | BitmessagePort 10 | 8454 11 | CFBundleDevelopmentRegion 12 | en 13 | CFBundleDocumentTypes 14 | 15 | 16 | CFBundleTypeExtensions 17 | 18 | bmbox 19 | 20 | CFBundleTypeIconFile 21 | 22 | CFBundleTypeName 23 | Bitmessage mailbox archive 24 | CFBundleTypeRole 25 | Editor 26 | LSItemContentTypes 27 | 28 | net.voluntary.bitmessage.archive 29 | 30 | 31 | 32 | CFBundleExecutable 33 | ${EXECUTABLE_NAME} 34 | CFBundleIconFile 35 | 36 | CFBundleIdentifier 37 | net.voluntary.bitpostapp 38 | CFBundleInfoDictionaryVersion 39 | 6.0 40 | CFBundleName 41 | ${PRODUCT_NAME} 42 | CFBundlePackageType 43 | APPL 44 | CFBundleShortVersionString 45 | 0.9.8.3 46 | CFBundleSignature 47 | ???? 48 | CFBundleURLTypes 49 | 50 | 51 | CFBundleURLSchemes 52 | 53 | bitmessage 54 | 55 | 56 | 57 | CFBundleVersion 58 | 0.9.8.3 59 | LSApplicationCategoryType 60 | public.app-category.social-networking 61 | LSMinimumSystemVersion 62 | ${MACOSX_DEPLOYMENT_TARGET} 63 | NSHumanReadableCopyright 64 | Copyright © 2014 Voluntary.net. All rights reserved. 65 | NSMainNibFile 66 | MainMenu 67 | NSPrincipalClass 68 | NSApplication 69 | torSocksPort 70 | 9050 71 | 72 | 73 | -------------------------------------------------------------------------------- /Bitmessage/Classes/Browser/Inspectors/Message/BMMessage+NodeView.m: -------------------------------------------------------------------------------- 1 | // 2 | // BMMessage+NodeView.m 3 | // Bitmessage 4 | // 5 | // Created by Steve Dekorte on 2/27/14. 6 | // Copyright (c) 2014 voluntary.net. All rights reserved. 7 | // 8 | 9 | #import "BMMessage+NodeView.h" 10 | #import 11 | #import 12 | #import "BMDraftController.h" 13 | #import "BMMessageView.h" 14 | 15 | @implementation BMMessage (NodeView) 16 | 17 | - (void)initCategory 18 | { 19 | [super initCategory]; 20 | 21 | { 22 | NavActionSlot *slot = [self.navMirror newActionSlotWithName:@"reply"]; 23 | [slot setVisibleName:@"reply"]; 24 | } 25 | 26 | { 27 | NavActionSlot *slot = [self.navMirror newActionSlotWithName:@"forward"]; 28 | [slot setVisibleName:@"forward"]; 29 | } 30 | } 31 | 32 | - (NSString *)nodeNote 33 | { 34 | return self.date.itemDateString; 35 | } 36 | 37 | - (NSString *)quotedMessage 38 | { 39 | NSString *date = [[self date] 40 | descriptionWithCalendarFormat:@"%b %d" timeZone:nil 41 | locale:[[NSUserDefaults standardUserDefaults] dictionaryRepresentation]]; 42 | 43 | NSString *s = ((BMMessageView *)self.nodeView).selectedContent; 44 | 45 | if (s == nil || [s length] == 0) 46 | { 47 | s = self.message.decodedBase64; 48 | } 49 | 50 | NSString *q = [s stringByReplacingOccurrencesOfString:@"\n" withString:@"\n> "]; 51 | q = [@"> " stringByAppendingString:q]; 52 | 53 | 54 | return [NSString stringWithFormat:@"\n\n\nOn %@, %@ wrote:\n%@\n", date, [self fromAddressLabel], q]; 55 | } 56 | 57 | - (void)reply // move to draft class 58 | { 59 | BMDraftController *draft = [BMDraftController openNewDraft]; 60 | 61 | [draft.to setStringValue:self.fromAddress]; 62 | [draft.from setStringValue:self.toAddress]; 63 | //[draft setDefaultFrom]; 64 | [draft setAddressesToLabels]; 65 | [draft.subject setStringValue:self.subjectString]; 66 | [draft addSubjectPrefix:@"Re: "]; 67 | [draft setBodyString:self.quotedMessage]; 68 | [draft setCursorForReply]; 69 | [draft open]; 70 | } 71 | 72 | - (void)forward // move to draft class 73 | { 74 | BMDraftController *draft = [BMDraftController openNewDraft]; 75 | 76 | [draft setDefaultFrom]; 77 | [draft setAddressesToLabels]; 78 | [draft.subject setStringValue:self.subjectString]; 79 | [draft addSubjectPrefix:@"Fwd: "]; 80 | [draft setBodyString:self.quotedMessage]; 81 | [draft setCursorOnTo]; 82 | [draft open]; 83 | } 84 | 85 | 86 | - (Class)viewClass 87 | { 88 | return [BMMessageView class]; 89 | } 90 | 91 | @end 92 | -------------------------------------------------------------------------------- /Bitmessage/resources/icons/unused_svg_icons/music.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 12 | 17 | 19 | 20 | 21 | 23 | 25 | 27 | 29 | 31 | 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | About Bitpost 3 | ========== 4 | 5 | Bitpost is a user friendly Bitmessage client for OSX. 6 | 7 | The official website for the project is: 8 | * http://voluntary.net/bitpost 9 | 10 | 11 | What's Bitmessage? 12 | -------------------------- 13 | 14 | Bitmessage is a decentralized messaging system. Instead of connecting to centralized servers (like Facebook, gmail, etc) or federated servers (like email, IRC, Jabber), when you run a Bitmessage client it connects to other clients directly forming a network which can relay messages with no central control. 15 | 16 | Your address is a public encryption key that others can use to encrypt messages to you in a way that only you can decrypt. Messages are sent to the network over Tor (another decentralized network that hides the source of network requests) in order to conceal the location of the sender. 17 | 18 | Bitmessage adopts some standards from Bitcoin such as sharing a similar binary protocol, similar node discovery and message sharing systems, and address format but it has no "blockchain". Messages are simply shared between nodes and cached for two days before being deleted (though your client will keep any messages sent to you). 19 | 20 | For more info see: 21 | 22 | * https://bitmessage.org 23 | 24 | 25 | How Bitpost Works 26 | ------------------------ 27 | 28 | The UI launches a local pybitmessage node in the background which uses Tor to connect to the Bitmessage network. 29 | 30 | The local bitmessage node is run with custom node and API ports so it doesn't interfere with other bitmessage clients. The app uses it's own bitmessage keys.dat file for the app which is stored in ~/Library/Application Support/Bitpost. 31 | 32 | 33 | Importing keys 34 | ------------------ 35 | 36 | Dropping in your current bitmessage-qt keys.dat file may not work as the .dat file format changes between pybitmessage releases. You may be able to import a key pair by: 37 | 38 | * making sure the Bitpost app is not running 39 | * make a backup copy of the Bitpost keys.dat 40 | * open the Bitpost keys.dat and copy in your identity key pair 41 | * close the keys.dat file and try starting Bitpost 42 | 43 | If this doesn't work, replace the Bitpost keys.dat file with the backup copy. 44 | 45 | 46 | Compiling 47 | ------------- 48 | 49 | After cloning the repo: 50 | 51 | * git clone https://github.com/stevedekorte/Bitpost.git 52 | 53 | and making sure to pull in the submodules, you should be able to open the project file in Xcode and build it. Note that BitmessageKit includes some precompiled components. See it's notes for compiling those from source. 54 | 55 | License 56 | ---------- 57 | 58 | The code is open source under an MIT license. 59 | 60 | 61 | Contributing 62 | --------------- 63 | 64 | We would welcome your contributions. 65 | 66 | 67 | Credits 68 | --------- 69 | 70 | * Chris Robinson - Designer 71 | * Steve Dekorte - Lead & UI Developer 72 | * Adam Thorsen - Generalist (Tor and Python intergration) 73 | * Dru Nelson - Unix Guru 74 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /Bitmessage/resources/icons/unused_svg_icons/photography.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 18 | 19 | 20 | 21 | 24 | 29 | 30 | 32 | 34 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /Bitmessage/Classes/Browser/Controllers/BMAppController.m: -------------------------------------------------------------------------------- 1 | 2 | #import "BMAppController.h" 3 | #import 4 | #import 5 | #import "BMDraftController.h" 6 | #import "BMNewUserView.h" 7 | #import "BMClient+NodeView.h" 8 | 9 | @implementation BMAppController 10 | 11 | - (void)applicationDidFinishLaunching: (NSNotification *)aNote 12 | { 13 | [super applicationDidFinishLaunching:aNote]; 14 | 15 | [self setNavTitle:@"launching server..."]; 16 | BMNode *root = BMClient.sharedBMClient; 17 | [self setRootNode:(NavNode *)root]; 18 | [self setNavTitle:@""]; 19 | [self addAbout]; 20 | 21 | [self checkForNewUser]; 22 | [NSAppleEventManager.sharedAppleEventManager setEventHandler:self 23 | andSelector:@selector(composeFromURL:) 24 | forEventClass:kInternetEventClass 25 | andEventID:kAEGetURL]; 26 | } 27 | 28 | - (void)addAbout 29 | { 30 | NavInfoNode *about = [[NavInfoNode alloc] init]; 31 | about.nodeTitle = @"About"; 32 | about.nodeSuggestedWidth = @200; 33 | 34 | NavInfoNode *info = (NavInfoNode *)BMClient.sharedBMClient.nodeAbout; 35 | [about addChild:info]; 36 | 37 | [self.rootNode addChild:about]; 38 | } 39 | 40 | - (void)checkForNewUser 41 | { 42 | if (BMClient.sharedBMClient.hasNoIdentites || 43 | BMClient.sharedBMClient.identities.firstIdentity.hasUnsetLabel) 44 | { 45 | [self openNewUserView]; 46 | } 47 | 48 | //[BMClient.sharedBMClient.channels channelWithPassphraseJoinIfNeeded:@"Bitpost"]; 49 | BMSubscription *sub = [BMClient.sharedBMClient.subscriptions subscriptionWithAddressAddIfNeeded:@"BM-2cWfHSiKkbXoUmwiqPAqdhZyRUoShQmPr5"]; 50 | [sub setLabel:@"Bitpost releases"]; 51 | 52 | } 53 | 54 | - (void)openNewUserView 55 | { 56 | /* 57 | BMIdentity *identity = [BMClient.sharedBMClient.identities createFirstIdentityIfAbsent]; 58 | 59 | if (identity.hasUnsetLabel) 60 | { 61 | identity.label = NSFullUserName(); 62 | [identity update]; 63 | } 64 | 65 | BMMessage *msg = [[BMMessage alloc] init]; 66 | msg.toAddress = identity.address; 67 | msg.fromAddress = identity.address; 68 | msg.subject = @"Welcome to Bitpost"; 69 | */ 70 | 71 | { 72 | //NSRect f = self.navWindow.backgroundView.frame; 73 | BMNewUserView *nuv = [[BMNewUserView alloc] initWithFrame:self.navWindow.backgroundView.frame]; 74 | [nuv setAutoresizesSubviews:YES]; 75 | nuv.targetWindow = self.navWindow; 76 | [nuv open]; 77 | } 78 | } 79 | 80 | - (IBAction)compose:(id)sender // hack - consolidate into BMDraftController 81 | { 82 | [(BMClient *)self.rootNode compose]; 83 | } 84 | 85 | - (IBAction)composeBroadcast:(id)sender // hack - consolidate into BMDraftController 86 | { 87 | [(BMClient *)self.rootNode composeBroadcast]; 88 | } 89 | 90 | - (void)composeFromURL:(NSAppleEventDescriptor *)event 91 | { 92 | NSURL *url = [NSURL URLWithString:[[event paramDescriptorForKeyword:keyDirectObject] stringValue]]; 93 | [(BMClient *)self.rootNode composeWithAddress: [url host]]; 94 | } 95 | 96 | 97 | /* 98 | - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename 99 | { 100 | NSLog(@"open '%@'", filename); 101 | return YES; 102 | } 103 | 104 | - (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames 105 | { 106 | NSLog(@"open filenames"); 107 | } 108 | */ 109 | 110 | @end 111 | -------------------------------------------------------------------------------- /Bitmessage/Classes/Browser/Inspectors/BMClient+NodeView.m: -------------------------------------------------------------------------------- 1 | // 2 | // BMClient+UI.m 3 | // Bitmessage 4 | // 5 | // Created by Steve Dekorte on 4/17/14. 6 | // Copyright (c) 2014 voluntary.net. All rights reserved. 7 | // 8 | 9 | #import "BMClient+NodeView.h" 10 | #import "BMDraftController.h" 11 | 12 | @implementation BMClient (NodeView) 13 | 14 | - (void)initCategory 15 | { 16 | [super initCategory]; 17 | 18 | { 19 | NavActionSlot *slot = [self.navMirror newActionSlotWithName:@"compose"]; 20 | [slot setVisibleName:@"compose"]; 21 | } 22 | 23 | /* 24 | { 25 | NavActionSlot *slot = [self.navMirror newActionSlotWithName:@"export"]; 26 | [slot setVisibleName:@"export"]; 27 | } 28 | 29 | { 30 | NavActionSlot *slot = [self.navMirror newActionSlotWithName:@"import"]; 31 | [slot setVisibleName:@"import"]; 32 | } 33 | */ 34 | } 35 | 36 | - (void)compose 37 | { 38 | BMDraftController *draft = [BMDraftController openNewDraft]; 39 | [draft setDefaultFrom]; 40 | [draft setCursorOnTo]; 41 | [draft open]; 42 | } 43 | 44 | - (void)composeBroadcast 45 | { 46 | BMDraftController *draft = [BMDraftController openNewBroadcast]; 47 | [draft setDefaultFrom]; 48 | [draft setCursorOnBody]; 49 | [draft open]; 50 | } 51 | 52 | - (void)composeWithAddress:(NSString *)address 53 | { 54 | BMDraftController *draft = [BMDraftController openNewDraft]; 55 | [draft setDefaultFrom]; 56 | [draft.to setStringValue:address]; 57 | [draft setCursorOnTo]; 58 | [draft open]; 59 | } 60 | 61 | 62 | /* 63 | - (NSString *)verifyActionMessage:(NSString *)actionString 64 | { 65 | if ([actionString isEqualToString:@"import"]) 66 | { 67 | return @"CAUTION: This operation will delete your current Bitmessage mailbox and any identities you have in it. This will destroy the private keys for those identities making any mail sent to them permanently unreadable."; 68 | } 69 | 70 | 71 | return nil; 72 | } 73 | */ 74 | 75 | // import/export 76 | 77 | /* 78 | - (void)export 79 | { 80 | NSOpenPanel* panel = [NSOpenPanel openPanel]; 81 | [panel setCanChooseDirectories:YES]; 82 | [panel setCanChooseFiles:NO]; 83 | [panel setAllowsMultipleSelection:NO]; 84 | [panel setMessage:@"Choose a folder to place your exported mailbox file in"]; 85 | 86 | NSWindow *window = [[NSApplication sharedApplication] mainWindow]; 87 | [panel beginSheetModalForWindow:window completionHandler:^(NSInteger result) 88 | { 89 | if (result == NSFileHandlingPanelOKButton) 90 | { 91 | NSArray* urls = [panel URLs]; 92 | NSURL *url = [urls firstObject]; 93 | NSLog(@"url '%@'", url); 94 | [BMClient.sharedBMClient archiveToUrl:url]; 95 | } 96 | }]; 97 | } 98 | 99 | - (void)import 100 | { 101 | NSOpenPanel *panel = [NSOpenPanel openPanel]; 102 | [panel setCanChooseDirectories:NO]; 103 | [panel setCanChooseFiles:YES]; 104 | [panel setAllowsMultipleSelection:NO]; 105 | [panel setMessage:@"Choose a .bmbox file to import"]; 106 | 107 | NSWindow *window = [[NSApplication sharedApplication] mainWindow]; 108 | [panel beginSheetModalForWindow:window completionHandler:^(NSInteger result) 109 | { 110 | if (result == NSFileHandlingPanelOKButton) 111 | { 112 | NSArray *urls = [panel URLs]; 113 | NSURL *url = [urls firstObject]; 114 | NSLog(@"url '%@'", url); 115 | [BMClient.sharedBMClient unarchiveFromUrl:url]; 116 | } 117 | 118 | }]; 119 | } 120 | */ 121 | 122 | @end 123 | -------------------------------------------------------------------------------- /Bitmessage/resources/icons/unused_svg_icons/icon_profile.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 16 | 17 | 23 | 25 | 30 | 32 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Bitmessage/Classes/Browser/Inspectors/NewUser/BMNewUserView.m: -------------------------------------------------------------------------------- 1 | // 2 | // BMNewUserView.m 3 | // Bitmessage 4 | // 5 | // Created by Steve Dekorte on 2/27/14. 6 | // Copyright (c) 2014 voluntary.net. All rights reserved. 7 | // 8 | 9 | #import "BMNewUserView.h" 10 | #import 11 | #import 12 | 13 | @implementation BMNewUserView 14 | 15 | - (id)initWithFrame:(NSRect)frame 16 | { 17 | self = [super initWithFrame:frame]; 18 | 19 | if (self) 20 | { 21 | self.darkColor = [NavTheme.sharedNavTheme formText3Color]; 22 | self.mediumColor = [NavTheme.sharedNavTheme formText2Color]; 23 | self.lightColor = [NavTheme.sharedNavTheme formText1Color]; 24 | 25 | [self setAutoresizingMask: NSViewWidthSizable | 26 | NSViewMinYMargin | 27 | NSViewMaxYMargin | 28 | NSViewHeightSizable | 29 | NSViewMinXMargin | 30 | NSViewMaxXMargin]; 31 | 32 | 33 | self.instructionsText = [[NavTextView alloc] initWithFrame:NSMakeRect(0, 0, frame.size.width, 50)]; 34 | self.instructionsText.string = @"Please choose a username and hit return to begin."; 35 | [self.instructionsText setupForDisplay]; 36 | self.instructionsText.textColor = self.darkColor; 37 | self.instructionsText.string = @"Looks like this is your first time running a bitmessage client\nso I've generated an address for you:"; 38 | 39 | 40 | self.addressText = [[NavTextView alloc] initWithFrame:NSMakeRect(0, 0, frame.size.width, 40)]; 41 | self.addressText.string = self.identity.address; 42 | [self.addressText setupForEditing]; 43 | [self.addressText setSelectable:YES]; 44 | [self.addressText setEditable:NO]; 45 | [self.addressText setFontSize:self.addressText.font.pointSize - 2]; 46 | self.addressText.textColor = self.mediumColor; 47 | 48 | self.instructionsText2 = [[NavTextView alloc] initWithFrame:NSMakeRect(0, 0, frame.size.width, 40)]; 49 | self.instructionsText2.string = @""; 50 | [self.instructionsText2 setupForDisplay]; 51 | self.instructionsText2.textColor = self.darkColor; 52 | self.instructionsText2.string = @"Like an email address, you can share this address to receive messages.\nYou can find this later in the My Identities tab."; 53 | 54 | self.okButton = [[NavButton alloc] initWithFrame:NSMakeRect(0, 0, self.width, 30)]; 55 | //self.okButton = [[NavButton alloc] initWithFrame:NSMakeRect(0, 0, 100, 30)]; 56 | [self.okButton setTarget:self]; 57 | [self.okButton setActionTitle:@"OK"]; 58 | [self.okButton setAction:@selector(ok)]; 59 | [self.okButton setFontSize:22]; 60 | [self.okButton updateTitle]; 61 | 62 | [self addSubview:self.instructionsText]; 63 | [self addSubview:self.addressText]; 64 | [self addSubview:self.instructionsText2]; 65 | [self addSubview:self.okButton]; 66 | 67 | [NSNotificationCenter.defaultCenter addObserver:self 68 | selector:@selector(windowDidResize:) 69 | name:NSWindowDidResizeNotification 70 | object:nil]; 71 | } 72 | 73 | return self; 74 | } 75 | 76 | - (void)dealloc 77 | { 78 | [NSNotificationCenter.defaultCenter removeObserver:self]; 79 | } 80 | 81 | - (void)windowDidResize:(NSNotification *)notification 82 | { 83 | [self layout]; 84 | } 85 | 86 | - (void)layout 87 | { 88 | [self stackSubviewsTopToBottomWithMargin:25.0]; 89 | [self centerStackedSubviewsY]; 90 | [self centerSubviewsX]; 91 | //[self.okButton centerXInSuperview]; 92 | } 93 | 94 | - (void)drawRect:(NSRect)dirtyRect 95 | { 96 | [super drawRect:dirtyRect]; 97 | [[NavTheme.sharedNavTheme formBackgroundColor] set]; 98 | NSRectFill(dirtyRect); 99 | } 100 | 101 | - (BMIdentity *)identity 102 | { 103 | return [[BMClient.sharedBMClient identities] createFirstIdentityIfAbsent]; 104 | } 105 | 106 | - (void)open 107 | { 108 | NSView *contentView = self.targetWindow.contentView; 109 | self.frame = contentView.frame; 110 | //[self.window.contentView replaceSubview:self.replacementView with:self]; 111 | 112 | [contentView addSubview:self]; 113 | 114 | if (self.identity.hasUnsetLabel) 115 | { 116 | self.identity.label = NSFullUserName(); 117 | [self.identity update]; 118 | } 119 | 120 | [self layout]; 121 | 122 | for (NSView *view in self.subviews) 123 | { 124 | [view animateUpFadeIn]; 125 | } 126 | } 127 | 128 | - (void)ok 129 | { 130 | [self close]; 131 | } 132 | 133 | - (void)close 134 | { 135 | for (NSView *view in self.subviews) 136 | { 137 | //[view animateDownFadeOut]; 138 | [view animateFadeOut]; 139 | } 140 | 141 | [self animateFadeOut]; 142 | [self performSelector:@selector(completeClose) withObject:nil afterDelay:1.0]; 143 | [NSNotificationCenter.defaultCenter removeObserver:self]; 144 | } 145 | 146 | - (void)completeClose 147 | { 148 | //NSView *contentView = self.targetWindow.contentView; 149 | [self removeFromSuperview]; 150 | 151 | //self.replacementView.alphaValue = 1.0; 152 | //[self.window.contentView replaceSubview:self with:self.replacementView]; 153 | //[self.window.contentView addSubview:self positioned:NSWindowAbove relativeTo:nil]; 154 | 155 | //[self.window.contentView addSubview:self.replacementView]; 156 | //[self removeFromSuperview]; 157 | //[self.replacementView animateFadeIn]; 158 | } 159 | 160 | @end 161 | -------------------------------------------------------------------------------- /Bitmessage/Classes/Browser/Controllers/Draft/BMAddressCompletor.m: -------------------------------------------------------------------------------- 1 | // 2 | // BMAddressCompletor.m 3 | // Bitmessage 4 | // 5 | // Created by Steve Dekorte on 2/24/14. 6 | // Copyright (c) 2014 voluntary.net. All rights reserved. 7 | // 8 | 9 | #import "BMAddressCompletor.h" 10 | #import 11 | #import 12 | 13 | 14 | @implementation BMAddressCompletor 15 | 16 | - (id)init 17 | { 18 | self = [super init]; 19 | //self.addressLabels = [BMClient.sharedBMClient addressLabels]; 20 | return self; 21 | } 22 | 23 | - (void)setTextField:(NSTextField *)textField 24 | { 25 | _textField = (BMAddressTextField *) textField; 26 | [_textField setDelegate:self]; 27 | } 28 | 29 | - (NSString *)selectedString 30 | { 31 | NSText *text = [self.textField.window fieldEditor:YES forObject:self.textField]; 32 | NSRange r = [text selectedRange]; 33 | return [[self.textField stringValue] substringWithRange:r]; 34 | } 35 | 36 | - (NSString *)unselectedString 37 | { 38 | NSText *text = [self.textField.window fieldEditor:YES forObject:self.textField]; 39 | NSRange r = [text selectedRange]; 40 | return [[text string] substringWithRange:NSMakeRange(0, r.location)]; // correct? 41 | } 42 | 43 | - (void)controlTextDidChange:(NSNotification *)note 44 | { 45 | if (self.isCompleting) 46 | { 47 | return; 48 | } 49 | else 50 | { 51 | self.shouldComplete = YES; 52 | 53 | if (self.textField.eventIsDelete) 54 | { 55 | //NSLog(@"delete - returning"); 56 | self.shouldComplete = NO; 57 | } 58 | 59 | if (self.textField.eventIsSpace) 60 | { 61 | //NSLog(@"space - returning"); 62 | self.textField.stringValue = [self.textField.stringValue stringByAppendingString:@" "]; 63 | self.shouldComplete = NO; 64 | } 65 | 66 | if (self.textField.eventIsTab) 67 | { 68 | [[self.textField nextKeyView] becomeFirstResponder]; 69 | self.shouldComplete = NO; 70 | } 71 | 72 | if (self.shouldComplete) 73 | { 74 | self.isCompleting = YES; 75 | 76 | //NSText *text = [self.textField.window fieldEditor:YES forObject:self.textField]; 77 | id editor = [[note userInfo] objectForKey:@"NSFieldEditor"]; 78 | if ([editor respondsToSelector:@selector(complete:)]) 79 | { 80 | [editor complete:nil]; 81 | } 82 | else 83 | { 84 | NSLog(@"can't call complete:"); 85 | } 86 | 87 | self.isCompleting = NO; 88 | } 89 | } 90 | 91 | if (self.isValid) 92 | { 93 | /* 94 | self.textField.textColor = [NavTheme.sharedNavTheme formText2Color]; 95 | [self.textField setFont:[NSFont fontWithName:[NavTheme.sharedNavTheme lightFontName] size:self.textField.font.pointSize]]; 96 | */ 97 | [self.textField setThemePath:@"draft/field"]; 98 | } 99 | else 100 | { 101 | /* 102 | self.textField.textColor = [NavTheme.sharedNavTheme formTextErrorColor]; 103 | [self.textField setFont:[NSFont fontWithName:@"Open Sans Bold" size:self.textField.font.pointSize]]; 104 | */ 105 | [self.textField setThemePath:@"draft/fieldError"]; 106 | } 107 | 108 | [self.textField resetEventCharacter]; 109 | } 110 | 111 | - (NSArray *)control:(NSControl *)control 112 | textView:(NSTextView *)textView 113 | completions:(NSArray *)words 114 | forPartialWordRange:(NSRange)charRange 115 | indexOfSelectedItem:(NSInteger *)index 116 | { 117 | if (!self.shouldComplete) 118 | { 119 | //NSLog(@"skip complete"); 120 | return [NSArray array]; 121 | } 122 | 123 | NSMutableArray *matches = [NSMutableArray array]; 124 | NSInteger end = charRange.location + charRange.length; 125 | NSRange fullRange = NSMakeRange(0, end); 126 | 127 | NSString *full = [[textView string] substringWithRange:fullRange]; 128 | NSString *selected = [[textView string] substringWithRange:charRange]; 129 | 130 | //NSLog(@"selected '%@' full '%@'", selected, full); 131 | 132 | for (NSString *label in self.addressLabels) 133 | { 134 | 135 | if ([full containsString:@" "]) 136 | { 137 | NSArray *words = [label componentsSeparatedByString:@" "]; 138 | 139 | for (NSString *word in words) 140 | { 141 | if (word.length && [[word lowercaseString] hasPrefix:[selected lowercaseString]]) 142 | { 143 | [matches addObject:word]; 144 | } 145 | } 146 | } 147 | else 148 | { 149 | if (label.length && [[label lowercaseString] hasPrefix:[full lowercaseString]]) 150 | { 151 | [matches addObject:label]; 152 | } 153 | } 154 | } 155 | 156 | return matches; 157 | } 158 | 159 | - (BOOL)isMatched 160 | { 161 | NSString *selected = [self.textField stringValue]; 162 | 163 | for (NSString *label in self.addressLabels) 164 | { 165 | if ([label isEqualToString:selected]) 166 | { 167 | return YES; 168 | } 169 | } 170 | 171 | return NO; 172 | } 173 | 174 | - (BOOL)isValid 175 | { 176 | return self.isMatched || [BMAddress isValidAddress:[self.textField.stringValue strip]]; 177 | } 178 | 179 | - (void)textDidEndEditing:(NSNotification *)notification 180 | { 181 | [self.textField textDidEndEditing:notification]; 182 | } 183 | 184 | //- (BOOL)textView:(NSTextView *)aTextView doCommandBySelector:(SEL)aSelector 185 | - (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)command 186 | { 187 | //NSLog(@"command '%@'", NSStringFromSelector(command)); 188 | 189 | if (command == @selector(insertTab:) || command == @selector(insertNewline:)) 190 | { 191 | NSView *next = self.textField.nextKeyView; 192 | //NSLog(@"selectNextKeyView %@", next); 193 | [next becomeFirstResponder]; 194 | //[[self window] selectNextKeyView:nil]; 195 | return YES; 196 | } 197 | 198 | return NO; 199 | } 200 | 201 | -(void)controlTextDidEndEditing:(NSNotification *)notification 202 | { 203 | // See if it was due to a return 204 | if ( [[[notification userInfo] objectForKey:@"NSTextMovement"] intValue] == NSReturnTextMovement ) 205 | { 206 | //NSLog(@"Return was pressed!"); 207 | } 208 | } 209 | 210 | @end 211 | -------------------------------------------------------------------------------- /Bitmessage/resources/icons/unused_svg_icons/sports.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 13 | 14 | 16 | 19 | 23 | 26 | 29 | 32 | 35 | 38 | 41 | 44 | 47 | 51 | 55 | 59 | 63 | 67 | 71 | 75 | 79 | 80 | -------------------------------------------------------------------------------- /Bitmessage/Classes/Browser/Inspectors/Addressed/BMAddressedView.m: -------------------------------------------------------------------------------- 1 | // 2 | // BMAddressedView.m 3 | // Bitmessage 4 | // 5 | // Created by Steve Dekorte on 2/21/14. 6 | // Copyright (c) 2014 voluntary.net. All rights reserved. 7 | // 8 | 9 | #import "BMAddressedView.h" 10 | #import 11 | #import 12 | 13 | @implementation BMAddressedView 14 | 15 | - (id)initWithFrame:(NSRect)frame 16 | { 17 | self = [super initWithFrame:frame]; 18 | 19 | if (self) 20 | { 21 | [self setAutoresizesSubviews:YES]; 22 | [self setAutoresizingMask:NSViewHeightSizable | NSViewWidthSizable]; 23 | [self setup]; 24 | } 25 | 26 | return self; 27 | } 28 | 29 | 30 | - (void)setup 31 | { 32 | [self setThemePath:@"address/background"]; 33 | 34 | self.innerView = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, self.width, self.height)]; 35 | [self addSubview:self.innerView]; 36 | [_innerView setAutoresizesSubviews:NO]; 37 | 38 | self.labelField = [[NSTextView alloc] initWithFrame:NSMakeRect(0, 0, self.width/2, 24)]; 39 | [self.innerView addSubview:self.labelField]; 40 | 41 | [self.labelField setThemePath:@"address/label"]; 42 | [self.labelField setSelectedThemePath:@"address/selected"]; 43 | 44 | [self.labelField centerXInSuperview]; 45 | [self.labelField centerYInSuperview]; 46 | [self.labelField setAutoresizingMask: NSViewWidthSizable | NSViewMinYMargin | NSViewMaxYMargin]; 47 | [self.labelField setDelegate:self]; 48 | [self.labelField setRichText:NO]; 49 | 50 | // address color is 143.0/255.0 51 | self.addressField = [[NSTextView alloc] initWithFrame:NSMakeRect(0, 0, self.width/2, 16)]; 52 | [self.innerView addSubview:self.addressField]; 53 | 54 | [self.addressField setThemePath:@"address/address"]; 55 | [self.addressField setSelectedThemePath:@"address/selected"]; 56 | 57 | [self.addressField centerXInSuperview]; 58 | [self.addressField setY:self.labelField.maxY + 10]; 59 | [self.addressField setAutoresizingMask: NSViewWidthSizable | NSViewMinYMargin | NSViewMaxYMargin]; 60 | [self.addressField setDelegate:self]; 61 | [self.addressField setRichText:NO]; 62 | 63 | 64 | self.checkbox = [[NSImageView alloc] initWithFrame:NSMakeRect(0, 0, 30, 30)]; 65 | [self.checkbox setImage:nil]; 66 | [self.innerView addSubview:self.checkbox]; 67 | 68 | [self setPositions]; 69 | 70 | } 71 | 72 | - (void)prepareToDisplay 73 | { 74 | if ([self.labelField.string isEqualToString:[[self.node class] defaultLabel]]) 75 | { 76 | [self.window makeFirstResponder:self.labelField]; 77 | //[self.labelField becomeFirstResponder]; 78 | [self.labelField selectAll:nil]; 79 | } 80 | [self setPositions]; 81 | } 82 | 83 | - (void)dealloc 84 | { 85 | [NSNotificationCenter.defaultCenter removeObserver:self]; 86 | } 87 | 88 | - (void)setFrame:(NSRect)frameRect 89 | { 90 | [super setFrame:frameRect]; 91 | [self setPositions]; 92 | [self setPositions]; 93 | } 94 | 95 | - (void)setPositions 96 | { 97 | //[self.innerView setFrame:self.bounds]; 98 | [self.innerView setFrame:NSMakeRect(0, 0, self.frame.size.width, self.frame.size.height)]; 99 | //[self.innerView centerXInSuperview]; 100 | //[self.innerView centerYInSuperview]; 101 | 102 | [self.labelField setX:0]; 103 | [self.labelField setY:0]; 104 | [self.labelField setWidth:self.width]; 105 | 106 | [self.addressField setX:0]; 107 | [self.addressField placeYBelow:_labelField margin:10]; 108 | [self.addressField setWidth:self.width]; 109 | 110 | [self.checkbox placeYBelow:_addressField margin:40]; 111 | 112 | [self.innerView sizeAndRepositionSubviewsToFit]; 113 | [self.innerView setWidth:self.width]; 114 | //[self.innerView centerSubviewsX]; 115 | [self.addressField centerXInSuperview]; 116 | [self.checkbox centerXInSuperview]; 117 | [self.innerView centerYInSuperview]; 118 | } 119 | 120 | - (void)setNode:(NavNode *)node 121 | { 122 | _node = node; 123 | [self syncFromNode]; 124 | [self updateCheckbox]; 125 | [self updateAddressColor]; 126 | } 127 | 128 | // change to get from col 129 | /* 130 | - (void)drawRect:(NSRect)dirtyRect 131 | { 132 | //[self setPositions]; // don't like this here but couldn't find who was moving the label 133 | [super drawRect:dirtyRect]; 134 | 135 | [bgColor set]; 136 | NSRectFill(dirtyRect); 137 | } 138 | */ 139 | 140 | - (BOOL)hasValidAddress 141 | { 142 | return [BMAddress isValidAddress:self.addressField.string.strip]; 143 | } 144 | 145 | - (void)updateAddressColor 146 | { 147 | if (self.hasValidAddress) 148 | { 149 | [self.addressField setThemePath:@"address/address"]; 150 | } 151 | else 152 | { 153 | [self.addressField setThemePath:@"address/addressError"]; 154 | 155 | } 156 | } 157 | 158 | - (BMContact *)contact 159 | { 160 | return (BMContact *)self.node; 161 | } 162 | 163 | // --- text changes --- 164 | 165 | - (void)textDidChange:(NSNotification *)aNotification 166 | { 167 | if (!self.isUpdating) // to avoid textDidChange call from endEditingOnReturn 168 | { 169 | self.isUpdating = YES; 170 | 171 | @try 172 | { 173 | if ([self.labelField didTab]) 174 | { 175 | [self.labelField removeTabs]; 176 | 177 | NSTextView *next = (NSTextView *)[self.labelField nextKeyView]; 178 | 179 | if (next && [next isEditable]) 180 | { 181 | [self.window makeFirstResponder:next]; 182 | [next selectAll:nil]; 183 | } 184 | 185 | self.isUpdating = NO; 186 | return; 187 | } 188 | 189 | if([self.labelField endEditingOnReturn]) 190 | { 191 | [self saveChanges]; 192 | [self.labelField gotoNext]; 193 | } 194 | 195 | if([self.addressField endEditingOnReturn]) 196 | { 197 | [self saveChanges]; 198 | [self.labelField gotoNext]; 199 | } 200 | 201 | [self updateAddressColor]; 202 | [self updateCheckbox]; 203 | } 204 | @catch (NSException *exception) 205 | { 206 | NSLog(@"exception %@", exception); 207 | } 208 | @finally 209 | { 210 | self.isUpdating = NO; 211 | } 212 | } 213 | } 214 | 215 | - (void)updateCheckbox 216 | { 217 | if (/*!self.isUpdating &&*/ self.isSynced && self.contact.isSynced && self.hasValidAddress) 218 | { 219 | [self.checkbox setImage:[NSImage imageNamed:@"icon_tick"]]; 220 | } 221 | else 222 | { 223 | [self.checkbox setImage:nil]; 224 | } 225 | 226 | [self.checkbox display]; 227 | } 228 | 229 | - (void)textDidEndEditing:(NSNotification *)aNotification 230 | { 231 | //NSLog(@"textDidEndEditing"); 232 | [[aNotification object] endEditing]; 233 | [self saveChanges]; 234 | } 235 | 236 | - (void)saveChanges 237 | { 238 | [self updateCheckbox]; 239 | [self updateAddressColor]; 240 | 241 | //if (!self.isSynced) 242 | { 243 | [self syncToNode]; 244 | [self updateContact]; 245 | [self syncFromNode]; 246 | } 247 | 248 | [self updateCheckbox]; 249 | [self updateAddressColor]; 250 | 251 | [self.labelField display]; 252 | [self.addressField display]; 253 | } 254 | 255 | - (void)updateContact 256 | { 257 | if (self.contact.isValidAddress) 258 | { 259 | [self.contact update]; 260 | } 261 | } 262 | 263 | // -- sync ---- 264 | 265 | - (BOOL)isSynced 266 | { 267 | BOOL labelMatches = [self.contact.visibleLabel 268 | isEqualToString:self.labelField.string.strip]; 269 | 270 | BOOL addressMatches = [self.contact.address 271 | isEqualToString:self.addressField.string.strip]; 272 | 273 | return labelMatches && addressMatches; 274 | } 275 | 276 | - (void)syncToNode 277 | { 278 | self.contact.visibleLabel = [self.labelField.string strip]; 279 | self.contact.address = [self.addressField.string strip]; 280 | } 281 | 282 | - (void)syncFromNode 283 | { 284 | [self.labelField setString:self.contact.visibleLabel]; 285 | [self.addressField setString:self.contact.address]; 286 | } 287 | 288 | - (void)selectFirstResponder 289 | { 290 | [self.window makeFirstResponder:self.labelField]; 291 | [self.labelField selectAll:nil]; 292 | //[labelField becomeFirstResponder]; 293 | } 294 | 295 | @end 296 | -------------------------------------------------------------------------------- /Bitmessage/Classes/Browser/Inspectors/Message/BMMessageView.m: -------------------------------------------------------------------------------- 1 | // 2 | // BMMessageView.m 3 | // Bitmarket 4 | // 5 | // Created by Steve Dekorte on 2/5/14. 6 | // Copyright (c) 2014 voluntary.net. All rights reserved. 7 | // 8 | 9 | #import "BMMessageView.h" 10 | #import 11 | #import 12 | 13 | @implementation BMMessageView 14 | 15 | - (id)initWithFrame:(NSRect)frameRect 16 | { 17 | self = [super initWithFrame:frameRect]; 18 | [self setThemePath:@"message/body"]; 19 | [self setAutoresizesSubviews:YES]; 20 | [self setAutoresizingMask:NSViewHeightSizable | NSViewWidthSizable]; 21 | [self setupBody]; 22 | return self; 23 | } 24 | 25 | - (void)dealloc 26 | { 27 | //NSLog(@"dealloc BMMessageView %p", (__bridge void *)self); 28 | } 29 | 30 | - (NSString *)fontName 31 | { 32 | return [NavTheme.sharedNavTheme lightFontName]; 33 | } 34 | 35 | - (NSDictionary *)subjectAttributes 36 | { 37 | return [NavTheme.sharedNavTheme attributesDictForPath:@"message/title"]; 38 | } 39 | 40 | - (NSDictionary *)infoAttributes 41 | { 42 | return [NavTheme.sharedNavTheme attributesDictForPath:@"message/subtitle"]; 43 | } 44 | 45 | - (NSDictionary *)bodyAttributes 46 | { 47 | NSDictionary *themeDict = [NavTheme.sharedNavTheme attributesDictForPath:@"message/body"]; 48 | NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:themeDict]; 49 | //[dict setObject:self.dynamicBackgroundColor forKey:NSBackgroundColorAttributeName]; 50 | return dict; 51 | } 52 | 53 | - (NSDictionary *)linkAttributes 54 | { 55 | return [NavTheme.sharedNavTheme attributesDictForPath:@"message/link"]; 56 | } 57 | 58 | - (NSMutableAttributedString *)linkForAddress:(NSString *)address 59 | { 60 | NSMutableDictionary *att = [NSMutableDictionary dictionaryWithDictionary:[self infoAttributes]]; 61 | 62 | if ([address hasPrefix:@"BM-"]) 63 | { 64 | att = [NSMutableDictionary dictionaryWithDictionary:[self linkAttributes]]; 65 | [att setObject:[NSString stringWithFormat:@"BitmessageAddContact://%@", address] forKey:NSLinkAttributeName]; 66 | } 67 | 68 | NSMutableAttributedString *string = [[NSMutableAttributedString alloc] 69 | initWithString:address 70 | attributes:att]; 71 | 72 | return string; 73 | } 74 | 75 | - (NSAttributedString *)bodyString 76 | { 77 | NSMutableParagraphStyle *indented = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; 78 | 79 | [indented setAlignment:NSLeftTextAlignment]; 80 | [indented setLineSpacing:1.0]; 81 | [indented setParagraphSpacing:1.0]; 82 | [indented setHeadIndent:0.0]; 83 | [indented setTailIndent:0.0]; 84 | //[indented setFirstLineHeadIndent:45.0]; 85 | [indented setLineBreakMode:NSLineBreakByWordWrapping]; 86 | 87 | [self.message markAsRead]; 88 | 89 | NSMutableAttributedString *fullMessage = [[NSMutableAttributedString alloc] initWithString:@""]; 90 | 91 | NSMutableAttributedString *subjectString = [[NSMutableAttributedString alloc] 92 | initWithString:[NSString stringWithFormat:@"%@\n", self.message.subjectString] 93 | attributes:[self subjectAttributes]]; 94 | 95 | [fullMessage appendAttributedString:subjectString]; 96 | [fullMessage appendAttributedString:[self linkForAddress:self.message.fromAddressLabel]]; 97 | 98 | [fullMessage appendAttributedString:[[NSMutableAttributedString alloc] 99 | initWithString:@" → " 100 | attributes:[self infoAttributes]]]; 101 | 102 | [fullMessage appendAttributedString:[self linkForAddress:self.message.toAddressLabel]]; 103 | 104 | if (self.message.class == [BMSentMessage class]) 105 | { 106 | NSString *status = ((BMSentMessage *)self.message).getHumanReadbleStatus; 107 | 108 | if (status) 109 | { 110 | [fullMessage appendAttributedString:[[NSMutableAttributedString alloc] 111 | initWithString:[NSString stringWithFormat:@" (%@)", status] 112 | attributes:[self infoAttributes]]]; 113 | } 114 | } 115 | 116 | [fullMessage appendAttributedString:[[NSMutableAttributedString alloc] 117 | initWithString:@"\n" 118 | attributes:[self infoAttributes]]]; 119 | 120 | [fullMessage appendAttributedString:[[NSMutableAttributedString alloc] 121 | initWithString:@"\n" 122 | attributes:[self subjectAttributes]]]; 123 | 124 | // body 125 | 126 | 127 | [fullMessage appendAttributedString:[self.message messageStringWithAttributes:self.bodyAttributes]]; 128 | 129 | [fullMessage addAttribute:NSParagraphStyleAttributeName 130 | value:indented 131 | range:NSMakeRange(0, [subjectString length])]; 132 | 133 | return fullMessage; 134 | } 135 | 136 | - (BMMessage *)message 137 | { 138 | return (BMMessage *)self.node; 139 | } 140 | 141 | - (void)setNode:(NavNode *)node 142 | { 143 | if (_node != node) 144 | { 145 | _node = node; 146 | 147 | //[self.textView setString:message.messageString]; 148 | //[self.textView setFont:nil]; 149 | 150 | [self.textView setRichText:YES]; 151 | [self.textView setEditable:NO]; 152 | [self.textView setString:@""]; 153 | [self.textView.textStorage setAttributedString:[self bodyString]]; 154 | [self.textView setWidth:self.frame.size.width]; 155 | 156 | 157 | [[self.scrollView contentView] scrollToPoint:NSMakePoint (0, 0)]; 158 | [self.scrollView reflectScrolledClipView: [self.scrollView contentView]]; 159 | 160 | } 161 | 162 | [self configBody]; 163 | } 164 | 165 | - (void)setNavView:(id)navView 166 | { 167 | _navView = navView; 168 | self.backgroundColor = self.dynamicBackgroundColor; 169 | } 170 | 171 | - (NSColor *)dynamicBackgroundColor 172 | { 173 | NavColumn *column = [self.navView columnForNode:_node]; 174 | NavThemeDictionary *theme = [NavTheme.sharedNavTheme themeForColumn:column.columnIndex - 1]; 175 | return[theme selectedBgColor]; 176 | } 177 | 178 | - (void)setupBody 179 | { 180 | NSRect f = self.frame; 181 | 182 | self.scrollView = [[NavResizingScrollView alloc] initWithFrame:f]; 183 | [self addSubview:self.scrollView]; 184 | [self.scrollView setHasVerticalScroller:YES]; 185 | [self.scrollView setHasHorizontalRuler:NO]; 186 | [self.scrollView setHorizontalScrollElasticity:NSScrollElasticityNone]; 187 | [self.scrollView setAutoresizesSubviews:YES]; 188 | [self.scrollView setAutoresizingMask:NSViewHeightSizable | NSViewWidthSizable]; 189 | 190 | self.textView = [[NavMarginTextView alloc] initWithFrame:self.scrollView.bounds]; 191 | [self.scrollView setDocumentView:self.textView]; 192 | [self.textView setDelegate:self]; 193 | 194 | [self configBody]; 195 | } 196 | 197 | - (void)configBody 198 | { 199 | [self.textView setThemePath:@"message/background"]; 200 | [self.textView setLinkTextAttributes:[self linkAttributes]]; 201 | } 202 | 203 | - (void)drawRect:(NSRect)dirtyRect 204 | { 205 | [super drawRect:dirtyRect]; 206 | [self.textView.backgroundColor set]; 207 | NSRectFill(dirtyRect); 208 | } 209 | 210 | - (NSString *)selectedContent 211 | { 212 | return [[self.textView string] 213 | substringWithRange:[self.textView selectedRange]]; 214 | } 215 | 216 | - (void)prepareToDisplay 217 | { 218 | 219 | } 220 | 221 | - (BOOL)textView:(NSTextView *)aTextView 222 | clickedOnLink:(id)link 223 | atIndex:(NSUInteger)charIndex 224 | { 225 | NSArray *parts = [link componentsSeparatedByString:@"://"]; 226 | NSString *command = [parts objectAtIndex:0]; 227 | NSString *argument = [parts objectAtIndex:1]; 228 | 229 | //NSLog(@"clickedOnLink %@", link); 230 | 231 | if ([command isEqualToString:@"BitmessageAddContact"]) 232 | { 233 | BMClient *client = BMClient.sharedBMClient; 234 | BMContacts *contacts = [client contacts]; 235 | BMContact *newContact = [contacts justAdd]; 236 | [newContact setAddress:argument]; 237 | 238 | NSArray *nodes = [NSArray arrayWithObjects:client, contacts, newContact, nil]; 239 | [self.navView selectNodePath:nodes]; 240 | return YES; // yes, we handled it 241 | } 242 | 243 | return NO; 244 | } 245 | 246 | @end 247 | 248 | -------------------------------------------------------------------------------- /Bitmessage/resources/themes/themes.json: -------------------------------------------------------------------------------- 1 | { 2 | "default": 3 | { 4 | 5 | "item" : 6 | { 7 | "unselected" : 8 | { 9 | "title" : 10 | { 11 | "fontName" : "Open Sans", 12 | "fontSize" : 13, 13 | "color" : "#CBCBCB", 14 | }, 15 | 16 | "subtitle" : 17 | { 18 | "fontName" : "Open Sans Light", 19 | "fontSize" : 11, 20 | "color" : "#989898", 21 | }, 22 | 23 | "note" : 24 | { 25 | "fontName" : "Open Sans Light", 26 | "fontSize" : 10, 27 | "color" : "#E7E7E7", 28 | }, 29 | }, 30 | 31 | "selected" : 32 | { 33 | "title" : 34 | { 35 | "fontName" : "Open Sans", 36 | "fontSize" : 13, 37 | "color" : "#FFFFFF", 38 | }, 39 | 40 | "subtitle" : 41 | { 42 | "fontName" : "Open Sans", 43 | "fontSize" : 11, 44 | "color" : "#FFFFFF", 45 | }, 46 | 47 | "note" : 48 | { 49 | "fontName" : "Open Sans", 50 | "fontSize" : 10, 51 | "color" : "#FFFFFF", 52 | }, 53 | }, 54 | 55 | "unread" : 56 | { 57 | "title" : 58 | { 59 | "fontName" : "Open Sans", 60 | "fontSize" : 13, 61 | "color" : "#81BAE5", 62 | }, 63 | 64 | "subtitle" : 65 | { 66 | "fontName" : "Open Sans Light", 67 | "fontSize" : 11, 68 | "color" : "#81BAE5", 69 | }, 70 | 71 | "note" : 72 | { 73 | "fontName" : "Open Sans", 74 | "fontSize" : 10, 75 | "color" : "#81BAE5", 76 | }, 77 | }, 78 | }, 79 | 80 | "columns": 81 | [ 82 | { 83 | "unselectedBgColor": [0.12], 84 | "selectedBgColor": [0.09], 85 | }, 86 | 87 | { 88 | "unselectedBgColor": [0.09], 89 | "selectedBgColor": [0.07], 90 | }, 91 | 92 | { 93 | "unselectedBgColor": [0.07], 94 | "selectedBgColor": [0.03], 95 | }, 96 | 97 | { 98 | "unselectedBgColor": [0.03], 99 | "selectedBgColor": [0.0], 100 | } 101 | ], 102 | 103 | 104 | "address": 105 | { 106 | "label" : 107 | { 108 | "fontName" : "Open Sans Light", 109 | "fontSize" : 24, 110 | "color" : "#FFFFFF", 111 | "align" : "center", 112 | }, 113 | 114 | "address" : 115 | { 116 | "fontName" : "Open Sans Light", 117 | "fontSize" : 16, 118 | "color" : "#8F8F8F", 119 | "align" : "center", 120 | }, 121 | 122 | "addressError" : 123 | { 124 | "fontName" : "Open Sans Light", 125 | "fontSize" : 16, 126 | "color" : "#FF0000", 127 | "align" : "center", 128 | }, 129 | 130 | "selected" : 131 | { 132 | "backgroundColor" : "#555555", 133 | }, 134 | 135 | "background" : 136 | { 137 | "backgroundColor" : "#000000", 138 | }, 139 | 140 | }, 141 | 142 | "formBackgroundColor": [0.03], 143 | "formText1Color": [1], 144 | "formText2Color": [0.82], 145 | "formText3Color": [0.5], 146 | "formText4Color": [0.3], 147 | "formTextErrorColor": [1, 0, 0], 148 | "formTextSelectedBgColor": [0.3], 149 | "formTextCursorColor": [1], 150 | "formTextLinkColor": [0.7], 151 | 152 | "lightFontName": "Open Sans Light", 153 | "mediumFontName": "Open Sans", 154 | 155 | "message": 156 | { 157 | "title" : 158 | { 159 | "fontName" : "Open Sans", 160 | "fontSize" : 24, 161 | "color" : "#FFFFFF", 162 | }, 163 | 164 | "subtitle" : 165 | { 166 | "fontName" : "Open Sans Light", 167 | "fontSize" : 13, 168 | "color" : "#BBBBBB", 169 | }, 170 | 171 | "link" : 172 | { 173 | "fontName" : "Open Sans Light", 174 | "fontSize" : 13, 175 | "color" : "#EEEEEE", 176 | "text-decoration": "none", 177 | }, 178 | 179 | "body" : 180 | { 181 | "fontName" : "Open Sans Light", 182 | "fontSize" : 13, 183 | "color" : "#D3D3D3", 184 | }, 185 | 186 | "background" : 187 | { 188 | "backgroundColor" : "#000000", 189 | }, 190 | }, 191 | 192 | "draft" : 193 | { 194 | "fieldTitle" : 195 | { 196 | "fontName" : "Open Sans", 197 | "fontSize" : 13, 198 | "color" : "#323232", 199 | "align": "right", 200 | }, 201 | 202 | "field" : 203 | { 204 | "fontName" : "Open Sans", 205 | "fontSize" : 13, 206 | "color" : "#8F8F8F", 207 | "align": "left", 208 | }, 209 | 210 | "field-uneditable" : 211 | { 212 | "fontName" : "Open Sans", 213 | "fontSize" : 13, 214 | "color" : "#8F8F8F", 215 | "align": "left", 216 | }, 217 | 218 | "fieldError" : 219 | { 220 | "fontName" : "Open Sans Bold", 221 | "fontSize" : 13, 222 | "color" : "#FF0000", 223 | }, 224 | 225 | "note" : 226 | { 227 | "fontName" : "Open Sans", 228 | "fontSize" : 13, 229 | "color" : "#DDDDDD", 230 | "align": "right", 231 | }, 232 | 233 | 234 | "body" : 235 | { 236 | "fontName" : "Open Sans", 237 | "fontSize" : 13, 238 | "color" : "#8F8F8F", 239 | "backgroundColor" : "#FFFFFF", 240 | }, 241 | 242 | "separators": 243 | { 244 | "backgroundColor" : "#EEEEEE", 245 | }, 246 | }, 247 | 248 | 249 | "info" : 250 | { 251 | "header" : 252 | { 253 | "fontName" : "Open Sans Bold", 254 | "fontSize" : 16, 255 | "color" : "#777777", 256 | "align" : "center", 257 | }, 258 | 259 | "subheader" : 260 | { 261 | "fontName" : "Open Sans Light", 262 | "fontSize" : 16, 263 | "color" : "#777777", 264 | "align" : "center", 265 | }, 266 | 267 | 268 | "title" : 269 | { 270 | "fontName" : "Open Sans", 271 | "fontSize" : 16, 272 | "color" : "#777777", 273 | "align" : "center", 274 | }, 275 | 276 | "item" : 277 | { 278 | "fontName" : "Open Sans Light", 279 | "fontSize" : 16, 280 | "color" : "#AAAAAA", 281 | "align" : "center", 282 | }, 283 | 284 | "item.alt" : 285 | { 286 | "fontName" : "Open Sans Light", 287 | "fontSize" : 16, 288 | "color" : "#DDDDDD", 289 | "align" : "center", 290 | }, 291 | 292 | 293 | "background": 294 | { 295 | "backgroundColor" : "#191919", 296 | }, 297 | } 298 | 299 | 300 | }, 301 | } 302 | -------------------------------------------------------------------------------- /Vendor/fonts/Open_Sans/LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /Bitmessage/resources/fonts/Open_Sans/LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /Bitmessage/Classes/Browser/Controllers/Draft/BMDraftController.m: -------------------------------------------------------------------------------- 1 | // 2 | // BMDraftController.m 3 | // Bitmarket 4 | // 5 | // Created by Steve Dekorte on 2/9/14. 6 | // Copyright (c) 2014 voluntary.net. All rights reserved. 7 | // 8 | 9 | #import "BMDraftController.h" 10 | #import 11 | #import 12 | 13 | NSMutableArray *sharedDrafts = nil; 14 | 15 | @implementation BMDraftController 16 | 17 | + (NSMutableArray *)drafts 18 | { 19 | if (!sharedDrafts) 20 | { 21 | sharedDrafts = [NSMutableArray array]; 22 | } 23 | 24 | return sharedDrafts; 25 | } 26 | 27 | + (BMDraftController *)openNewDraft 28 | { 29 | BMDraftController *draft = [[BMDraftController alloc] initWithNibName:@"Compose" bundle:nil]; 30 | [[[self class] drafts] addObject:draft]; 31 | [draft view]; // to force lazy load 32 | [draft open]; 33 | return draft; 34 | } 35 | 36 | + (BMDraftController *)openNewBroadcast 37 | { 38 | BMDraftController *draft = [[BMDraftController alloc] initWithNibName:@"Compose" bundle:nil]; 39 | [[[self class] drafts] addObject:draft]; 40 | [draft setIsBroadcast:YES]; 41 | [draft view]; // to force lazy load 42 | [draft open]; 43 | return draft; 44 | } 45 | 46 | 47 | - (void)placeWindow 48 | { 49 | NSRect f = [[NSApplication sharedApplication] mainWindow].frame; 50 | NSPoint topLeft = f.origin; 51 | topLeft.y += f.size.height; 52 | topLeft.y -= 20; 53 | topLeft.x += 20; 54 | NSWindow *window = [[self view] window]; 55 | [window setFrameTopLeftPoint:topLeft]; 56 | [window makeKeyAndOrderFront:self]; 57 | } 58 | 59 | - (NSWindow *)window 60 | { 61 | return self.view.window; 62 | } 63 | 64 | - (void)dealloc 65 | { 66 | [NSNotificationCenter.defaultCenter removeObserver:self]; 67 | } 68 | 69 | - (void)loadView 70 | { 71 | [super loadView]; 72 | 73 | self.fromCompletor = [[BMAddressCompletor alloc] init]; 74 | self.fromCompletor.addressLabels = [BMClient.sharedBMClient fromAddressLabels]; 75 | 76 | self.toCompletor = [[BMAddressCompletor alloc] init]; 77 | self.toCompletor.addressLabels = [BMClient.sharedBMClient allAddressLabels]; 78 | 79 | [self setupViewPositions]; 80 | [self setupHighlightColors]; 81 | [self setupNotifications]; 82 | [self setupDefaultValues]; 83 | [self updateWindow]; 84 | [self.window setDelegate:self]; 85 | 86 | //[self.from setDelegate:self.fromCompletor]; 87 | //[self.to setDelegate:self.toCompletor]; 88 | 89 | [self.fromCompletor setTextField:self.from]; 90 | [self.toCompletor setTextField:self.to]; 91 | } 92 | 93 | - (void)setupViewPositions 94 | { 95 | [self.bodyArea setThemePath:@"draft/body"]; 96 | [self.topBackground setThemePath:@"draft/separators"]; 97 | [self.fromBackground setThemePath:@"draft/body"]; 98 | [self.toBackground setThemePath:@"draft/body"]; 99 | [self.subjectBackground setThemePath:@"draft/body"]; 100 | 101 | [self removeFocusRings]; 102 | 103 | //[[self.to superview] setY:[self.from superview].maxY + 2]; 104 | [[self.to superview] setY:[self.from superview].y - [self.to superview].height - 1]; 105 | [[self.subject superview] setY:[self.to superview].y - [self.subject superview].height - 1]; 106 | 107 | [self.topBackground setX:0]; 108 | [self.topBackground setWidth:((NSView *)self.window.contentView).frame.size.width]; 109 | 110 | [self.topBackground setY:[self.subject superview].y -1]; 111 | [self.topBackground setHeight:[self.from superview].maxY - [self.subject superview].y]; 112 | 113 | [self.scrollView setX:0]; 114 | [self.scrollView setY:0]; 115 | [self.scrollView setHeight:self.topBackground.y -0]; 116 | [self.scrollView setWidth:self.scrollView.superview.width]; 117 | 118 | [self.bodyText setThemePath:@"draft/body"]; 119 | 120 | [self.to setThemePath:@"draft/field"]; 121 | [self.toLabel setThemePath:@"draft/fieldTitle"]; 122 | 123 | [self.from setThemePath:@"draft/field"]; 124 | [self.fromLabel setThemePath:@"draft/fieldTitle"]; 125 | 126 | [self.subject setThemePath:@"draft/field"]; 127 | [self.subjectLabel setThemePath:@"draft/fieldTitle"]; 128 | 129 | [self.from setNextKeyView:self.to]; 130 | [self.to setNextKeyView:self.subject]; 131 | [self.subject setNextKeyView:self.bodyText]; 132 | 133 | [self.fromNote setY:self.from.y]; 134 | [self.fromNote setThemePath:@"draft/note"]; 135 | 136 | [self.toNote setY:self.to.y]; 137 | [self.toNote setThemePath:@"draft/note"]; 138 | 139 | if (self.isBroadcast) 140 | { 141 | [self.to setStringValue:@"[broadcast subscribers]"]; 142 | [self.to setEditable:NO]; 143 | [self.to setSelectable:NO]; 144 | [self.to setThemePath:@"draft/field-uneditable"]; 145 | [self.from setNextKeyView:self.subject]; 146 | } 147 | } 148 | 149 | - (void)setupHighlightColors 150 | { 151 | [self.to setSelectedThemePath:@"draft/fieldSelected"]; 152 | [self.from setSelectedThemePath:@"draft/fieldSelected"]; 153 | [self.subject setSelectedThemePath:@"draft/fieldSelected"]; 154 | 155 | /* 156 | NSDictionary *att = [NSDictionary dictionaryWithObjectsAndKeys: 157 | [NavTheme.sharedNavTheme draftBodyTextSelectedColor], NSBackgroundColorAttributeName, 158 | nil]; 159 | NSTextView *tv; 160 | 161 | [self.to setSelectedThemePath:@"draft/fieldSelected"]; 162 | [self.from setSelectedThemePath:@"draft/fieldSelected"]; 163 | [self.subject setSelectedThemePath:@"draft/fieldSelected"]; 164 | 165 | tv = (NSTextView *)[self.window fieldEditor:YES forObject:self.to]; 166 | [tv setSelectedTextAttributes:att]; 167 | 168 | tv = (NSTextView *)[self.window fieldEditor:YES forObject:self.from]; 169 | [tv setSelectedTextAttributes:att]; 170 | 171 | tv = (NSTextView *)[self.window fieldEditor:YES forObject:self.subject]; 172 | [tv setSelectedTextAttributes:att]; 173 | */ 174 | } 175 | 176 | - (void)setupNotifications 177 | { 178 | [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(updateSendButton) name:NSControlTextDidChangeNotification object:self.from]; 179 | 180 | [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(updateSendButton) name:NSControlTextDidChangeNotification object:self.to]; 181 | 182 | [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(updateSendButton) name:NSControlTextDidChangeNotification object:self.subject]; 183 | } 184 | 185 | - (void)setBodyString:(NSString *)aString 186 | { 187 | [self.bodyText insertText:aString]; 188 | [self.bodyText setSelectedRange:NSMakeRange(0, 0)]; 189 | } 190 | 191 | /* 192 | NSTextView * fieldEditor = [thePanel fieldEditor:NO forObject:theTextField]; 193 | 194 | NSUInteger text_len = [[fieldEditor string] length]; 195 | [fieldEditor setSelectedRange:(NSRange){text_len, 0}]; 196 | */ 197 | 198 | - (void)setupDefaultValues 199 | { 200 | BMIdentities *ids = [BMClient.sharedBMClient identities]; 201 | BMIdentity *identity = [[ids children] firstObject]; 202 | 203 | if (identity) 204 | { 205 | [self.from setStringValue:identity.address]; 206 | } 207 | } 208 | 209 | - (void)updateWindow 210 | { 211 | // to get widnow to redraw - not sure why we have to do it this way 212 | NSRect r = self.window.frame; 213 | r.size.width ++; 214 | [self.window setFrame:r display:YES]; 215 | //[self.bodyText becomeFirstResponder]; 216 | [self updateSendButton]; 217 | } 218 | 219 | - (void)removeFocusRings 220 | { 221 | [self.from setFocusRingType:NSFocusRingTypeNone]; 222 | [self.to setFocusRingType:NSFocusRingTypeNone]; 223 | [self.subject setFocusRingType:NSFocusRingTypeNone]; 224 | } 225 | 226 | - (NSString *)fromAddress 227 | { 228 | NSString *s = self.from.stringValue; 229 | NSString *address = [BMClient.sharedBMClient identityOrChannelAddressForLabel:s]; 230 | 231 | if (address) 232 | { 233 | s = address; 234 | } 235 | 236 | return s; 237 | } 238 | 239 | - (NSString *)toAddress 240 | { 241 | NSString *s = self.to.stringValue; 242 | NSString *address = [BMClient.sharedBMClient addressForLabel:s]; 243 | 244 | if (address) 245 | { 246 | s = address; 247 | } 248 | 249 | return s; 250 | } 251 | 252 | - (BOOL)canSend 253 | { 254 | return [self hasValidAddresses]; 255 | } 256 | 257 | - (IBAction)send:(id)sender 258 | { 259 | BMMessage *m = [[BMMessage alloc] init]; 260 | [m setFromAddress:self.fromAddress]; 261 | [m setToAddress:self.toAddress]; 262 | [m setSubject:self.subject.stringValue]; 263 | [m setMessage:self.bodyText.string]; 264 | 265 | if (self.isBroadcast) 266 | { 267 | [m broadcast]; 268 | } 269 | else 270 | { 271 | [m send]; 272 | } 273 | 274 | [[[BMClient.sharedBMClient messages] sent] refresh]; 275 | [self close]; 276 | } 277 | 278 | - (void)updateSendButton 279 | { 280 | [self.from setStringValue:self.from.stringValue.strip]; 281 | [self.to setStringValue:self.to.stringValue.strip]; 282 | 283 | if([self canSend]) 284 | { 285 | [self.sendButton setImage:[NSImage imageNamed:@"send_active"]]; 286 | [self.sendButton setEnabled:YES]; 287 | } 288 | else 289 | { 290 | [self.sendButton setImage:[NSImage imageNamed:@"send_inactive"]]; 291 | [self.sendButton setEnabled:NO]; 292 | } 293 | 294 | [self updateNotes]; 295 | } 296 | 297 | - (void)updateNotes 298 | { 299 | NSUInteger max = 40; 300 | 301 | [self.fromNote setStringValue:[self.fromAddress stringAbbreviatedToIndex:max]]; 302 | [self.fromNote setHidden:[self.from.stringValue hasPrefix:@"BM-"] || ![BMAddress isValidAddress:self.fromAddress]]; 303 | 304 | [self.toNote setStringValue:[self.toAddress stringAbbreviatedToIndex:max]]; 305 | [self.toNote setHidden:self.isBroadcast || ![BMAddress isValidAddress:self.toAddress]]; 306 | } 307 | 308 | - (void)open 309 | { 310 | [self setAddressesToLabels]; 311 | [self placeWindow]; 312 | [self updateSendButton]; 313 | [self.scrollView scrollToTop]; 314 | [self.scrollView.window makeKeyAndOrderFront:nil]; 315 | } 316 | 317 | - (void)close 318 | { 319 | [self.window orderOut:self]; 320 | } 321 | 322 | - (BOOL)windowShouldClose:(id)sender 323 | { 324 | [[[self class] drafts] removeObject:self]; 325 | 326 | //[NSNotificationCenter.defaultCenter postNotificationName:@"draftClosed" object:self]; 327 | return YES; 328 | } 329 | 330 | - (void)setCursorForReply 331 | { 332 | NSInteger charIndex = 0; 333 | [self.bodyText setSelectedRange: NSMakeRange(charIndex, 0)]; 334 | [self.scrollView becomeFirstResponder]; 335 | //[self.bodyText becomeFirstResponder]; 336 | } 337 | 338 | - (void)setCursorOnTo 339 | { 340 | [self.to becomeFirstResponder]; 341 | } 342 | 343 | - (void)setCursorOnBody 344 | { 345 | [self setCursorForReply]; 346 | } 347 | 348 | // --- delegate --- 349 | 350 | - (BOOL)hasValidAddresses 351 | { 352 | if (self.isBroadcast) 353 | { 354 | return self.fromCompletor.isValid; 355 | } 356 | 357 | return self.toCompletor.isValid && self.fromCompletor.isValid; 358 | } 359 | 360 | -(void)controlTextDidChange:(NSNotification *)note 361 | { 362 | //NSLog(@"draft controlTextDidChange"); 363 | 364 | NSTextField *field = [note object]; 365 | NSString *address = [field.stringValue strip]; 366 | 367 | if ([BMAddress isValidAddress:address]) 368 | { 369 | [field setThemePath:@"draft/field"]; 370 | } 371 | else 372 | { 373 | field.textColor = [NavTheme.sharedNavTheme formTextErrorColor]; 374 | } 375 | } 376 | 377 | - (void)setDefaultFrom 378 | { 379 | NSString *from = [[[BMClient.sharedBMClient identities] firstIdentity] label]; 380 | 381 | if (from) 382 | { 383 | [self.from setStringValue:from]; 384 | } 385 | } 386 | 387 | - (void)setAddressesToLabels 388 | { 389 | self.to.stringValue = [BMClient.sharedBMClient labelForAddress:self.to.stringValue]; 390 | self.from.stringValue = [BMClient.sharedBMClient labelForAddress:self.from.stringValue]; 391 | } 392 | 393 | - (void)addSubjectPrefix:(NSString *)prefix 394 | { 395 | NSString *subject = self.subject.stringValue; 396 | 397 | if (![subject.lowercaseString hasPrefix:prefix.lowercaseString]) 398 | { 399 | self.subject.stringValue = [prefix stringByAppendingString:subject]; 400 | } 401 | } 402 | 403 | @end 404 | -------------------------------------------------------------------------------- /Bitmessage/resources/xibs/Compose.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 173 | 177 | 178 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | --------------------------------------------------------------------------------