consolidated shared code for LoginCpp

This commit is contained in:
Austin Diviness 2016-04-03 15:17:20 -07:00
Родитель 4c7c1e8e94
Коммит 4b6f88212d
15 изменённых файлов: 682 добавлений и 1155 удалений

Просмотреть файл

@ -0,0 +1,109 @@
//******************************************************************************
//
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
//
// This code is licensed under the MIT License (MIT).
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
//******************************************************************************
#include "pch.h"
#include "Dialogs.xaml.h"
using namespace LoginCpp;
using namespace concurrency;
using namespace winsdkfb;
using namespace Platform;
using namespace Platform::Collections;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::Graphics::Display;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Interop;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
void Dialogs::FeedDialogButton_Click(
Object^ sender,
RoutedEventArgs^ e
)
{
FBSession^ s = FBSession::ActiveSession;
if (!s->LoggedIn)
{
OutputDebugString(L"The user is no longer logged in.\n");
}
else
{
PropertySet^ params = ref new PropertySet();
params->Insert(L"caption", L"I love Brussels Sprouts!");
params->Insert(L"link", L"https://en.wikipedia.org/wiki/Brussels_sprout");
params->Insert(L"description", L"Om Nom Nom!");
create_task(s->ShowFeedDialogAsync(params))
.then([=](FBResult^ Response)
{
OutputDebugString(L"Showed 'Feed' dialog.\n");
});
}
}
void Dialogs::AppRequestsButton_Click(
Object^ sender,
RoutedEventArgs^ e
)
{
FBSession^ s = FBSession::ActiveSession;
if (!s->LoggedIn)
{
OutputDebugString(L"The user is no longer logged in.\n");
}
else
{
PropertySet^ params = ref new PropertySet();
params->Insert(L"title", L"I love Brussels Sprouts!");
params->Insert(L"message", L"Om Nom Nom!");
create_task(s->ShowRequestsDialogAsync(params))
.then([=](FBResult^ Response)
{
OutputDebugString(L"Showed 'Requests' dialog.\n");
});
}
}
void LoginCpp::Dialogs::SendDialogButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
FBSession^ s = FBSession::ActiveSession;
if (!s->LoggedIn)
{
OutputDebugString(L"The user is no longer logged in.\n");
}
else
{
PropertySet^ params = ref new PropertySet();
params->Insert(L"link", L"http://example.com");
create_task(s->ShowSendDialogAsync(params))
.then([=](FBResult^ DialogResponse)
{
OutputDebugString(L"Showed 'Send' dialog.\n");
});
}
}

Просмотреть файл

@ -19,7 +19,11 @@
<ClCompile Include="$(MSBuildThisFileDirectory)App.xaml.cpp">
<DependentUpon>$(MSBuildThisFileDirectory)App.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)Dialogs.Shared.xaml.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)FBPageBindable.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)MainPage.Shared.xaml.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)UserInfo.Shared.xaml.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)UserLikes.Shared.xaml.cpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)App.xaml.h">
<DependentUpon>$(MSBuildThisFileDirectory)App.xaml</DependentUpon>
</ClInclude>

Просмотреть файл

@ -6,6 +6,10 @@
<CLCompile Include="$(MSBuildThisFileDirectory)pch.cpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)pch.h" />
<ClCompile Include="$(MSBuildThisFileDirectory)FBPageBindable.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)MainPage.Shared.xaml.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)Dialogs.Shared.xaml.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)UserInfo.Shared.xaml.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)UserLikes.Shared.xaml.cpp" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="$(MSBuildThisFileDirectory)App.xaml" />

Просмотреть файл

