~haowenl/vorg-windows

c2948e42f2683aec471c17a7ef4440f7482f5a5d — Haowen Liu 11 months ago 764df76
Basic browsing capability
M libvorg => libvorg +1 -1
@@ 1,1 1,1 @@
Subproject commit 5e3a83f27cc1765e19ab38f453ca4335a5f6a5fb
Subproject commit ad947ddb215301323503ee07f25f46f0960c0eb5

M vorg-windows/App.xaml.cpp => vorg-windows/App.xaml.cpp +32 -1
@@ 6,6 6,7 @@
#include "App.xaml.h"

#include "MainWindow.xaml.h"
#include "BrowseVideoData.h"

using namespace winrt;
using namespace Windows::Foundation;


@@ 24,7 25,7 @@ namespace winrt::vorg_windows::implementation
/// Initializes the singleton application object.  This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
App::App()
App::App() : mFilter(Vorg::VorgFilter::buildFromString(""))
{
    InitializeComponent();



@@ 74,6 75,12 @@ winrt::hstring App::GetNextFile() const
    return winrt::to_hstring(fileUTF8);
}

winrt::hstring App::GetNextFileName() const
{
    std::string nameUTF8 = mRepo->getNextFilePath().filename().string();
    return winrt::to_hstring(nameUTF8);
}

bool App::ImportNext(const winrt::hstring &title, const winrt::hstring &studio,
                     const winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> &actors,
                     const winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> &tags)


@@ 86,6 93,29 @@ bool App::ImportNext(const winrt::hstring &title, const winrt::hstring &studio,
    return mRepo->importNext(titleUTF8, studioUTF8, actorsStd, tagsStd) == Vorg::VorgRepo::Success;
}

void App::PopulateVideoData(
    winrt::Windows::Foundation::Collections::IObservableVector<winrt::Windows::Foundation::IInspectable> &resultData)
    const
{
    resultData.Clear();
    std::vector<Vorg::VorgFileData> rawData = mRepo->getFiles(mFilter);
    for (const Vorg::VorgFileData &fileData : rawData)
    {
        winrt::vorg_windows::BrowseVideoData winrtData = winrt::make<winrt::vorg_windows::implementation::BrowseVideoData>();

        std::filesystem::path videoPathUTF8 = mRepo->getVideoPath(fileData);
        std::vector<std::filesystem::path> thumbnailPathsUTF8 = mRepo->getThumbnailPaths(fileData);

        winrt::hstring videoPath = winrt::to_hstring(videoPathUTF8.string());
        // NOTE: currently only the first thumbnail at 25% is used
        winrt::hstring thumbnailPath = winrt::to_hstring(thumbnailPathsUTF8[0].string());
        winrtData.VideoPath(videoPath);
        winrtData.ThumbnailPath(thumbnailPath);

        resultData.Append(winrtData);
    }
}

winrt::hstring App::GetVorgError() const
{
    if (mRepo == nullptr)


@@ 95,6 125,7 @@ winrt::hstring App::GetVorgError() const
    std::string errorUTF8 = mRepo->getErrorMsg();
    return winrt::to_hstring(errorUTF8);
}

