Skip to content

Commit 15575cc

Browse files
author
David Khristepher Santos
committed
Merge branch 'tags'
2 parents 931a6bc + 3f2d3ed commit 15575cc

25 files changed

Lines changed: 807 additions & 46 deletions

Diffusion.Common/ModelView.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ public class ModelView
88
public string Hashv2 { get; set; }
99
public string SHA256 { get; set; }
1010
public int ImageCount { get; set; }
11-
}
11+
}

Diffusion.Common/Query/QueryOptions.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ public QueryOptions()
2323
public bool HideNSFW { get; set; }
2424
public IReadOnlyCollection<int> AlbumIds { get; set; }
2525
public IReadOnlyCollection<ModelInfo> Models { get; set; }
26+
public IReadOnlyCollection<int> TagIds { get; set; }
27+
2628
public SearchView SearchView { get; set; }
2729
public bool SearchNodes { get; set; }
2830
public ComfyQueryOptions ComfyQueryOptions { get; set; }
@@ -32,4 +34,5 @@ public QueryOptions()
3234

3335
[JsonIgnore]
3436
public bool IsEmpty => Filter.IsEmpty && string.IsNullOrEmpty(Query);
37+
3538
}

Diffusion.Database/DataStore.Query.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public bool QueryExists(string name)
2222