@ -0,0 +1,308 @@
//******************************************************************************
//
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
//
// This code is licensed under the MIT License (MIT).
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
//******************************************************************************
#include "pch.h"
#include "MainPage.xaml.h"
#include "UserInfo.xaml.h"
#include "Dialogs.xaml.h"
using namespace Platform;
using namespace Platform::Collections;
using namespace Windows::ApplicationModel;
using namespace Windows::ApplicationModel::Activation;
using namespace Windows::ApplicationModel::Core;
using namespace Windows::ApplicationModel::Resources;
using namespace Windows::UI::Core;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
using namespace Windows::Globalization::DateTimeFormatting;
using namespace Windows::Security::Authentication::Web;
using namespace winsdkfb;
using namespace concurrency;
using namespace LoginCpp;
#define FBAppIDName L"FBApplicationId"
#define FBStoreAppIDName L"FBWindowsAppId"
#define PermissionGranted L"granted"
const wchar_t* requested_permissions[] =
{
L"public_profile",
L"user_friends",
L"user_likes",
L"user_groups",
L"user_location"
};
MainPage::MainPage()
{
InitializeComponent();
String^ whatever = WebAuthenticationBroker::GetCurrentApplicationCallbackUri()->DisplayUri + L"\n";
OutputDebugString(whatever->Data());
SetSessionAppIds();
}
FBPermissions^ MainPage::BuildPermissions(
)
{
FBPermissions^ result = nullptr;
Vector<String^>^ v = ref new Vector<String^>();
for (unsigned int i = 0; i < ARRAYSIZE(requested_permissions); i++)
{
v->Append(ref new String(requested_permissions[i]));
}
result = ref new FBPermissions(v->GetView());
return result;
}
void MainPage::SetSessionAppIds()
{
FBSession^ s = FBSession::ActiveSession;
// Assumes the Facebook App ID and Windows Phone Store ID have been saved
// in the default resource file.
ResourceLoader^ rl = ResourceLoader::GetForCurrentView();
String^ appId = rl->GetString(FBAppIDName);
String^ winAppId = rl->GetString(FBStoreAppIDName);
// IDs are both sent to FB app, so it can validate us.
s->FBAppId = appId;
s->WinAppId = winAppId;
}
void MainPage::LogoutAndRetry(
)
{
// It's necessary to logout prior to reattempting login, because it could
// be that the session has cached an access token that is no longer valid,
// e.g. if the user revoked the app in Settings. FBSession::Logout clears
// the session's cached access token, among other things.
create_task(FBSession::ActiveSession->LogoutAsync())
.then([=]()
{
// Login call has to happen on UI thread, so circle back around to it
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
Windows::UI::Core::CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler([=]()
{
TryRerequest(TRUE);
}));
});
}
BOOL MainPage::DidGetAllRequestedPermissions(
)
{
BOOL success = FALSE;
FBAccessTokenData^ data = FBSession::ActiveSession->AccessTokenData;
unsigned int grantedCount = 0;
if (data)
{
success = !data->DeclinedPermissions->Values->Size;
}
return success;
}
BOOL MainPage::WasAppPermissionRemovedByUser(
FBResult^ result
)
{
return (result &&
(!result->Succeeded) &&
((result->ErrorInfo->Code == (int)winsdkfb::ErrorCode::ErrorCodeOauthException) &&
(result->ErrorInfo->Subcode == (int)winsdkfb::ErrorSubcode::ErrorSubcodeSessionInvalidated)));
}
BOOL MainPage::ShouldRerequest(
FBResult^ result
)
{
return (result &&
result->Succeeded &&
!DidGetAllRequestedPermissions());
}
void MainPage::TryRerequest(
BOOL retry
)
{
// If we're logged out, the session has cleared the FB and Windows app IDs,
// so they need to be set again. We load these IDs via the ResourceLoader
// class, which must be accessed on the UI thread, which is why this call
// is outside the task context.
SetSessionAppIds();
create_task(FBSession::ActiveSession->LoginAsync(BuildPermissions(), GetLoginBehavior()))
.then([=](FBResult^ result)
{
if (result->Succeeded)
{
if (retry && (!DidGetAllRequestedPermissions()))
{
// Login call has to happen on UI thread, so circle back around to it
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
Windows::UI::Core::CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler([=]()
{
TryRerequest(false);
}));
}
else
{
UpdateXamlControls();
}
}
});
}
void MainPage::login_OnClicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
FBSession^ sess = FBSession::ActiveSession;
if (sess->LoggedIn)
{
sess->LogoutAsync();
LoginButton->Content = L"Logout";
LoginCpp::App^ a = dynamic_cast<LoginCpp::App^>(Application::Current);
Windows::UI::Xaml::Controls::Frame^ f = a->CreateRootFrame();
f->Navigate(MainPage::typeid);
}
else
{
create_task(sess->LoginAsync(BuildPermissions(), GetLoginBehavior())).then([=](FBResult^ result)
{
// There may be other cases where an a failed login request should
// prompt the app to retry login, but this one is common enough that
// it's helpful to demonstrate handling it here. If the predicate
// returns TRUE, the user has gone to facebook.com in the browser,
// and removed our app from their list off allowed apps in Settings.
if (WasAppPermissionRemovedByUser(result))
{
LogoutAndRetry();
}
else if (ShouldRerequest(result))
{
// Login call has to happen on UI thread, so circle back around to it
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
Windows::UI::Core::CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler([=]()
{
TryRerequest(FALSE);
}));
}
else if (result && result->Succeeded)
{
// Got a token, and all the permissions we wanted - go ahead to the options page
UpdateXamlControls();
}
});
}
}
void LoginCpp::MainPage::UserInfoButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
Windows::UI::Core::CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler([this]()
{
LoginCpp::App^ a = dynamic_cast<LoginCpp::App^>(Application::Current);
Windows::UI::Xaml::Controls::Frame^ f = a->CreateRootFrame();
f->Navigate(UserInfo::typeid);
}));
}
void LoginCpp::MainPage::DialogsPageButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
Windows::UI::Core::CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler([this]()
{
LoginCpp::App^ a = dynamic_cast<LoginCpp::App^>(Application::Current);
Windows::UI::Xaml::Controls::Frame^ f = a->CreateRootFrame();
f->Navigate(Dialogs::typeid);
}));
}
void LoginCpp::MainPage::UpdateXamlControls()
{
FBSession^ sess = FBSession::ActiveSession;
if (sess->LoggedIn)
{
LoginButton->Content = L"Logout";
AccessTokenText->Text = sess->AccessTokenData->AccessToken;
DateTimeFormatter^ dateFormatter = ref new DateTimeFormatter(
L"{year.full(4)}-{month.integer(2)}-{day.integer(2)} "
L"{hour.integer(2)}:{minute.integer(2)}:{second.integer(2)}");
ExpirationDateText->Text = dateFormatter->Format(sess->AccessTokenData->ExpirationDate);
UserInfoButton->IsEnabled = true;
DialogsPageButton->IsEnabled = true;
}
else
{
LoginButton->Content = L"Login To FB";
AccessTokenText->Text = L"";
ExpirationDateText->Text = L"";
UserInfoButton->IsEnabled = false;
DialogsPageButton->IsEnabled = false;
}
}
SessionLoginBehavior LoginCpp::MainPage::GetLoginBehavior()
{
ComboBoxItem^ selectedLoginMethod = dynamic_cast<ComboBoxItem^>(LoginMethodComboBox->SelectedItem);
String^ text = dynamic_cast<String^>(selectedLoginMethod->Content);
if (String::CompareOrdinal(text, L"WebView") == 0)
{
return SessionLoginBehavior::WebView;
}
if (String::CompareOrdinal(text, L"WebAuth") == 0)
{
return SessionLoginBehavior::WebAuth;
}
if (String::CompareOrdinal(text, L"WebAccountProvider") == 0)
{
return SessionLoginBehavior::WebAccountProvider;
}
if (String::CompareOrdinal(text, L"DefaultOrdering") == 0)
{
return SessionLoginBehavior::DefaultOrdering;
}
if (String::CompareOrdinal(text, L"Silent") == 0)
{
return SessionLoginBehavior::Silent;
}
throw ref new InvalidArgumentException();
}
void LoginCpp::MainPage::LayoutRoot_Loaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
UpdateXamlControls();
}

Просмотреть файл

@ -0,0 +1,90 @@
//******************************************************************************
//
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
//
// This code is licensed under the MIT License (MIT).
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
//******************************************************************************
#include "pch.h"
#include "UserInfo.xaml.h"
#include "UserLikes.xaml.h"
using namespace LoginCpp;
using namespace winsdkfb;
using namespace winsdkfb::Graph;
using namespace Platform;
using namespace Platform::Collections;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::Graphics::Display;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Interop;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
#pragma region Navigation support
DependencyProperty^ UserInfo::_navigationHelperProperty =
DependencyProperty::Register("NavigationHelper",
TypeName(Common::NavigationHelper::typeid), TypeName(UserInfo::typeid), nullptr);
/// The methods provided in this section are simply used to allow
/// NavigationHelper to respond to the page's navigation methods.
///
/// Page specific logic should be placed in event handlers for the
/// <see cref="NavigationHelper::LoadState"/>
/// and <see cref="NavigationHelper::SaveState"/>.
/// The navigation parameter is available in the LoadState method
/// in addition to page state preserved during an earlier session.
void UserInfo::OnNavigatedTo(NavigationEventArgs^ e)
{
NavigationHelper->OnNavigatedTo(e);
FBSession^ sess = FBSession::ActiveSession;
if (sess->LoggedIn)
{
FBUser^ user = sess->User;
if (user)
{
UserId->Text = user->Id;
UserFirstName->Text = user->FirstName;
UserGender->Text = user->Gender;
UserLastName->Text = user->LastName;
UserLink->Text = user->Link;
UserLocale->Text = user->Locale;
UserName->Text = user->Name;
UserTimezone->Text = user->Timezone.ToString();
UserUpdatedTime->Text = user->UpdatedTime;
UserVerified->Text = user->Verified.ToString();
SquarePicture->UserId = user->Id;
}
}
}
void UserInfo::OnNavigatedFrom(NavigationEventArgs^ e)
{
NavigationHelper->OnNavigatedFrom(e);
}
#pragma endregion
void LoginCpp::UserInfo::UserLikesButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
LoginCpp::App^ a = dynamic_cast<LoginCpp::App^>(Application::Current);
Windows::UI::Xaml::Controls::Frame^ f = a->CreateRootFrame();
f->Navigate(UserLikes::typeid);
}