std::vector<std::string> App::WinrtToStdVector(
    const winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> &input)
{

M vorg-windows/App.xaml.h => vorg-windows/App.xaml.h +5 -0
@@ 20,9 20,13 @@ struct App : AppT<App>
    bool SetImportFile(const winrt::hstring &path);
    bool SetImportFolder(const winrt::hstring &path);
    winrt::hstring GetNextFile() const;
    winrt::hstring GetNextFileName() const;
    bool ImportNext(const winrt::hstring &title, const winrt::hstring &studio,
                    const winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> &actors,
                    const winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> &tags);
    void PopulateVideoData(
        winrt::Windows::Foundation::Collections::IObservableVector<winrt::Windows::Foundation::IInspectable>
            &resultData) const;

    // Error handling
    winrt::hstring GetVorgError() const;


@@ 32,6 36,7 @@ struct App : AppT<App>

  private:
    std::unique_ptr<Vorg::VorgRepo> mRepo;
    Vorg::VorgFilter mFilter;

    static std::vector<std::string> WinrtToStdVector(
        const winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> &input);

M vorg-windows/BrowsePage.idl => vorg-windows/BrowsePage.idl +7 -1
@@ 1,11 1,17 @@
// Copyright (c) Microsoft Corporation and Contributors.
// Licensed under the MIT License.

import "BrowseVideoData.idl";

namespace vorg_windows
{
[default_interface] runtimeclass BrowsePage : Microsoft.UI.Xaml.Controls.Page
{
    BrowsePage();
    Int32 MyProperty;

    Windows.Foundation.Collections.IIterable<IInspectable> VideoData
    {
        get;
    };
}
} // namespace vorg_windows

M vorg-windows/BrowsePage.xaml => vorg-windows/BrowsePage.xaml +37 -5
@@ 1,16 1,48 @@
<!-- Copyright (c) Microsoft Corporation and Contributors. -->
<!-- Licensed under the MIT License. -->
<!--  Copyright (c) Microsoft Corporation and Contributors.  -->
<!--  Licensed under the MIT License.  -->

<Page
    x:Class="vorg_windows.BrowsePage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:vorg_windows"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="using:vorg_windows"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    NavigationCacheMode="Required"
    mc:Ignorable="d">

    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
        <Button x:Name="myButton" Click="myButton_Click">Click Me</Button>
    <Page.Resources>
        <DataTemplate x:Key="ThumbnailTemplate" x:DataType="local:BrowseVideoData">
            <Image
                Width="190"
                Height="130"
                DoubleTapped="Thumbnail_DoubleTapped"
                IsDoubleTapEnabled="True"
                Source="{x:Bind ThumbnailPath}"
                Stretch="UniformToFill" />
        </DataTemplate>
    </Page.Resources>

    <StackPanel
        Margin="0,44,0,44"
        HorizontalAlignment="Stretch"
        VerticalAlignment="Stretch">
        <Grid
            Height="40"
            Margin="0,0,0,22"
            VerticalAlignment="Top"
            Background="Transparent">
            <TextBlock
                VerticalAlignment="Center"
                FontSize="22"
                Style="{StaticResource TitleTextBlockStyle}"
                Text="Browse Repository" />
        </Grid>

        <GridView
            x:Name="VideoGallery"
            ItemTemplate="{StaticResource ThumbnailTemplate}"
            ItemsSource="{x:Bind VideoData}"
            SelectionMode="Single" />
    </StackPanel>
</Page>

M vorg-windows/BrowsePage.xaml.cpp => vorg-windows/BrowsePage.xaml.cpp +30 -11
@@ 11,28 11,47 @@
using namespace winrt;
using namespace Microsoft::UI::Xaml;

// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.

namespace winrt::vorg_windows::implementation
{
BrowsePage::BrowsePage()
    : mVideoData(winrt::single_threaded_observable_vector<winrt::Windows::Foundation::IInspectable>())
{
    InitializeComponent();
}

int32_t BrowsePage::MyProperty()
{
    throw hresult_not_implemented();
    // Initialize app ptr
    mApp.copy_from(winrt::get_self<vorg_windows::implementation::App>(
        Application::Current().as<winrt::default_interface<vorg_windows::implementation::App>>()));

    // Populate video data
    mApp->PopulateVideoData(mVideoData);
}

void BrowsePage::MyProperty(int32_t /* value */)
winrt::Windows::Foundation::Collections::IIterable<winrt::Windows::Foundation::IInspectable> BrowsePage::VideoData()
    const
{
    throw hresult_not_implemented();
    return mVideoData;
}

void BrowsePage::myButton_Click(IInspectable const &, RoutedEventArgs const &)
fire_and_forget BrowsePage::Thumbnail_DoubleTapped(
    winrt::Windows::Foundation::IInspectable const &sender,
    winrt::Microsoft::UI::Xaml::Input::DoubleTappedRoutedEventArgs const &)
{
    myButton().Content(box_value(L"Clicked"));
    winrt::Microsoft::UI::Xaml::Controls::Image image = sender.as<winrt::Microsoft::UI::Xaml::Controls::Image>();
    winrt::Windows::Foundation::IInspectable dataContext = image.DataContext();
    vorg_windows::BrowseVideoData videoData = dataContext.as<vorg_windows::BrowseVideoData>();
    Windows::Storage::StorageFile videoFile =
        co_await Windows::Storage::StorageFile::GetFileFromPathAsync(videoData.VideoPath());
    if (videoFile)
    {
        Windows::System::Launcher::LaunchFileAsync(videoFile);
    }
    else
    {
        winrt::vorg_windows::ErrorContentDialog dialog;
        dialog.Title(winrt::box_value(L"Error opening file"));
        dialog.Content(winrt::box_value(L"This should not happen. Please file a bug report."));
        dialog.XamlRoot(XamlRoot());
        co_await dialog.ShowAsync();
    }
}
} // namespace winrt::vorg_windows::implementation

M vorg-windows/BrowsePage.xaml.h => vorg-windows/BrowsePage.xaml.h +10 -4
@@ 5,17 5,23 @@

#include "BrowsePage.g.h"

#include "App.xaml.h"

namespace winrt::vorg_windows::implementation
{
struct BrowsePage : BrowsePageT<BrowsePage>
{
    BrowsePage();

    int32_t MyProperty();
    void MyProperty(int32_t value);
    winrt::Windows::Foundation::Collections::IIterable<winrt::Windows::Foundation::IInspectable> VideoData() const;

  private:
    winrt::Windows::Foundation::Collections::IObservableVector<winrt::Windows::Foundation::IInspectable> mVideoData;
    winrt::com_ptr<vorg_windows::implementation::App> mApp{nullptr};

    void myButton_Click(Windows::Foundation::IInspectable const &sender,
                        Microsoft::UI::Xaml::RoutedEventArgs const &args);
  public:
    fire_and_forget Thumbnail_DoubleTapped(winrt::Windows::Foundation::IInspectable const &sender,
                                winrt::Microsoft::UI::Xaml::Input::DoubleTappedRoutedEventArgs const &);
};
} // namespace winrt::vorg_windows::implementation


A vorg-windows/BrowseVideoData.cpp => vorg-windows/BrowseVideoData.cpp +29 -0
@@ 0,0 1,29 @@
#include "pch.h"

#include "BrowseVideoData.h"
#if __has_include("BrowseVideoData.g.cpp")
#include "BrowseVideoData.g.cpp"
#endif

namespace winrt::vorg_windows::implementation
{
winrt::hstring BrowseVideoData::ThumbnailPath() const
{
    return mThumbnailPath;
}

void BrowseVideoData::ThumbnailPath(const winrt::hstring &thumbnailPath)
{
    mThumbnailPath = thumbnailPath;
}

winrt::hstring BrowseVideoData::VideoPath() const
{
    return mVideoPath;
}

void BrowseVideoData::VideoPath(const winrt::hstring &videoPath)
{
    mVideoPath = videoPath;
}
} // namespace winrt::vorg_windows::implementation
\ No newline at end of file

A vorg-windows/BrowseVideoData.h => vorg-windows/BrowseVideoData.h +26 -0
@@ 0,0 1,26 @@
#pragma once

#include "BrowseVideoData.g.h"

namespace winrt::vorg_windows::implementation
{
struct BrowseVideoData : BrowseVideoDataT<BrowseVideoData>
{
    winrt::hstring ThumbnailPath() const;
    void ThumbnailPath(const winrt::hstring &thumbnailPath);

    winrt::hstring VideoPath() const;
    void VideoPath(const winrt::hstring &videoPath);

  private:
    winrt::hstring mThumbnailPath;
    winrt::hstring mVideoPath;
};
} // namespace winrt::vorg_windows::implementation

namespace winrt::vorg_windows::factory_implementation
{
struct BrowseVideoData : BrowseVideoDataT<BrowseVideoData, implementation::BrowseVideoData>
{
};
} // namespace winrt::vorg_windows::factory_implementation

A vorg-windows/BrowseVideoData.idl => vorg-windows/BrowseVideoData.idl +9 -0
@@ 0,0 1,9 @@
namespace vorg_windows
{
[default_interface] runtimeclass BrowseVideoData {
    BrowseVideoData();

    String ThumbnailPath;
    String VideoPath;
}
} // namespace vorg_windows

M vorg-windows/ImportEditPage.idl => vorg-windows/ImportEditPage.idl +7 -0
@@ 20,5 20,12 @@ namespace vorg_windows
            get;
            set;
        };
        String FileName
        {
            get;
            set;
        };

        event Windows.Foundation.TypedEventHandler<ImportEditPage, Object> EditFinished;
    }
}