2323
return count == 1;
2424
}
25+
2526
public void CreateOrUpdateQuery(string name, QueryOptions queryOptions)
2627
{
2728
var json = JsonSerializer.Serialize(queryOptions);
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
using Diffusion.Common;
2+
using Diffusion.Common.Query;
3+
using Diffusion.Database.Models;
4+
using System;
5+
using System.Text;
6+
using System.Xml.Linq;
7+
8+
namespace Diffusion.Database
9+
{
10+
11+
public partial class DataStore
12+
{
13+
public IEnumerable<Tag> GetTags()
14+
{
15+
using var db = OpenConnection();
16+
17+
var query = $"SELECT Id, Name FROM Tag ORDER BY Name";
18+
19+
var models = db.Query<Tag>(query);
20+
21+
db.Close();
22+
23+
return models;
24+
}
25+
26+
public IEnumerable<TagCount> GetTagsWithCount()
27+
{
28+
using var db = OpenConnection();
29+
30+
var query = $"SELECT Id, Name, (SELECT COUNT(1) FROM {nameof(ImageTag)} IT WHERE T.Id = IT.TagId) AS [Count] FROM Tag T ORDER BY Name";
31+
32+
var models = db.Query<TagCount>(query);
33+
34+
db.Close();
35+
36+
return models;
37+
}
38+
39+
40+
public void CreateTag(string name)
41+
{
42+
using var db = OpenConnection();
43+
44+
var command = db.CreateCommand("INSERT INTO Tag (Name) VALUES (?)", name);
45+
46+
lock (_lock)
47+
{
48+
command.ExecuteNonQuery();
49+
}
50+
51+
db.Close();
52+
}
53+
54+
public void UpdateTag(int id, string name)
55+
{
56+
using var db = OpenConnection();
57+
58+
var command = db.CreateCommand("UPDATE Tag SET Name = ? WHERE Id = ?", name, id);
59+
60+
lock (_lock)
61+
{
62+
command.ExecuteNonQuery();
63+
}
64+
65+
db.Close();
66+
}
67+
68+
public void RemoveTag(int id)
69+
{
70+
using var db = OpenConnection();
71+
72+
var command = db.CreateCommand("DELETE FROM Tag WHERE Id = ?", id);
73+
74+
lock (_lock)
75+
{
76+
command.ExecuteNonQuery();
77+
}
78+
79+
db.Close();
80+
}
81+
82+
private class TagIdTemp
83+
{
84+
public int TagId { get; set; }
85+
}
86+
87+
public IEnumerable<int> GetImageTags(int id)
88+
{
89+
using var db = OpenConnection();
90+
91+
var query = $"SELECT TagId FROM ImageTag WHERE ImageId = {id}";
92+
93+
var results = db.Query<TagIdTemp>(query);
94+
95+
db.Close();
96+
97+
return results.Select(d => d.TagId).ToList();
98+
}
99+
100+
public void AddImageTag(int id, int tagId)
101+
{
102+
using var db = OpenConnection();
103+
104+
var command = db.CreateCommand("REPLACE INTO ImageTag (ImageId, TagId) VALUES (?,?)", id, tagId);
105+
106+
lock (_lock)
107+
{
108+
command.ExecuteNonQuery();
109+
}
110+
111+
db.Close();
112+
}
113+
114+
public void RemoveImageTag(int id, int tagId)
115+
{
116+
using var db = OpenConnection();
117+
118+
var command = db.CreateCommand("DELETE FROM ImageTag WHERE ImageId = ? AND TagId = ?", id, tagId);
119+
120+
lock (_lock)
121+
{
122+
command.ExecuteNonQuery();
123+
}
124+
125+
db.Close();
126+
}
127+
128+
public void AddImagesTag(IEnumerable<int> ids, int tagId)
129+
{
130+
using var db = OpenConnection();
131+
132+
var values = new List<string>();
133+
134+
foreach (var id in ids)
135+
{
136+
values.Add($"({id}, {tagId})");
137+
}
138+
139+
var command = db.CreateCommand($"REPLACE INTO ImageTag (ImageId, TagId) VALUES {string.Join(", ", values)}");
140+
141+
lock (_lock)
142+
{
143+
command.ExecuteNonQuery();
144+
}
145+
146+
db.Close();
147+
}
148+
149+
public void RemoveImagesTag(IEnumerable<int> ids, int tagId)
150+
{
151+
using var db = OpenConnection();
152+
153+
var values = new List<string>();
154+
155+
foreach (var id in ids)
156+
{
157+
values.Add($"{id}");
158+
}
159+
160+
var command = db.CreateCommand($"DELETE FROM ImageTag WHERE ImageId IN ({string.Join(", ", values)}) AND TagId = ?", tagId);
161+
162+
lock (_lock)
163+
{
164+
command.ExecuteNonQuery();
165+
}
166+
167+
db.Close();
168+
}
169+
170+
public void RemoveImageTags(int id)
171+
{
172+
using var db = OpenConnection();
173+
174+
var command = db.CreateCommand("DELETE FROM ImageTag SET WHERE ImageId = ?", id);
175+
176+
lock (_lock)
177+
{
178+
command.ExecuteNonQuery();
179+
}
180+
181+
db.Close();
182+
}
183+
}
184+
}

Diffusion.Database/DataStore.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,11 @@ void SchemaUpdated(object? sender, EventArgs args)
138138

139139
db.CreateIndex<Image>(image => image.Type);
140140

141+
db.CreateTable<Tag>();
142+
db.CreateIndex<Tag>(tag => tag.Id);
143+
144+
db.CreateTable<ImageTag>();
145+
db.CreateIndex<ImageTag>(tag => new { tag.ImageId, tag.TagId }, true);
141146

142147
db.CreateTable<Album>();
143148
db.CreateIndex<Album>(album => album.Name, true);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace Diffusion.Database.Models;
2+
3+
public class ImageTag
4+
{
5+
public int ImageId { get; set; }
6+
public int TagId { get; set; }
7+
}

Diffusion.Database/Models/Tag.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using SQLite;
2+
3+
namespace Diffusion.Database.Models;
4+
5+
public class Tag
6+
{
7+
[PrimaryKey, AutoIncrement]
8+
public int Id { get; set; }
9+
public string Name { get; set; }
10+
}
11+
12+
public class TagCount
13+
{
14+
public int Id { get; set; }
15+
public string Name { get; set; }
16+
public int Count { get; set; }
17+
}

Diffusion.Database/QueryCombiner.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,12 @@ private static void ApplyFilters(ref string query, ref IEnumerable<object> bindi
181181
bindings = bindings.Concat(options.AlbumIds.Cast<object>());
182182
}
183183

184+
if (options.TagIds is { Count: > 0 })
185+
{
186+
var placeholders = string.Join(",", options.TagIds.Select(a => "?"));
187+
filters.Add($"SELECT DISTINCT m1.Id FROM Image m1 INNER JOIN ImageTag it ON it.ImageId = m1.Id INNER JOIN Tag t ON t.Id = it.TagId WHERE t.Id IN ({placeholders})");
188+
bindings = bindings.Concat(options.TagIds.Cast<object>());
189+
}
184190

185191
if (options.Models is { Count: > 0 })
186192
{

Diffusion.Toolkit/Configuration/NavigationSectionSettings.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public NavigationSectionSettings()
1414
FolderHeight = Double.PositiveInfinity;
1515
ModelHeight = Double.PositiveInfinity;
1616
AlbumHeight = Double.PositiveInfinity;
17+
TagHeight = Double.PositiveInfinity;
1718
}
1819

1920
public NavigationSectionSettings(bool initialize)
@@ -45,6 +46,12 @@ public AccordionState AlbumState
4546
set => UpdateValue(ref field, value);
4647
}
4748