Просмотреть файл

@ -0,0 +1,162 @@
//******************************************************************************
//
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
//
// This code is licensed under the MIT License (MIT).
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
//******************************************************************************
#include "pch.h"
#include "UserLikes.xaml.h"
using namespace LoginCpp;
using namespace concurrency;
using namespace Platform;
using namespace Platform::Collections;
using namespace Windows::ApplicationModel::Core;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
using namespace winsdkfb;
using namespace winsdkfb::Graph;
IVector<FBPageBindable^>^ UserLikes::Items::get()
{
return _listViewItems;
}
FBPageBindable^ UserLikes::SelectedItem::get()
{
return _selectedItem;
}
void UserLikes::AddLikes(
IVectorView<Object^>^ NewLikes
)
{
for (IIterator<Object^>^ it = NewLikes->First(); it->HasCurrent; it->MoveNext())
{
FBPageBindable^ page = static_cast<FBPageBindable^>(it->Current);
if (page)
{
String^ msg = L"Found page: " + page->Name + "\n";
OutputDebugString(msg->Data());
_listViewItems->Append(page);
}
}
// go through the paginated calls here so that we don't have to deal with task chaining
if (_likes->HasNext)
{
create_task(_likes->NextAsync()).then([this](FBResult^ result)
{
if (result->Succeeded)
{
IVectorView<Object^>^ items = static_cast<IVectorView<Object^>^> (result->Object);
if (items->Size > 0)
{
AddLikes(items);
}
}
});
}
}
void UserLikes::GetUserLikes(
)
{
FBSession^ sess = FBSession::ActiveSession;
if (sess->LoggedIn)
{
String^ graphPath = sess->User->Id + L"/likes";
FBJsonClassFactory^ fact =
ref new FBJsonClassFactory([](String^ JsonText) -> Object^
{
return FBPageBindable::FromJson(JsonText);
});
_likes = ref new FBPaginatedArray(graphPath, nullptr, fact);
create_task(_likes->FirstAsync()).then([this](FBResult^ result)
{
if (result->Succeeded)
{
BadResultsTextBlock->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
LikesListView->Visibility = Windows::UI::Xaml::Visibility::Visible;
IVectorView<Object^>^ items = static_cast<IVectorView<Object^>^> (result->Object);
if (items->Size > 0)
{
AddLikes(items);
}
else
{
LikesListView->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
BadResultsTextBlock->Visibility = Windows::UI::Xaml::Visibility::Visible;
BadResultsTextBlock->Text = L"No User likes found";
}
}
else
{
LikesListView->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
BadResultsTextBlock->Visibility = Windows::UI::Xaml::Visibility::Visible;
BadResultsTextBlock->Text = result->ErrorInfo->Message;
}
});
}
}
void UserLikes::ListView_SelectionChanged(
Object^ sender,
SelectionChangedEventArgs^ e
)
{
FBPageBindable^ selected = static_cast<FBPageBindable^>(e->AddedItems->GetAt(0));
if (selected)
{
FBSingleValue^ val = ref new FBSingleValue(L"/" + selected->Id,
nullptr,
ref new FBJsonClassFactory([](String^ JsonText) -> Object^
{
return FBPageBindable::FromJson(JsonText);
}));
create_task(val->GetAsync())
.then([this](FBResult^ result)
{
if (result->Succeeded)
{
_selectedItem = static_cast<FBPageBindable^>(result->Object);
NotifyPropertyChanged("SelectedItem");
}
});
}
}
void UserLikes::NotifyPropertyChanged(
String^ prop
)
{
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
Windows::UI::Core::CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler([this, prop]()
{
PropertyChangedEventArgs^ args = ref new PropertyChangedEventArgs(prop);
PropertyChanged(this, args);
}));
}

Просмотреть файл

@ -14,11 +14,6 @@
//
//******************************************************************************
//
// Dialogs.xaml.cpp
// Implementation of the Dialogs class
//
#include "pch.h"
#include "Dialogs.xaml.h"
@ -37,82 +32,11 @@ using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
Dialogs::Dialogs()
{
InitializeComponent();
}
void LoginCpp::Dialogs::FeedDialogButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
FBSession^ s = FBSession::ActiveSession;
if (!s->LoggedIn)
{
OutputDebugString(L"The user is no longer logged in.\n");
}
else
{
PropertySet^ params = ref new PropertySet();
params->Insert(L"caption", L"I love Brussels Sprouts!");
params->Insert(L"link", L"https://en.wikipedia.org/wiki/Brussels_sprout");
params->Insert(L"description", L"Om Nom Nom!");
create_task(s->ShowFeedDialogAsync(params))
.then([=](FBResult^ Response)
{
OutputDebugString(L"Showed 'Feed' dialog.\n");
});
}
}
void LoginCpp::Dialogs::AppRequestsButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
FBSession^ s = FBSession::ActiveSession;
if (!s->LoggedIn)
{
OutputDebugString(L"The user is no longer logged in.\n");
}
else
{
PropertySet^ params = ref new PropertySet();
params->Insert(L"title", L"I love Brussels Sprouts!");
params->Insert(L"message", L"Om Nom Nom!");
create_task(s->ShowRequestsDialogAsync(params))
.then([=](FBResult^ Response)
{
OutputDebugString(L"Showed 'Requests' dialog.\n");
});
}
}
void LoginCpp::Dialogs::SendDialogButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
FBSession^ s = FBSession::ActiveSession;
if (!s->LoggedIn)
{
OutputDebugString(L"The user is no longer logged in.\n");
}
else
{
PropertySet^ params = ref new PropertySet();
params->Insert(L"link", L"http://example.com");
create_task(s->ShowSendDialogAsync(params))
.then([=](FBResult^ DialogResponse)
{
OutputDebugString(L"Showed 'Send' dialog.\n");
});
}
}
void LoginCpp::Dialogs::BackButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
if (Frame->CanGoBack)

