Skip to content

Commit

Permalink
Start adding new samples
Browse files Browse the repository at this point in the history
  • Loading branch information
drasticactions committed Dec 29, 2023
1 parent aefde3a commit 92907ab
Show file tree
Hide file tree
Showing 3 changed files with 189 additions and 0 deletions.
18 changes: 18 additions & 0 deletions samples/FishyFlipSamplesApp/FishyFlipSamplesApp.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Sharprompt" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\FishyFlip\FishyFlip.csproj" />
</ItemGroup>

</Project>
31 changes: 31 additions & 0 deletions samples/FishyFlipSamplesApp/FishyFlipSamplesApp.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FishyFlipSamplesApp", "FishyFlipSamplesApp.csproj", "{F2AE0B15-074A-4A0D-A67A-CC3FEEC6BCF4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FishyFlip", "..\..\src\FishyFlip\FishyFlip.csproj", "{165511B7-407B-4E12-808D-39D1D13DC981}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F2AE0B15-074A-4A0D-A67A-CC3FEEC6BCF4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F2AE0B15-074A-4A0D-A67A-CC3FEEC6BCF4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F2AE0B15-074A-4A0D-A67A-CC3FEEC6BCF4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F2AE0B15-074A-4A0D-A67A-CC3FEEC6BCF4}.Release|Any CPU.Build.0 = Release|Any CPU
{165511B7-407B-4E12-808D-39D1D13DC981}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{165511B7-407B-4E12-808D-39D1D13DC981}.Debug|Any CPU.Build.0 = Debug|Any CPU
{165511B7-407B-4E12-808D-39D1D13DC981}.Release|Any CPU.ActiveCfg = Release|Any CPU
{165511B7-407B-4E12-808D-39D1D13DC981}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {562900E4-F7B1-4FD5-9396-271802E0633B}
EndGlobalSection
EndGlobal
140 changes: 140 additions & 0 deletions samples/FishyFlipSamplesApp/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
// <copyright file="Program.cs" company="Drastic Actions">
// Copyright (c) Drastic Actions. All rights reserved.
// </copyright>

using FishyFlip;
using FishyFlip.Models;
using FishyFlip.Tools;
using Sharprompt;
using System.ComponentModel.DataAnnotations;

Console.WriteLine("FishyFlipSamplesApp");

var domain = Prompt.Input<string>("Instance Domain", "https://bsky.social");
Uri.TryCreate(domain, UriKind.Absolute, out var domainUri);
if (domainUri == null)
{
Console.WriteLine("Invalid domain.");
return;
}

var builder = new FishyFlip.ATProtocolBuilder()
.WithInstanceUrl(domainUri);

var authAsk = Prompt.Confirm("Do you want to authenticate?", defaultValue: false);

var atProtocol = builder.Build();

if (authAsk)
{
var username = Prompt.Input<string>("Username");
var password = Prompt.Password("Password");
var authResult = (await atProtocol.Server.CreateSessionAsync(username, password)).HandleResult();
if (authResult is null)
{
Console.WriteLine("Could not create auth session.");
return;
}
}

string[] authMenuChoices = ["Exit"];

string[] noAuthMenuChoices = ["Exit", "Get Profile Via AtDID", "Get Profile Via Handle", "Get Avatar for Profile"];

if (authAsk)
{
while (true)
{
var menuChoice = Prompt.Select("Menu", authMenuChoices);
if (menuChoice == "Exit")
{
break;
}
}
}
else
{
while (true)
{
var menuChoice = Prompt.Select("Menu", noAuthMenuChoices);
switch (menuChoice)
{
case "Get Avatar for Profile":
await GetAvatarForProfile(atProtocol);
break;
case "Get Profile Via AtDID":
await GetProfileViaATDID(atProtocol);
break;
case "Get Profile Via Handle":
await GetProfileViaHandle(atProtocol);
break;
case "Exit":
return;
}
}
}

async Task GetAvatarForProfile(ATProtocol protocol)
{
var actorRecord = await GetProfileViaHandle(protocol);
if (actorRecord is null)
{
return;
}

if (actorRecord?.Value?.Avatar is null)
{
Console.WriteLine("Profile has no avatar.");
return;
}

// Once we have the profile record, we can get the image by using GetBlob, the actors ATDid, and the ImageRef link.
var avatar = (await protocol.Sync.GetBlobAsync(actorRecord.Uri.Did, actorRecord.Value.Avatar.Ref.Link)).HandleResult();
if (avatar is null)
{
Console.WriteLine("Could not get avatar.");
return;
}

// The avatar is a byte array, so we can save it to disk.
File.WriteAllBytes($"avatar.jpg", avatar.Data);
Console.WriteLine("Avatar saved to disk.");
}

async Task<ActorRecord?> GetProfileViaHandle(ATProtocol protocol)
{
var handle = Prompt.Input<string>("Handle", defaultValue: "drasticactions.dev", validators: new[] { Validators.Required() });
var profile = (await protocol.Identity.ResolveHandleAsync(ATHandle.Create(handle)!)).HandleResult();
return await GetProfileViaATDID(protocol, profile?.Did!);
}

async Task<ActorRecord?> GetProfileViaATDID(ATProtocol protocol, ATDid? did = null)
{
if (did is null)
{
var atdid = Prompt.Input<string>("ATDID", validators: new[] { ProtocolValidators.IsATDid() });
did = ATDid.Create(atdid);
Console.WriteLine(did);
}

var profile = (await protocol.Repo.GetActorAsync(did)).HandleResult();
Console.WriteLine($"Name: {profile?.Value?.DisplayName ?? "Empty"}");
Console.WriteLine($"Description: {profile?.Value?.Description}" ?? "Empty");
return profile;
}

public static class ProtocolValidators
{
public static Func<object, ValidationResult> IsATDid()
{
return delegate (object input)
{
if (input == null)
{
return new ValidationResult("ATDid is invalid.");
}

return (input is string value && !ATDid.IsValid(value)) ? new ValidationResult("ATDid is invalid.") : ValidationResult.Success;
};
}
}

0 comments on commit 92907ab

Please sign in to comment.