M vorg-windows/ImportEditPage.xaml => vorg-windows/ImportEditPage.xaml +7 -2
@@ 10,14 10,19 @@
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <StackPanel Orientation="Vertical">
    <StackPanel Margin="0,62,0,0" Orientation="Vertical">
        <TextBlock
            Margin="0,0,0,20"
            VerticalAlignment="Center"
            FontSize="22"
            Style="{StaticResource SubtitleTextBlockStyle}"
            Text="{x:Bind FileName}" />
        <MediaPlayerElement
            x:Name="MediaPlayer"
            AreTransportControlsEnabled="True"
            BorderThickness="0"
            CornerRadius="16"
            Source="{x:Bind MediaSource}" />

        <Grid
            Margin="0,16,0,0"
            ColumnSpacing="16"

M vorg-windows/ImportEditPage.xaml.cpp => vorg-windows/ImportEditPage.xaml.cpp +26 -3
@@ 44,6 44,16 @@ void ImportEditPage::MediaSource(const winrt::Windows::Media::Core::MediaSource 
    mMediaSource = mediaSource;
}

winrt::hstring ImportEditPage::FileName() const
{
    return mFileName;
}

void ImportEditPage::FileName(const winrt::hstring &fileName)
{
    mFileName = fileName;
}

void ImportEditPage::UserControl_PointerEntered(const winrt::Windows::Foundation::IInspectable &sender,
                                                const winrt::Microsoft::UI::Xaml::Input::PointerRoutedEventArgs &)
{


@@ 66,7 76,7 @@ void ImportEditPage::ActorsDeleteButton_Click(const winrt::Windows::Foundation::
    winrt::Microsoft::UI::Xaml::Controls::Button button = sender.as<winrt::Microsoft::UI::Xaml::Controls::Button>();
    winrt::Windows::Foundation::IInspectable dataContext = button.DataContext();
    winrt::hstring itemName = dataContext.as<winrt::hstring>();
    DelteFromVector(mActors, itemName);
    DeleteFromVector(mActors, itemName);
}

void ImportEditPage::TagsDeleteButton_Click(const winrt::Windows::Foundation::IInspectable &sender,


@@ 75,7 85,7 @@ void ImportEditPage::TagsDeleteButton_Click(const winrt::Windows::Foundation::II
    winrt::Microsoft::UI::Xaml::Controls::Button button = sender.as<winrt::Microsoft::UI::Xaml::Controls::Button>();
    winrt::Windows::Foundation::IInspectable dataContext = button.DataContext();
    winrt::hstring itemName = dataContext.as<winrt::hstring>();
    DelteFromVector(mTags, itemName);
    DeleteFromVector(mTags, itemName);
}

void ImportEditPage::ActorsSubmitButton_Click(const winrt::Windows::Foundation::IInspectable &,


@@ 112,9 122,22 @@ void ImportEditPage::SubmitButton_Click(const winrt::Windows::Foundation::IInspe
                                        const winrt::Microsoft::UI::Xaml::RoutedEventArgs &)
{
    mApp->ImportNext(TitleInput().Text(), StudioInput().Text(), mActors, mTags);
    mEditFinishedEvent(*this, nullptr);
}

winrt::event_token ImportEditPage::EditFinished(
    const winrt::Windows::Foundation::TypedEventHandler<vorg_windows::ImportEditPage,
                                                        winrt::Windows::Foundation::IInspectable> &handler)
{
    return mEditFinishedEvent.add(handler);
}

void ImportEditPage::EditFinished(const winrt::event_token &token)
{
    mEditFinishedEvent.remove(token);
}

void ImportEditPage::DelteFromVector(winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> &vector,
void ImportEditPage::DeleteFromVector(winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> &vector,
                                     const winrt::hstring &item)
{
    for (uint32_t i = 0; i < vector.Size(); ++i)

M vorg-windows/ImportEditPage.xaml.h => vorg-windows/ImportEditPage.xaml.h +14 -3
@@ 19,6 19,9 @@ struct ImportEditPage : ImportEditPageT<ImportEditPage>
    winrt::Windows::Media::Core::MediaSource MediaSource() const;
    void MediaSource(const winrt::Windows::Media::Core::MediaSource &mediaSource);

    winrt::hstring FileName() const;
    void FileName(const winrt::hstring &fileName);

    void UserControl_PointerEntered(const winrt::Windows::Foundation::IInspectable &sender,
                                    const winrt::Microsoft::UI::Xaml::Input::PointerRoutedEventArgs &);
    void UserControl_PointerExited(const winrt::Windows::Foundation::IInspectable &sender,


@@ 34,20 37,28 @@ struct ImportEditPage : ImportEditPageT<ImportEditPage>
                                const winrt::Microsoft::UI::Xaml::RoutedEventArgs &e);

    void ActorNameInput_KeyUp(winrt::Windows::Foundation::IInspectable const &,
                                winrt::Microsoft::UI::Xaml::Input::KeyRoutedEventArgs const &e);
    void TagNameInput_KeyUp(winrt::Windows::Foundation::IInspectable const &,
                              winrt::Microsoft::UI::Xaml::Input::KeyRoutedEventArgs const &e);
    void TagNameInput_KeyUp(winrt::Windows::Foundation::IInspectable const &,
                            winrt::Microsoft::UI::Xaml::Input::KeyRoutedEventArgs const &e);

    void SubmitButton_Click(const winrt::Windows::Foundation::IInspectable &,
                            const winrt::Microsoft::UI::Xaml::RoutedEventArgs &);

    winrt::event_token EditFinished(const winrt::Windows::Foundation::TypedEventHandler<
                                    vorg_windows::ImportEditPage, winrt::Windows::Foundation::IInspectable> &handler);
    void EditFinished(const winrt::event_token &token);

  private:
    winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> mActors;
    winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> mTags;
    winrt::Windows::Media::Core::MediaSource mMediaSource{nullptr};
    winrt::hstring mFileName;
    winrt::com_ptr<winrt::vorg_windows::implementation::App> mApp;
    winrt::event<winrt::Windows::Foundation::TypedEventHandler<vorg_windows::ImportEditPage,
                                                               winrt::Windows::Foundation::IInspectable>>
        mEditFinishedEvent;

    static void DelteFromVector(winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> &vector,
    static void DeleteFromVector(winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> &vector,
                                const winrt::hstring &item);
    static bool FindInVector(winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> &vector,
                             const winrt::hstring &item);

M vorg-windows/ImportPage.idl => vorg-windows/ImportPage.idl +0 -3
@@ 1,6 1,3 @@
// Copyright (c) Microsoft Corporation and Contributors.
// Licensed under the MIT License.

namespace vorg_windows
{
[default_interface] runtimeclass ImportPage : Microsoft.UI.Xaml.Controls.Page

M vorg-windows/ImportPage.xaml => vorg-windows/ImportPage.xaml +1 -0
@@ 8,6 8,7 @@
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="using:vorg_windows"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    NavigationCacheMode="Required"
    mc:Ignorable="d">

    <Grid

M vorg-windows/ImportPage.xaml.cpp => vorg-windows/ImportPage.xaml.cpp +35 -3
@@ 13,9 13,6 @@
using namespace winrt;
using namespace Microsoft::UI::Xaml;

// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.

namespace winrt::vorg_windows::implementation
{
ImportPage::ImportPage()


@@ 48,8 45,43 @@ void ImportPage::ImportSelectionPage_SelectionFinished(const vorg_windows::Impor
    // Set ImportEditPage MediaSource
    vorg_windows::ImportEditPage editPage = ContentFrame().Content().as<vorg_windows::ImportEditPage>();
    winrt::hstring filePath = mApp->GetNextFile();
    winrt::hstring fileName = mApp->GetNextFileName();
    editPage.FileName(fileName);
    winrt::Windows::Media::Core::MediaSource mediaSouce =
        winrt::Windows::Media::Core::MediaSource::CreateFromUri(winrt::Windows::Foundation::Uri{filePath});
    editPage.MediaSource(mediaSouce);
    mEditFinishedToken =
        editPage.EditFinished([this](auto &sender, auto &args) { this->ImportEditPage_EditFinished(sender, args); });
}

void ImportPage::ImportEditPage_EditFinished(const vorg_windows::ImportEditPage &,
                                             const winrt::Windows::Foundation::IInspectable &)
{
    // Check for next file
    winrt::hstring filePath = mApp->GetNextFile();
    if (filePath.empty())
    {
        // No more file
        // Remove EditFinished handler
        vorg_windows::ImportEditPage editPage = ContentFrame().Content().as<vorg_windows::ImportEditPage>();
        editPage.EditFinished(mEditFinishedToken);

        // Navigate to ImportSelectionPage
        ContentFrame().Navigate(winrt::xaml_typename<winrt::vorg_windows::ImportSelectionPage>());
        vorg_windows::ImportSelectionPage selectionPage =
            ContentFrame().Content().as<vorg_windows::ImportSelectionPage>();
        mSelectionFinishedToken = selectionPage.SelectionFinished(
            [this](auto &sender, auto &args) { this->ImportSelectionPage_SelectionFinished(sender, args); });
    }
    else
    {
        // Continue editing next file
        winrt::hstring fileName = mApp->GetNextFileName();
        vorg_windows::ImportEditPage editPage = ContentFrame().Content().as<vorg_windows::ImportEditPage>();
        editPage.FileName(fileName);
        winrt::Windows::Media::Core::MediaSource mediaSouce =
            winrt::Windows::Media::Core::MediaSource::CreateFromUri(winrt::Windows::Foundation::Uri{filePath});
        editPage.MediaSource(mediaSouce);
    }
}
} // namespace winrt::vorg_windows::implementation

M vorg-windows/ImportPage.xaml.h => vorg-windows/ImportPage.xaml.h +4 -1
@@ 16,9 16,12 @@ struct ImportPage : ImportPageT<ImportPage>
    void ImportSelectionPage_SelectionFinished(const vorg_windows::ImportSelectionPage &,
                                               const winrt::Windows::Foundation::IInspectable &);

    void ImportEditPage_EditFinished(const vorg_windows::ImportEditPage &,
                                     const winrt::Windows::Foundation::IInspectable &);

  private:
    winrt::event_token mSelectionFinishedToken;

    winrt::event_token mEditFinishedToken;
    winrt::com_ptr<winrt::vorg_windows::implementation::App> mApp{nullptr};
};
} // namespace winrt::vorg_windows::implementation

M vorg-windows/ImportSelectionPage.xaml.cpp => vorg-windows/ImportSelectionPage.xaml.cpp +1 -1
@@ 46,7 46,7 @@ winrt::fire_and_forget ImportSelectionPage::ImportFileButton_Click(
        {
            // Show dialog with error
            winrt::vorg_windows::ErrorContentDialog dialog;
            dialog.Title(winrt::box_value(L"Error importing folder"));
            dialog.Title(winrt::box_value(L"Error importing file"));
            dialog.Content(winrt::box_value(mApp->GetVorgError()));
            dialog.XamlRoot(XamlRoot());
            co_await dialog.ShowAsync();

M vorg-windows/MainWindow.xaml.cpp => vorg-windows/MainWindow.xaml.cpp +2 -3
@@ 44,7 44,7 @@ MainWindow::MainWindow()

    // Register OpenRepo handler
    vorg_windows::LandingPage landingPage = ContentFrame().Content().as<vorg_windows::LandingPage>();
    mLandingPageOpenRepoToken =
    mOpenRepoEventToken =
        landingPage.OpenRepo([this](auto &sender, auto &args) { this->LandingPage_OpenRepo(sender, args); });
}



@@ 53,7 53,6 @@ void MainWindow::NavigationView_ItemInvoked(const Controls::NavigationView &,
{
    const winrt::hstring &tag = args.InvokedItemContainer().Tag().as<winrt::hstring>();
    ContentFrame().Navigate(mNavigationTypeMap.at(tag));
    // NavigationView().Header(mNavigationHeaderMap.at(tag));
}

void MainWindow::LandingPage_OpenRepo(const winrt::vorg_windows::LandingPage &,


@@ 61,7 60,7 @@ void MainWindow::LandingPage_OpenRepo(const winrt::vorg_windows::LandingPage &,
{
    // Remove OpenRepo handler
    vorg_windows::LandingPage landingPage = ContentFrame().Content().as<vorg_windows::LandingPage>();
    landingPage.OpenRepo(mLandingPageOpenRepoToken);
    landingPage.OpenRepo(mOpenRepoEventToken);

    // Navigate to ImportPage
    ContentFrame().Navigate(mNavigationTypeMap.at(L"Import"));

M vorg-windows/MainWindow.xaml.h => vorg-windows/MainWindow.xaml.h +3 -3
@@ 18,11 18,11 @@ struct MainWindow : MainWindowT<MainWindow>
    void NavigationView_ItemInvoked(const Microsoft::UI::Xaml::Controls::NavigationView &sender,
                                    const Microsoft::UI::Xaml::Controls::NavigationViewItemInvokedEventArgs &args);

    void LandingPage_OpenRepo(const winrt::vorg_windows::LandingPage &sender,
                              const winrt::Windows::Foundation::IInspectable &args);
    void LandingPage_OpenRepo(const winrt::vorg_windows::LandingPage &,
                              const winrt::Windows::Foundation::IInspectable &);

  private:
    winrt::event_token mLandingPageOpenRepoToken;
    winrt::event_token mOpenRepoEventToken;
    std::map<winrt::hstring, winrt::Windows::UI::Xaml::Interop::TypeName> mNavigationTypeMap;
    std::map<winrt::hstring, winrt::Windows::Foundation::IInspectable> mNavigationHeaderMap;
};

M vorg-windows/ManagePage.xaml => vorg-windows/ManagePage.xaml +8 -4
@@ 1,16 1,20 @@
<!-- Copyright (c) Microsoft Corporation and Contributors. -->
<!-- Licensed under the MIT License. -->
<!--  Copyright (c) Microsoft Corporation and Contributors.  -->
<!--  Licensed under the MIT License.  -->

<Page
    x:Class="vorg_windows.ManagePage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:vorg_windows"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="using:vorg_windows"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    NavigationCacheMode="Required"
    mc:Ignorable="d">

    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
    <StackPanel
        HorizontalAlignment="Center"
        VerticalAlignment="Center"
        Orientation="Horizontal">
        <Button x:Name="myButton" Click="myButton_Click">Click Me</Button>
    </StackPanel>
</Page>

M vorg-windows/pch.h => vorg-windows/pch.h +1 -0
@@ 30,6 30,7 @@
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Media.Core.h>
#include <winrt/Windows.Storage.Pickers.h>
#include <winrt/Windows.System.h>
#include <winrt/Windows.UI.Xaml.Interop.h>

#include <wil/cppwinrt_helpers.h>

M vorg-windows/vorg-windows.vcxproj => vorg-windows/vorg-windows.vcxproj +3 -0
@@ 127,6 127,7 @@
      <DependentUpon>BrowsePage.xaml</DependentUpon>
      <SubType>Code</SubType>
    </ClInclude>
    <ClInclude Include="BrowseVideoData.h" />
    <ClInclude Include="ErrorContentDialog.xaml.h">
      <DependentUpon>ErrorContentDialog.xaml</DependentUpon>
      <SubType>Code</SubType>


@@ 189,6 190,7 @@
      <DependentUpon>BrowsePage.xaml</DependentUpon>
      <SubType>Code</SubType>
    </ClCompile>
    <ClCompile Include="BrowseVideoData.cpp" />
    <ClCompile Include="ErrorContentDialog.xaml.cpp">
      <DependentUpon>ErrorContentDialog.xaml</DependentUpon>
      <SubType>Code</SubType>


@@ 233,6 235,7 @@
      <DependentUpon>BrowsePage.xaml</DependentUpon>
      <SubType>Code</SubType>
    </Midl>
    <Midl Include="BrowseVideoData.idl" />
    <Midl Include="ErrorContentDialog.idl">
      <DependentUpon>ErrorContentDialog.xaml</DependentUpon>
      <SubType>Code</SubType>

M vorg-windows/vorg-windows.vcxproj.filters => vorg-windows/vorg-windows.vcxproj.filters +3 -0
@@ 16,13 16,16 @@
  <ItemGroup>
    <Midl Include="App.idl" />
    <Midl Include="MainWindow.idl" />
    <Midl Include="BrowseVideoData.idl" />
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="pch.cpp" />
    <ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
    <ClCompile Include="BrowseVideoData.cpp" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="pch.h" />
    <ClInclude Include="BrowseVideoData.h" />
  </ItemGroup>
  <ItemGroup>
    <Image Include="Assets\Wide310x150Logo.scale-200.png">