Просмотреть файл

@ -14,303 +14,4 @@
//
//******************************************************************************
//
// MainPage.xaml.cpp
// Implementation of the MainPage class.
//
#include "pch.h"
#include "MainPage.xaml.h"
#include "Dialogs.xaml.h"
#include "UserInfo.xaml.h"
using namespace concurrency;
using namespace winsdkfb;
using namespace LoginCpp;
using namespace Platform;
using namespace Platform::Collections;
using namespace Windows::ApplicationModel;
using namespace Windows::ApplicationModel::Activation;
using namespace Windows::ApplicationModel::Core;
using namespace Windows::ApplicationModel::Resources;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::Security::Authentication::Web;
using namespace Windows::UI::Core;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
using namespace Windows::Globalization::DateTimeFormatting;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
#define FBAppIDName L"FBApplicationId"
#define FBStoreAppIDName L"FBWindowsAppId"
#define PermissionGranted L"granted"
const wchar_t* requested_permissions[] =
{
L"public_profile",
L"user_friends",
L"user_likes",
L"user_groups",
L"user_location"
};
MainPage::MainPage()
{
InitializeComponent();
String^ whatever = WebAuthenticationBroker::GetCurrentApplicationCallbackUri()->DisplayUri + L"\n";
OutputDebugString(whatever->Data());
SetSessionAppIds();
}
void MainPage::SetSessionAppIds()
{
FBSession^ s = FBSession::ActiveSession;
// Assumes the Facebook App ID and Windows Phone Store ID have been saved
// in the default resource file.
ResourceLoader^ rl = ResourceLoader::GetForCurrentView();
String^ appId = rl->GetString(FBAppIDName);
String^ winAppId = rl->GetString(FBStoreAppIDName);
// IDs are both sent to FB app, so it can validate us.
s->FBAppId = appId;
s->WinAppId = winAppId;
}
FBPermissions^ MainPage::BuildPermissions(
)
{
FBPermissions^ result = nullptr;
Vector<String^>^ v = ref new Vector<String^>();
for (unsigned int i = 0; i < ARRAYSIZE(requested_permissions); i++)
{
v->Append(ref new String(requested_permissions[i]));
}
result = ref new FBPermissions(v->GetView());
return result;
}
BOOL MainPage::DidGetAllRequestedPermissions(
)
{
BOOL success = FALSE;
FBAccessTokenData^ data = FBSession::ActiveSession->AccessTokenData;
unsigned int grantedCount = 0;
if (data)
{
success = !data->DeclinedPermissions->Values->Size;
}
return success;
}
BOOL MainPage::WasAppPermissionRemovedByUser(
FBResult^ result
)
{
return (result &&
(!result->Succeeded) &&
((result->ErrorInfo->Code == (int)winsdkfb::ErrorCode::ErrorCodeOauthException) &&
(result->ErrorInfo->Subcode == (int)winsdkfb::ErrorSubcode::ErrorSubcodeSessionInvalidated)));
}
BOOL MainPage::ShouldRerequest(
FBResult^ result
)
{
return (result &&
result->Succeeded &&
!DidGetAllRequestedPermissions());
}
void MainPage::TryRerequest(
BOOL retry
)
{
// If we're logged out, the session has cleared the FB and Windows app IDs,
// so they need to be set again. We load these IDs via the ResourceLoader
// class, which must be accessed on the UI thread, which is why this call
// is outside the task context.
SetSessionAppIds();
create_task(FBSession::ActiveSession->LoginAsync(BuildPermissions(), GetLoginBehavior()))
.then([=](FBResult^ result)
{
if (result->Succeeded)
{
if (retry && (!DidGetAllRequestedPermissions()))
{
// Login call has to happen on UI thread, so circle back around to it
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
Windows::UI::Core::CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler([=]()
{
TryRerequest(false);
}));
}
else
{
UpdateXamlControls();
}
}
});
}
void MainPage::LogoutAndRetry(
)
{
// It's necessary to logout prior to reattempting login, because it could
// be that the session has cached an access token that is no longer valid,
// e.g. if the user revoked the app in Settings. FBSession::Logout clears
// the session's cached access token, among other things.
create_task(FBSession::ActiveSession->LogoutAsync())
.then([=]()
{
// Login call has to happen on UI thread, so circle back around to it
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
Windows::UI::Core::CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler([=]()
{
TryRerequest(TRUE);
}));
});
}
void MainPage::login_OnClicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
FBSession^ sess = FBSession::ActiveSession;
if (sess->LoggedIn)
{
sess->LogoutAsync();
LoginButton->Content = L"Logout";
LoginCpp::App^ a = dynamic_cast<LoginCpp::App^>(Application::Current);
Windows::UI::Xaml::Controls::Frame^ f = a->CreateRootFrame();
f->Navigate(MainPage::typeid);
}
else
{
create_task(sess->LoginAsync(BuildPermissions(), GetLoginBehavior())).then([=](FBResult^ result)
{
// There may be other cases where an a failed login request should
// prompt the app to retry login, but this one is common enough that
// it's helpful to demonstrate handling it here. If the predicate
// returns TRUE, the user has gone to facebook.com in the browser,
// and removed our app from their list off allowed apps in Settings.
if (WasAppPermissionRemovedByUser(result))
{
LogoutAndRetry();
}
else if (ShouldRerequest(result))
{
// Login call has to happen on UI thread, so circle back around to it
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
Windows::UI::Core::CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler([=]()
{
TryRerequest(FALSE);
}));
}
else if (result && result->Succeeded)
{
UpdateXamlControls();
}
});
}
}
void LoginCpp::MainPage::UserInfoButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
Windows::UI::Core::CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler([this]()
{
LoginCpp::App^ a = dynamic_cast<LoginCpp::App^>(Application::Current);
Windows::UI::Xaml::Controls::Frame^ f = a->CreateRootFrame();
f->Navigate(UserInfo::typeid);
}));
}
void LoginCpp::MainPage::DialogsPageButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
Windows::UI::Core::CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler([this]()
{
LoginCpp::App^ a = dynamic_cast<LoginCpp::App^>(Application::Current);
Windows::UI::Xaml::Controls::Frame^ f = a->CreateRootFrame();
f->Navigate(Dialogs::typeid);
}));
}
void LoginCpp::MainPage::UpdateXamlControls()
{
FBSession^ sess = FBSession::ActiveSession;
if (sess->LoggedIn)
{
LoginButton->Content = L"Logout";
AccessTokenText->Text = sess->AccessTokenData->AccessToken;
DateTimeFormatter^ dateFormatter = ref new DateTimeFormatter(
L"{year.full(4)}-{month.integer(2)}-{day.integer(2)} "
L"{hour.integer(2)}:{minute.integer(2)}:{second.integer(2)}");
ExpirationDateText->Text = dateFormatter->Format(sess->AccessTokenData->ExpirationDate);
UserInfoButton->IsEnabled = true;
DialogsPageButton->IsEnabled = true;
}
else
{
LoginButton->Content = L"Login To FB";
AccessTokenText->Text = L"";
ExpirationDateText->Text = L"";
UserInfoButton->IsEnabled = false;
DialogsPageButton->IsEnabled = false;
}
}
SessionLoginBehavior MainPage::GetLoginBehavior()
{
ComboBoxItem^ selectedLoginMethod = dynamic_cast<ComboBoxItem^>(LoginMethodComboBox->SelectedItem);
String^ text = dynamic_cast<String^>(selectedLoginMethod->Content);
if (String::CompareOrdinal(text, L"WebView") == 0)
{
return SessionLoginBehavior::WebView;
}
if (String::CompareOrdinal(text, L"WebAuth") == 0)
{
return SessionLoginBehavior::WebAuth;
}
if (String::CompareOrdinal(text, L"WebAccountProvider") == 0)
{
return SessionLoginBehavior::WebAccountProvider;
}
if (String::CompareOrdinal(text, L"DefaultOrdering") == 0)
{
return SessionLoginBehavior::DefaultOrdering;
}
if (String::CompareOrdinal(text, L"Silent") == 0)
{
return SessionLoginBehavior::Silent;
}
throw ref new InvalidArgumentException();
}
void LoginCpp::MainPage::LayoutRoot_Loaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
UpdateXamlControls();
}
#include "pch.h"

Просмотреть файл

@ -74,51 +74,6 @@ Common::NavigationHelper^ UserInfo::NavigationHelper::get()
return safe_cast<Common::NavigationHelper^>(GetValue(_navigationHelperProperty));
}
#pragma region Navigation support
DependencyProperty^ UserInfo::_navigationHelperProperty =
DependencyProperty::Register("NavigationHelper",
TypeName(Common::NavigationHelper::typeid), TypeName(UserInfo::typeid), nullptr);
/// The methods provided in this section are simply used to allow
/// NavigationHelper to respond to the page's navigation methods.
///
/// Page specific logic should be placed in event handlers for the
/// <see cref="NavigationHelper::LoadState"/>
/// and <see cref="NavigationHelper::SaveState"/>.
/// The navigation parameter is available in the LoadState method
/// in addition to page state preserved during an earlier session.
void UserInfo::OnNavigatedTo(NavigationEventArgs^ e)
{
NavigationHelper->OnNavigatedTo(e);
FBSession^ sess = FBSession::ActiveSession;
if (sess->LoggedIn)
{
FBUser^ user = sess->User;
if (user)
{
UserId->Text = user->Id;
UserFirstName->Text = user->FirstName;
UserGender->Text = user->Gender;
UserLastName->Text = user->LastName;
UserLink->Text = user->Link;
UserLocale->Text = user->Locale;
UserName->Text = user->Name;
UserTimezone->Text = user->Timezone.ToString();
UserUpdatedTime->Text = user->UpdatedTime;
UserVerified->Text = user->Verified.ToString();
SquarePicture->UserId = user->Id;
}
}
}
void UserInfo::OnNavigatedFrom(NavigationEventArgs^ e)
{
NavigationHelper->OnNavigatedFrom(e);
}
#pragma endregion
/// <summary>
/// Populates the page with content passed during navigation. Any saved state is also
@ -150,15 +105,6 @@ void UserInfo::SaveState(Object^ sender, Common::SaveStateEventArgs^ e){
(void)e; // Unused parameter
}
void LoginCpp::UserInfo::UserLikesButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
LoginCpp::App^ a = dynamic_cast<LoginCpp::App^>(Application::Current);
Windows::UI::Xaml::Controls::Frame^ f = a->CreateRootFrame();
f->Navigate(UserLikes::typeid);
}
void LoginCpp::UserInfo::BackButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
if (Frame->CanGoBack)

Просмотреть файл

