зеркало из https://github.com/microsoft/winsdkfb.git
consolidated shared code for LoginCpp
This commit is contained in:
Родитель
4c7c1e8e94
Коммит
4b6f88212d
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче