Viewing Tweets with the Timeline View

,

The timeline view presents a Twitter user’s list of recent tweets (status updates). The TwitterTimelineViewModel class relies on the ITwitterService to retrieve the list of tweets.

TwitterTimelineViewModel contains several properties, which are described in the following list:

Image TimelineItemsAn IEnumerable of TimelineItem objects, which is populated using the ITwitterService. This list is bound to a ListBox control in the view.

Image ScreenNameThe Twitter screen name that was supplied by the user on the sign-in view.

Image ImageUrlThe URL to the Twitter user’s avatar. This is retrieved from the Twitter web API.

Image MessageAn arbitrary string used to supply feedback to the user during retrieval.

Image BusyA bool value indicating whether an asynchronous operation is under way.

The viewmodel also includes a command of type DelegateCommand<string> named loadUserTimelineCommand, which coordinates the retrieval of the list of status updates. LoadUserTimelineCommand receives a Twitter screen name, which is passed to the ITwitterService. See the following excerpt:

public class TwitterTimelineViewModel : ViewModelBase
{
    readonly ITwitterService twitterService;

    public TwitterTimelineViewModel(ITwitterService twitterService)
    {
        this.twitterService = ArgumentValidator.AssertNotNull(
                                        twitterService, "twitterService");

        loadUserTimelineCommand = new DelegateCommand<string>(LoadTimeline);
    }
...
}

When the LoadUserTimelineCommand executes, the LoadTimeline method is called. This method first ensures that a Twitter screen name has been supplied; if not, it navigates back to the sign-in page.

The ITwitterService.GetCachedTimeline method executes asynchronously and attempts to retrieve the cached timeline from the local database. When it returns, the viewmodel is populated using the HandleGetTimelineResult. After attempting to restore the cached timeline, the ITwitterService.GetTimeline method is used to retrieve the latest data from the Twitter web API. See the following excerpt:

void LoadTimeline(string twitterScreenName)
{
    if (string.IsNullOrWhiteSpace(twitterScreenName))
    {
        var messageService = Dependency.Resolve<IMessageService>();
        messageService.ShowError("Please provide a twitter screen name.");

        var navigationService = Dependency.Resolve<INavigationService>();
        navigationService.GoBack();
        return;
    }

    if (twitterScreenName == screenName)
    {
        return;
    }

    Busy = true;

    try
    {
        Message = "Retrieving cached timeline from database.";

        twitterService.GetCachedTimeline(twitterScreenName,
            args =>
            {
                HandleGetTimelineResult(args);
                Message = "Retrieving real data from Twitter.";
                Busy = true;
                twitterService.GetTimeline(
                    twitterScreenName, HandleGetTimelineResult);
            });
    }
    catch (Exception ex)
    {
        Busy = false;
        Message = string.Format("Error retrieving items.");
        Console.WriteLine(ex);
    }
}

The HandleGetTimelineResult method is called twice, once for the cached items and then for the live Twitter data. The Error property of the ResultEventArgs is used to determine whether the call completed successfully, and if so, the viewmodel’s properties are populated accordingly:

void HandleGetTimelineResult(ResultEventArgs<TwitterUser> e)
{
    Busy = false;

    if (e.Error != null)
    {
        Message = "Unable to retrieve timeline.";
        return;
    }

    if (e.Result == null)
    {
        Message = "No result";
        return;
    }

    Message = "Received result.";
    TimelineItems = e.Result.TimelineItems.ToList();
    ScreenName = e.Result.ScreenName;
    ImageUrl = e.Result.ImageUrl;
}

When the viewmodel is instantiated, in the view’s code-beside class, it is passed a TwitterService object, as shown:

public TwitterTimelineView()
{
    InitializeComponent();
    DataContext = new TwitterTimelineViewModel(new TwitterService());
}

The view executes the LoadUserTimelineCommand in its OnNavigatedTo handler, as shown:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    string twitterName;
    if (NavigationContext.QueryString.TryGetValue("name", out twitterName))
    {
        ViewModel.LoadUserTimelineCommand.Execute(twitterName);
    }
}

The view XAML contains controls to display the Twitter timeline information, as well as the Twitter user information. A ListBox presents each TimelineItem using a DataTemplate, as shown in the following excerpt:

<Grid x:Name="ContentPanel" Grid.Row="1">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>

    <Grid Margin="{StaticResource PhoneMargin}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>

        <Image Source="{Binding ImageUrl}"
                    MaxWidth="60" MaxHeight="60" />
        <TextBlock Grid.Column="1" Text="{Binding ScreenName}"
            Style="{StaticResource PhoneTextExtraLargeStyle}" />
    </Grid>

    <ListBox Grid.Row="1"
        ItemsSource="{Binding TimelineItems}"
        Margin="{StaticResource PhoneHorizontalMargin}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Border CornerRadius="10"
                BorderBrush="{StaticResource PhoneBorderBrush}"
                BorderThickness="2"
                Margin="14,5,4,10">
                    <Grid Margin="10">
                        <Grid.RowDefinitions>
                            <RowDefinition />
                            <RowDefinition />
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="100" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>
                        <TextBlock
                            Text="{Binding ReceivedTime,
                            StringFormat='0:HH:mm:ss'}"
                            MaxWidth="100" />

                        <TextBlock Text="{Binding Text}"
                        Grid.Column="1"
                        TextWrapping="Wrap"
                        Style="{StaticResource PhoneTextSmallStyle}" />

                    </Grid>
                </Border>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

A ProgressIndicator is used to monitor the Busy property of the viewmodel and to display the viewmodel’s Message text, as shown:

<shell:SystemTray.ProgressIndicator>
    <shell:ProgressIndicator IsIndeterminate="{Binding Busy}"
                             IsVisible="{Binding Busy}"
                             Text="{Binding Message}" />
</shell:SystemTray.ProgressIndicator>

When a result is received from the Twitter service, it is displayed in the view as shown in Figure 29.5.

Image

FIGURE 29.5 TwitterTimelineView page.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.20.101