@ -14,11 +14,6 @@
//
//******************************************************************************
//
// UserLikes.xaml.cpp
// Implementation of the UserLikes class
//
#include "pch.h"
#include "UserLikes.xaml.h"
@ -40,8 +35,6 @@ using namespace Windows::UI::Xaml::Navigation;
using namespace winsdkfb;
using namespace winsdkfb::Graph;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
UserLikes::UserLikes() :
_selectedItem(nullptr)
{
@ -51,131 +44,6 @@ UserLikes::UserLikes() :
GetUserLikes();
}
IVector<FBPageBindable^>^ UserLikes::Items::get()
{
return _listViewItems;
}
FBPageBindable^ UserLikes::SelectedItem::get()
{
return _selectedItem;
}
void UserLikes::AddLikes(
IVectorView<Object^>^ NewLikes
)
{
for (IIterator<Object^>^ it = NewLikes->First(); it->HasCurrent; it->MoveNext())
{
FBPageBindable^ page = static_cast<FBPageBindable^>(it->Current);
if (page)
{
String^ msg = L"Found page: " + page->Name + "\n";
OutputDebugString(msg->Data());
_listViewItems->Append(page);
}
}
// go through the paginated calls here so that we don't have to deal with task chaining
if (_likes->HasNext)
{
create_task(_likes->NextAsync()).then([this](FBResult^ result)
{
if (result->Succeeded)
{
IVectorView<Object^>^ items = static_cast<IVectorView<Object^>^> (result->Object);
if (items->Size > 0)
{
AddLikes(items);
}
}
});
}
}
void UserLikes::GetUserLikes(
)
{
FBSession^ sess = FBSession::ActiveSession;
if (sess->LoggedIn)
{
String^ graphPath = sess->User->Id + L"/likes";
FBJsonClassFactory^ fact =
ref new FBJsonClassFactory([](String^ JsonText) -> Object^
{
return FBPageBindable::FromJson(JsonText);
});
_likes = ref new FBPaginatedArray(graphPath, nullptr, fact);
create_task(_likes->FirstAsync()).then([this](FBResult^ result)
{
if (result->Succeeded)
{
BadResultsTextBlock->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
LikesListView->Visibility = Windows::UI::Xaml::Visibility::Visible;
IVectorView<Object^>^ items = static_cast<IVectorView<Object^>^> (result->Object);
if (items->Size > 0)
{
AddLikes(items);
}
else
{
LikesListView->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
BadResultsTextBlock->Visibility = Windows::UI::Xaml::Visibility::Visible;
BadResultsTextBlock->Text = L"No User likes found";
}
}
else
{
LikesListView->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
BadResultsTextBlock->Visibility = Windows::UI::Xaml::Visibility::Visible;
BadResultsTextBlock->Text = result->ErrorInfo->Message;
}
});
}
}
void UserLikes::ListView_SelectionChanged(
Object^ sender,
SelectionChangedEventArgs^ e
)
{
FBPageBindable^ selected = static_cast<FBPageBindable^>(e->AddedItems->GetAt(0));
if (selected)
{
FBSingleValue^ val = ref new FBSingleValue(L"/" + selected->Id,
nullptr,
ref new FBJsonClassFactory([](String^ JsonText) -> Object^
{
return FBPageBindable::FromJson(JsonText);
}));
create_task(val->GetAsync())
.then([this](FBResult^ result)
{
if (result->Succeeded)
{
_selectedItem = static_cast<FBPageBindable^>(result->Object);
NotifyPropertyChanged("SelectedItem");
}
});
}
}
void UserLikes::NotifyPropertyChanged(
String^ prop
)
{
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
Windows::UI::Core::CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler([this, prop]()
{
PropertyChangedEventArgs^ args = ref new PropertyChangedEventArgs(prop);
PropertyChanged(this, args);
}));
}
void LoginCpp::UserLikes::BackButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{

Просмотреть файл

@ -1,4 +1,5 @@
//******************************************************************************

//******************************************************************************
//
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
//
@ -14,11 +15,6 @@
//
//******************************************************************************
//
// Dialogs.xaml.cpp
// Implementation of the Dialogs class
//
#include "pch.h"
#include "Dialogs.xaml.h"
@ -40,8 +36,6 @@ using namespace Windows::UI::Xaml::Interop;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
// The Basic Page item template is documented at http://go.microsoft.com/fwlink/?LinkID=390556
Dialogs::Dialogs()
{
InitializeComponent();
@ -129,77 +123,3 @@ void Dialogs::SaveState(Object^ sender, Common::SaveStateEventArgs^ e) {
(void)sender; // Unused parameter
(void)e; // Unused parameter
}
void Dialogs::FeedDialogButton_Click(
Object^ sender,
RoutedEventArgs^ e
)
{
FBSession^ s = FBSession::ActiveSession;
if (!s->LoggedIn)
{
OutputDebugString(L"The user is no longer logged in.\n");
}
else
{
PropertySet^ params = ref new PropertySet();
params->Insert(L"caption", L"I love Brussels Sprouts!");
params->Insert(L"link", L"https://en.wikipedia.org/wiki/Brussels_sprout");
params->Insert(L"description", L"Om Nom Nom!");
create_task(s->ShowFeedDialogAsync(params))
.then([=](FBResult^ Response)
{
OutputDebugString(L"Showed 'Feed' dialog.\n");
});
}
}
void Dialogs::AppRequestsButton_Click(
Object^ sender,
RoutedEventArgs^ e
)
{
FBSession^ s = FBSession::ActiveSession;
if (!s->LoggedIn)
{
OutputDebugString(L"The user is no longer logged in.\n");
}
else
{
PropertySet^ params = ref new PropertySet();
params->Insert(L"title", L"I love Brussels Sprouts!");
params->Insert(L"message", L"Om Nom Nom!");
create_task(s->ShowRequestsDialogAsync(params))
.then([=](FBResult^ Response)
{
OutputDebugString(L"Showed 'Requests' dialog.\n");
});
}
}
void LoginCpp::Dialogs::SendDialogButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
FBSession^ s = FBSession::ActiveSession;
if (!s->LoggedIn)
{
OutputDebugString(L"The user is no longer logged in.\n");
}
else
{
PropertySet^ params = ref new PropertySet();
params->Insert(L"link", L"http://example.com");
create_task(s->ShowSendDialogAsync(params))
.then([=](FBResult^ DialogResponse)
{
OutputDebugString(L"Showed 'Send' dialog.\n");
});
}
}

Просмотреть файл

@ -14,304 +14,4 @@
//
//******************************************************************************
//
// MainPage.xaml.cpp
// Implementation of the MainPage class.
//
#include "pch.h"
#include "MainPage.xaml.h"
#include "UserInfo.xaml.h"
#include "Dialogs.xaml.h"
using namespace concurrency;
using namespace winsdkfb;
using namespace LoginCpp;
using namespace Platform;
using namespace Platform::Collections;
using namespace Windows::ApplicationModel;
using namespace Windows::ApplicationModel::Activation;
using namespace Windows::ApplicationModel::Core;
using namespace Windows::ApplicationModel::Resources;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::Security::Authentication::Web;
using namespace Windows::UI::Core;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
using namespace Windows::Globalization::DateTimeFormatting;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
#define FBAppIDName L"FBApplicationId"
#define FBStoreAppIDName L"FBWindowsAppId"
#define PermissionGranted L"granted"
const wchar_t* requested_permissions[] =
{
L"public_profile",
L"user_friends",
L"user_likes",
L"user_groups",
L"user_location"
};
MainPage::MainPage()
{
InitializeComponent();
String^ whatever = WebAuthenticationBroker::GetCurrentApplicationCallbackUri()->DisplayUri + L"\n";
OutputDebugString(whatever->Data());
SetSessionAppIds();
}
void MainPage::SetSessionAppIds()
{
FBSession^ s = FBSession::ActiveSession;
// Assumes the Facebook App ID and Windows Phone Store ID have been saved
// in the default resource file.
ResourceLoader^ rl = ResourceLoader::GetForCurrentView();
String^ appId = rl->GetString(FBAppIDName);
String^ winAppId = rl->GetString(FBStoreAppIDName);
// IDs are both sent to FB app, so it can validate us.
s->FBAppId = appId;
s->WinAppId = winAppId;
}
FBPermissions^ MainPage::BuildPermissions(
)
{
FBPermissions^ result = nullptr;
Vector<String^>^ v = ref new Vector<String^>();
for (unsigned int i = 0; i < ARRAYSIZE(requested_permissions); i++)
{
v->Append(ref new String(requested_permissions[i]));
}
result = ref new FBPermissions(v->GetView());
return result;
}
BOOL MainPage::DidGetAllRequestedPermissions(
)
{
BOOL success = FALSE;
FBAccessTokenData^ data = FBSession::ActiveSession->AccessTokenData;
unsigned int grantedCount = 0;
if (data)
{
success = !data->DeclinedPermissions->Values->Size;
}
return success;
}
BOOL MainPage::WasAppPermissionRemovedByUser(
FBResult^ result
)
{
return (result &&
(!result->Succeeded) &&
((result->ErrorInfo->Code == (int)winsdkfb::ErrorCode::ErrorCodeOauthException) &&
(result->ErrorInfo->Subcode == (int)winsdkfb::ErrorSubcode::ErrorSubcodeSessionInvalidated)));
}
BOOL MainPage::ShouldRerequest(
FBResult^ result
)
{
return (result &&
result->Succeeded &&
!DidGetAllRequestedPermissions());
}
void MainPage::TryRerequest(
BOOL retry
)
{
// If we're logged out, the session has cleared the FB and Windows app IDs,
// so they need to be set again. We load these IDs via the ResourceLoader
// class, which must be accessed on the UI thread, which is why this call
// is outside the task context.
SetSessionAppIds();
create_task(FBSession::ActiveSession->LoginAsync(BuildPermissions(), GetLoginBehavior()))
.then([=](FBResult^ result)
{
if (result->Succeeded)
{
if (retry && (!DidGetAllRequestedPermissions()))
{
// Login call has to happen on UI thread, so circle back around to it
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
Windows::UI::Core::CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler([=]()
{
TryRerequest(false);
}));
}
else
{
UpdateXamlControls();
}
}
});
}
void MainPage::LogoutAndRetry(
)
{
// It's necessary to logout prior to reattempting login, because it could
// be that the session has cached an access token that is no longer valid,
// e.g. if the user revoked the app in Settings. FBSession::Logout clears
// the session's cached access token, among other things.
create_task(FBSession::ActiveSession->LogoutAsync())
.then([=]()
{
// Login call has to happen on UI thread, so circle back around to it
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
Windows::UI::Core::CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler([=]()
{
TryRerequest(TRUE);
}));
});
}
void MainPage::login_OnClicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
FBSession^ sess = FBSession::ActiveSession;
if (sess->LoggedIn)
{
sess->LogoutAsync();
LoginButton->Content = L"Logout";
LoginCpp::App^ a = dynamic_cast<LoginCpp::App^>(Application::Current);
Windows::UI::Xaml::Controls::Frame^ f = a->CreateRootFrame();
f->Navigate(MainPage::typeid);
}
else
{
create_task(sess->LoginAsync(BuildPermissions(), GetLoginBehavior())).then([=](FBResult^ result)
{
// There may be other cases where an a failed login request should
// prompt the app to retry login, but this one is common enough that
// it's helpful to demonstrate handling it here. If the predicate
// returns TRUE, the user has gone to facebook.com in the browser,
// and removed our app from their list off allowed apps in Settings.
if (WasAppPermissionRemovedByUser(result))
{
LogoutAndRetry();
}
else if (ShouldRerequest(result))
{
// Login call has to happen on UI thread, so circle back around to it
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
Windows::UI::Core::CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler([=]()
{
TryRerequest(FALSE);
}));
}
else if (result && result->Succeeded)
{
// Got a token, and all the permissions we wanted - go ahead to the options page
UpdateXamlControls();
}
});
}
}
void LoginCpp::MainPage::UserInfoButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
Windows::UI::Core::CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler([this]()
{
LoginCpp::App^ a = dynamic_cast<LoginCpp::App^>(Application::Current);
Windows::UI::Xaml::Controls::Frame^ f = a->CreateRootFrame();
f->Navigate(UserInfo::typeid);
}));
}
void LoginCpp::MainPage::DialogsPageButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
Windows::UI::Core::CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler([this]()
{
LoginCpp::App^ a = dynamic_cast<LoginCpp::App^>(Application::Current);
Windows::UI::Xaml::Controls::Frame^ f = a->CreateRootFrame();
f->Navigate(Dialogs::typeid);
}));
}
void LoginCpp::MainPage::UpdateXamlControls()
{
FBSession^ sess = FBSession::ActiveSession;
if (sess->LoggedIn)
{
LoginButton->Content = L"Logout";
AccessTokenText->Text = sess->AccessTokenData->AccessToken;
DateTimeFormatter^ dateFormatter = ref new DateTimeFormatter(
L"{year.full(4)}-{month.integer(2)}-{day.integer(2)} "
L"{hour.integer(2)}:{minute.integer(2)}:{second.integer(2)}");
ExpirationDateText->Text = dateFormatter->Format(sess->AccessTokenData->ExpirationDate);
UserInfoButton->IsEnabled = true;
DialogsPageButton->IsEnabled = true;
}
else
{
LoginButton->Content = L"Login To FB";
AccessTokenText->Text = L"";
ExpirationDateText->Text = L"";
UserInfoButton->IsEnabled = false;
DialogsPageButton->IsEnabled = false;
}
}
SessionLoginBehavior MainPage::GetLoginBehavior()
{
ComboBoxItem^ selectedLoginMethod = dynamic_cast<ComboBoxItem^>(LoginMethodComboBox->SelectedItem);
String^ text = dynamic_cast<String^>(selectedLoginMethod->Content);
if (String::CompareOrdinal(text, L"WebView") == 0)
{
return SessionLoginBehavior::WebView;
}
if (String::CompareOrdinal(text, L"WebAuth") == 0)
{
return SessionLoginBehavior::WebAuth;
}
if (String::CompareOrdinal(text, L"WebAccountProvider") == 0)
{
return SessionLoginBehavior::WebAccountProvider;
}
if (String::CompareOrdinal(text, L"DefaultOrdering") == 0)
{
return SessionLoginBehavior::DefaultOrdering;
}
if (String::CompareOrdinal(text, L"Silent") == 0)
{
return SessionLoginBehavior::Silent;
}
throw ref new InvalidArgumentException();
}
void LoginCpp::MainPage::LayoutRoot_Loaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
UpdateXamlControls();
}
#include "pch.h"