49+
public AccordionState TagState
50+
{
51+
get;
52+
set => UpdateValue(ref field, value);
53+
}
54+
4855
public AccordionState QueryState
4956
{
5057
get;
@@ -70,6 +77,12 @@ public double AlbumHeight
7077
set => UpdateValue(ref field, value);
7178
}
7279

80+
public double TagHeight
81+
{
82+
get;
83+
set => UpdateValue(ref field, value);
84+
}
85+
7386
public double QueryHeight
7487
{
7588
get;

Diffusion.Toolkit/Controls/MetadataPanel.xaml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
xmlns:lex="http://wpflocalizeextension.codeplex.com"
88
xmlns:converters="clr-namespace:Diffusion.Toolkit.Converters"
99
xmlns:common="clr-namespace:Diffusion.Toolkit.Common"
10+
xmlns:fa="http://schemas.fontawesome.io/icons/"
1011
mc:Ignorable="d"
1112
d:DesignHeight="776.386" d:DesignWidth="464.94">
1213
<UserControl.Resources>
@@ -222,6 +223,53 @@
222223
</StackPanel>
223224
</ScrollViewer>
224225
</TabItem>
226+
<TabItem Header="Tags" Background="Transparent" GotFocus="UIElement_OnGotFocus" HorizontalContentAlignment="Stretch">
227+
228+
<Grid Background="Transparent" Height="{Binding ActualHeight, RelativeSource={RelativeSource FindAncestor, AncestorType=TabControl, AncestorLevel=1}}">
229+
<Grid.RowDefinitions>
230+
<RowDefinition Height="20"></RowDefinition>
231+
<RowDefinition Height="*"></RowDefinition>
232+
<RowDefinition Height="20"></RowDefinition>
233+
<RowDefinition Height="36"></RowDefinition>
234+
</Grid.RowDefinitions>
235+
<Grid Background="Transparent" Grid.Row="0">
236+
<TextBox></TextBox>
237+
</Grid>
238+
<Grid Background="Transparent" Grid.Row="1" ></Grid>
239+
<ScrollViewer Grid.Row="1" Background="Transparent" VerticalScrollBarVisibility="Auto">
240+
<ListView ItemsSource="{Binding ImageTags}">
241+
<ListView.ItemTemplate>
242+
<DataTemplate>
243+
<CheckBox IsChecked="{Binding IsTicked}" Content="{Binding Name}"></CheckBox>
244+
</DataTemplate>
245+
</ListView.ItemTemplate>
246+
<ListView.ItemContainerStyle>
247+
<Style TargetType="{x:Type ListViewItem}">
248+
<Setter Property="BorderThickness" Value="0"/>
249+
<Setter Property="Padding" Value="5"/>
250+
<!-- Add a trigger to handle focus if a dotted outline remains -->
251+
<Style.Triggers>
252+
<Trigger Property="IsFocused" Value="True">
253+
<Setter Property="BorderThickness" Value="0"/>
254+
<!-- You might also need to set the focus visual style to null in more complex scenarios -->
255+
</Trigger>
256+
</Style.Triggers>
257+
</Style>
258+
</ListView.ItemContainerStyle>
259+
</ListView>
260+
</ScrollViewer>
261+
<Grid Grid.Row="2">
262+
<Grid.ColumnDefinitions>
263+
<ColumnDefinition Width="*"/>
264+
<ColumnDefinition Width="20"/>
265+
</Grid.ColumnDefinitions>
266+
<TextBox x:Name="AddTagText" Grid.Column="0"></TextBox>
267+
<Button Style="{StaticResource BorderlessButton}" Grid.Column="1" Click="AddTagButton_OnClick">
268+
<fa:FontAwesome Icon="Plus"></fa:FontAwesome>
269+
</Button>
270+
</Grid>
271+
</Grid>
272+
</TabItem>
225273
<TabItem Header="Workflow" Background="Transparent" GotFocus="UIElement_OnGotFocus" HorizontalContentAlignment="Stretch">
226274
<ScrollViewer Background="Transparent" VerticalScrollBarVisibility="Auto">
227275
<local:ComfyNodeStack Nodes="{Binding Nodes}" Background="Transparent"></local:ComfyNodeStack>

0 commit comments

Comments
 (0)