Просмотреть файл

@ -14,17 +14,11 @@
//
//******************************************************************************
//
// UserInfo.xaml.cpp
// Implementation of the UserInfo class
//
#include "pch.h"
#include "UserInfo.xaml.h"
#include "UserLikes.xaml.h"
using namespace LoginCpp;
using namespace winsdkfb;
using namespace winsdkfb::Graph;
using namespace Platform;
@ -74,51 +68,7 @@ Common::NavigationHelper^ UserInfo::NavigationHelper::get()
return safe_cast<Common::NavigationHelper^>(GetValue(_navigationHelperProperty));
}
#pragma region Navigation support
DependencyProperty^ UserInfo::_navigationHelperProperty =
DependencyProperty::Register("NavigationHelper",
TypeName(Common::NavigationHelper::typeid), TypeName(UserInfo::typeid), nullptr);
/// The methods provided in this section are simply used to allow
/// NavigationHelper to respond to the page's navigation methods.
///
/// Page specific logic should be placed in event handlers for the
/// <see cref="NavigationHelper::LoadState"/>
/// and <see cref="NavigationHelper::SaveState"/>.
/// The navigation parameter is available in the LoadState method
/// in addition to page state preserved during an earlier session.
void UserInfo::OnNavigatedTo(NavigationEventArgs^ e)
{
NavigationHelper->OnNavigatedTo(e);
FBSession^ sess = FBSession::ActiveSession;
if (sess->LoggedIn)
{
FBUser^ user = sess->User;
if (user)
{
UserId->Text = user->Id;
UserFirstName->Text = user->FirstName;
UserGender->Text = user->Gender;
UserLastName->Text = user->LastName;
UserLink->Text = user->Link;
UserLocale->Text = user->Locale;
UserName->Text = user->Name;
UserTimezone->Text = user->Timezone.ToString();
UserUpdatedTime->Text = user->UpdatedTime;
UserVerified->Text = user->Verified.ToString();
SquarePicture->UserId = user->Id;
}
}
}
void UserInfo::OnNavigatedFrom(NavigationEventArgs^ e)
{
NavigationHelper->OnNavigatedFrom(e);
}
#pragma endregion
/// <summary>
/// Populates the page with content passed during navigation. Any saved state is also
@ -149,20 +99,3 @@ void UserInfo::SaveState(Object^ sender, Common::SaveStateEventArgs^ e){
(void)sender; // Unused parameter
(void)e; // Unused parameter
}
void LoginCpp::UserInfo::UserLikesButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
LoginCpp::App^ a = dynamic_cast<LoginCpp::App^>(Application::Current);
Windows::UI::Xaml::Controls::Frame^ f = a->CreateRootFrame();
f->Navigate(UserLikes::typeid);
}
void LoginCpp::UserInfo::BackButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
if (Frame->CanGoBack)
{
Frame->GoBack();
}
}

Просмотреть файл

@ -65,7 +65,6 @@ namespace LoginCpp
void Button_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void UserLikesButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void UserGroupsButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void BackButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
};
}

Просмотреть файл

@ -14,11 +14,6 @@
//
//******************************************************************************
//
// UserLikes.xaml.cpp
// Implementation of the UserLikes class
//
#include "pch.h"
#include "UserLikes.xaml.h"
@ -40,8 +35,6 @@ using namespace Windows::UI::Xaml::Navigation;
using namespace winsdkfb;
using namespace winsdkfb::Graph;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
UserLikes::UserLikes() :
_selectedItem(nullptr)
{
@ -49,138 +42,4 @@ UserLikes::UserLikes() :
_listViewItems = ref new Vector<FBPageBindable^>(0);
DataContext = this;
GetUserLikes();
}
IVector<FBPageBindable^>^ UserLikes::Items::get()
{
return _listViewItems;
}
FBPageBindable^ UserLikes::SelectedItem::get()
{
return _selectedItem;
}
void UserLikes::AddLikes(
IVectorView<Object^>^ NewLikes
)
{
for (IIterator<Object^>^ it = NewLikes->First(); it->HasCurrent; it->MoveNext())
{
FBPageBindable^ page = static_cast<FBPageBindable^>(it->Current);
if (page)
{
String^ msg = L"Found page: " + page->Name + "\n";
OutputDebugString(msg->Data());
_listViewItems->Append(page);
}
}
// go through the paginated calls here so that we don't have to deal with task chaining
if (_likes->HasNext)
{
create_task(_likes->NextAsync()).then([this](FBResult^ result)
{
if (result->Succeeded)
{
IVectorView<Object^>^ items = static_cast<IVectorView<Object^>^> (result->Object);
if (items->Size > 0)
{
AddLikes(items);
}
}
});
}
}
void UserLikes::GetUserLikes(
)
{
FBSession^ sess = FBSession::ActiveSession;
if (sess->LoggedIn)
{
String^ graphPath = sess->User->Id + L"/likes";
FBJsonClassFactory^ fact =
ref new FBJsonClassFactory([](String^ JsonText) -> Object^
{
return FBPageBindable::FromJson(JsonText);
});
_likes = ref new FBPaginatedArray(graphPath, nullptr, fact);
create_task(_likes->FirstAsync()).then([this](FBResult^ result)
{
if (result->Succeeded)
{
BadResultsTextBlock->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
LikesListView->Visibility = Windows::UI::Xaml::Visibility::Visible;
IVectorView<Object^>^ items = static_cast<IVectorView<Object^>^> (result->Object);
if (items->Size > 0)
{
AddLikes(items);
}
else
{
LikesListView->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
BadResultsTextBlock->Visibility = Windows::UI::Xaml::Visibility::Visible;
BadResultsTextBlock->Text = L"No User likes found";
}
}
else
{
LikesListView->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
BadResultsTextBlock->Visibility = Windows::UI::Xaml::Visibility::Visible;
BadResultsTextBlock->Text = result->ErrorInfo->Message;
}
});
}
}
void UserLikes::ListView_SelectionChanged(
Object^ sender,
SelectionChangedEventArgs^ e
)
{
FBPageBindable^ selected = static_cast<FBPageBindable^>(e->AddedItems->GetAt(0));
if (selected)
{
FBSingleValue^ val = ref new FBSingleValue(L"/" + selected->Id,
nullptr,
ref new FBJsonClassFactory([](String^ JsonText) -> Object^
{
return FBPageBindable::FromJson(JsonText);
}));
create_task(val->GetAsync())
.then([this](FBResult^ result)
{
if (result->Succeeded)
{
_selectedItem = static_cast<FBPageBindable^>(result->Object);
NotifyPropertyChanged("SelectedItem");
}
});
}
}
void UserLikes::NotifyPropertyChanged(
String^ prop
)
{
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
Windows::UI::Core::CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler([this, prop]()
{
PropertyChangedEventArgs^ args = ref new PropertyChangedEventArgs(prop);
PropertyChanged(this, args);
}));
}
void LoginCpp::UserLikes::BackButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
if (Frame->CanGoBack)
{
Frame->GoBack();
}
}
}