1 // OpenTween - Client of Twitter
2 // Copyright (c) 2007-2011 kiri_feather (@kiri_feather) <kiri.feather@gmail.com>
3 // (c) 2008-2011 Moz (@syo68k)
4 // (c) 2008-2011 takeshik (@takeshik) <http://www.takeshik.org/>
5 // (c) 2010-2011 anis774 (@anis774) <http://d.hatena.ne.jp/anis774/>
6 // (c) 2010-2011 fantasticswallow (@f_swallow) <http://twitter.com/f_swallow>
7 // (c) 2011 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
8 // All rights reserved.
10 // This file is part of OpenTween.
12 // This program is free software; you can redistribute it and/or modify it
13 // under the terms of the GNU General Public License as published by the Free
14 // Software Foundation; either version 3 of the License, or (at your option)
17 // This program is distributed in the hope that it will be useful, but
18 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 // You should have received a copy of the GNU General Public License along
23 // with this program. If not, see <http://www.gnu.org/licenses/>, or write to
24 // the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
25 // Boston, MA 02110-1301, USA.
30 using System.Collections.Generic;
31 using System.ComponentModel;
36 using System.Threading.Tasks;
37 using System.Windows.Forms;
38 using OpenTween.Connection;
39 using OpenTween.Models;
43 public partial class ListManage : OTBaseForm
45 private readonly Twitter tw;
47 public ListManage(Twitter tw)
49 this.InitializeComponent();
54 private void ListManage_KeyDown(object sender, KeyEventArgs e)
56 if (e.KeyCode == Keys.Enter && this.EditCheckBox.Checked)
57 this.OKEditButton.PerformClick();
60 private async void ListManage_Load(object sender, EventArgs e)
62 using (ControlTransaction.Disabled(this))
66 var lists = (IReadOnlyList<ListElement>)TabInformations.GetInstance().SubscribableLists;
68 lists = await this.FetchListsAsync();
70 this.UpdateListsListBox(lists);
72 catch (OperationCanceledException)
74 this.DialogResult = DialogResult.Cancel;
77 catch (WebApiException)
79 this.DialogResult = DialogResult.Abort;
85 private void ListsList_SelectedIndexChanged(object sender, EventArgs e)
87 if (this.ListsList.SelectedItem == null) return;
89 var list = (ListElement)this.ListsList.SelectedItem;
90 this.UsernameTextBox.Text = list.Username;
91 this.NameTextBox.Text = list.Name;
92 this.PublicRadioButton.Checked = list.IsPublic;
93 this.PrivateRadioButton.Checked = !list.IsPublic;
94 this.MemberCountTextBox.Text = list.MemberCount.ToString();
95 this.SubscriberCountTextBox.Text = list.SubscriberCount.ToString();
96 this.DescriptionText.Text = list.Description;
98 this.UserList.Items.Clear();
99 foreach (var user in list.Members)
100 this.UserList.Items.Add(user);
102 this.GetMoreUsersButton.Text = this.UserList.Items.Count > 0 ? Properties.Resources.ListManageGetMoreUsers2 : Properties.Resources.ListManageGetMoreUsers1;
105 private void EditCheckBox_CheckedChanged(object sender, EventArgs e)
107 this.AddListButton.Enabled = !this.EditCheckBox.Checked;
108 this.EditCheckBox.Enabled = !this.EditCheckBox.Checked;
109 this.DeleteListButton.Enabled = !this.EditCheckBox.Checked;
111 this.NameTextBox.ReadOnly = !this.EditCheckBox.Checked;
112 this.PublicRadioButton.Enabled = this.EditCheckBox.Checked;
113 this.PrivateRadioButton.Enabled = this.EditCheckBox.Checked;
114 this.DescriptionText.ReadOnly = !this.EditCheckBox.Checked;
115 this.ListsList.Enabled = !this.EditCheckBox.Checked;
117 this.OKEditButton.Enabled = this.EditCheckBox.Checked;
118 this.CancelEditButton.Enabled = this.EditCheckBox.Checked;
119 this.EditCheckBox.AutoCheck = !this.EditCheckBox.Checked;
121 this.MemberGroup.Enabled = !this.EditCheckBox.Checked;
122 this.UserGroup.Enabled = !this.EditCheckBox.Checked;
123 this.CloseButton.Enabled = !this.EditCheckBox.Checked;
125 this.UsernameTextBox.TabStop = !this.EditCheckBox.Checked;
126 this.MemberCountTextBox.TabStop = !this.EditCheckBox.Checked;
127 this.SubscriberCountTextBox.TabStop = !this.EditCheckBox.Checked;
128 if (this.EditCheckBox.Checked == true) this.NameTextBox.Focus();
131 private async void OKEditButton_Click(object sender, EventArgs e)
133 if (this.ListsList.SelectedItem == null) return;
135 using (ControlTransaction.Disabled(this))
137 var listItem = (ListElement)this.ListsList.SelectedItem;
139 if (MyCommon.IsNullOrEmpty(this.NameTextBox.Text))
141 MessageBox.Show(Properties.Resources.ListManageOKButton1);
145 listItem.Name = this.NameTextBox.Text;
146 listItem.IsPublic = this.PublicRadioButton.Checked;
147 listItem.Description = this.DescriptionText.Text;
151 await listItem.Refresh();
153 catch (WebApiException ex)
155 MessageBox.Show(string.Format(Properties.Resources.ListManageOKButton2, ex.Message));
159 this.ListsList.Items.Clear();
160 this.ListManage_Load(this, EventArgs.Empty);
162 this.EditCheckBox.AutoCheck = true;
163 this.EditCheckBox.Checked = false;
167 private void CancelEditButton_Click(object sender, EventArgs e)
169 this.EditCheckBox.AutoCheck = true;
170 this.EditCheckBox.Checked = false;
172 for (var i = this.ListsList.Items.Count - 1; i >= 0; i--)
174 if (this.ListsList.Items[i] is NewListElement)
175 this.ListsList.Items.RemoveAt(i);
178 this.ListsList_SelectedIndexChanged(this.ListsList, EventArgs.Empty);
181 private async void RefreshUsersButton_Click(object sender, EventArgs e)
183 using (ControlTransaction.Disabled(this))
185 if (this.ListsList.SelectedItem == null) return;
186 this.UserList.Items.Clear();
188 var list = (ListElement)this.ListsList.SelectedItem;
191 await list.RefreshMembers();
193 catch (WebApiException ex)
195 MessageBox.Show(string.Format(Properties.Resources.ListManageGetListMembersCallback1, ex.Message));
199 this.ListsList_SelectedIndexChanged(this.ListsList, EventArgs.Empty);
200 this.GetMoreUsersButton.Text = Properties.Resources.ListManageGetMoreUsers1;
204 private async void GetMoreUsersButton_Click(object sender, EventArgs e)
206 using (ControlTransaction.Disabled(this))
208 if (this.ListsList.SelectedItem == null) return;
209 this.UserList.Items.Clear();
211 var list = (ListElement)this.ListsList.SelectedItem;
214 await list.GetMoreMembers();
216 catch (WebApiException ex)
218 MessageBox.Show(string.Format(Properties.Resources.ListManageGetListMembersCallback1, ex.Message));
222 this.ListsList_SelectedIndexChanged(this.ListsList, EventArgs.Empty);
223 this.GetMoreUsersButton.Text = Properties.Resources.ListManageGetMoreUsers1;
227 private async void DeleteUserButton_Click(object sender, EventArgs e)
229 if (this.ListsList.SelectedItem == null || this.UserList.SelectedItem == null)
232 using (ControlTransaction.Disabled(this))
234 var list = (ListElement)this.ListsList.SelectedItem;
235 var user = (UserInfo)this.UserList.SelectedItem;
236 if (MessageBox.Show(Properties.Resources.ListManageDeleteUser1, ApplicationSettings.ApplicationName, MessageBoxButtons.OKCancel) == DialogResult.OK)
240 await this.tw.Api.ListsMembersDestroy(list.Id, user.ScreenName)
243 catch (WebApiException ex)
245 MessageBox.Show(string.Format(Properties.Resources.ListManageDeleteUser2, ex.Message));
249 var idx = this.ListsList.SelectedIndex;
250 list.Members.Remove(user);
251 this.ListsList_SelectedIndexChanged(this.ListsList, EventArgs.Empty);
252 if (idx < this.ListsList.Items.Count) this.ListsList.SelectedIndex = idx;
257 private async void DeleteListButton_Click(object sender, EventArgs e)
259 if (this.ListsList.SelectedItem == null) return;
261 using (ControlTransaction.Disabled(this))
263 var list = (ListElement)this.ListsList.SelectedItem;
265 if (MessageBox.Show(Properties.Resources.ListManageDeleteLists1, ApplicationSettings.ApplicationName, MessageBoxButtons.OKCancel) == DialogResult.OK)
269 await this.tw.DeleteList(list.Id);
271 catch (WebApiException ex)
273 MessageBox.Show(Properties.Resources.ListManageOKButton2, ex.Message);
279 await this.tw.GetListsApi();
281 catch (WebApiException ex)
283 MessageBox.Show(Properties.Resources.ListsDeleteFailed, ex.Message);
287 this.ListsList.Items.Clear();
288 this.ListManage_Load(this, EventArgs.Empty);
293 private void AddListButton_Click(object sender, EventArgs e)
295 var newList = new NewListElement(this.tw);
296 this.ListsList.Items.Add(newList);
297 this.ListsList.SelectedItem = newList;
298 this.EditCheckBox.Checked = true;
299 this.EditCheckBox_CheckedChanged(this.EditCheckBox, EventArgs.Empty);
302 private async void UserList_SelectedIndexChanged(object sender, EventArgs e)
304 if (this.UserList.SelectedItem == null)
306 this.UserIcon.Image?.Dispose();
307 this.UserIcon.Image = null;
308 this.UserLocation.Text = "";
309 this.UserWeb.Text = "";
310 this.UserFollowNum.Text = "0";
311 this.UserFollowerNum.Text = "0";
312 this.UserPostsNum.Text = "0";
313 this.UserProfile.Text = "";
314 this.UserTweetDateTime.Text = "";
315 this.UserTweet.Text = "";
316 this.DeleteUserButton.Enabled = false;
320 var user = (UserInfo)this.UserList.SelectedItem;
321 this.UserLocation.Text = user.Location;
322 this.UserWeb.Text = user.Url;
323 this.UserFollowNum.Text = user.FriendsCount.ToString("#,###,##0");
324 this.UserFollowerNum.Text = user.FollowersCount.ToString("#,###,##0");
325 this.UserPostsNum.Text = user.StatusesCount.ToString("#,###,##0");
326 this.UserProfile.Text = user.Description;
327 if (!MyCommon.IsNullOrEmpty(user.RecentPost))
329 this.UserTweetDateTime.Text = user.PostCreatedAt.ToLocalTimeString("yy/MM/dd HH:mm");
330 this.UserTweet.Text = user.RecentPost;
334 this.UserTweetDateTime.Text = "";
335 this.UserTweet.Text = "";
337 this.DeleteUserButton.Enabled = true;
339 if (user.ImageUrl != null)
340 await this.LoadUserIconAsync(user.ImageUrl, user.Id);
344 private async Task LoadUserIconAsync(Uri imageUri, PersonId userId)
346 var oldImage = this.UserIcon.Image;
347 this.UserIcon.Image = null;
350 await this.UserIcon.SetImageFromTask(async () =>
352 var sizeName = Twitter.DecideProfileImageSize(this.UserIcon.Width);
353 var uri = Twitter.CreateProfileImageUrl(imageUri.AbsoluteUri, sizeName);
355 using var imageStream = await Networking.Http.GetStreamAsync(uri);
356 var image = await MemoryImage.CopyFromStreamAsync(imageStream);
358 // 画像の読み込み中に選択中のユーザーが変化していたらキャンセルとして扱う
359 var selectedUser = (UserInfo)this.UserList.SelectedItem;
360 if (selectedUser.Id != userId)
363 throw new OperationCanceledException();
370 private async void RefreshListsButton_Click(object sender, EventArgs e)
372 using (ControlTransaction.Disabled(this))
376 var lists = await this.FetchListsAsync();
377 this.UpdateListsListBox(lists);
379 catch (OperationCanceledException)
382 catch (WebApiException ex)
384 MessageBox.Show(string.Format(Properties.Resources.ListsDeleteFailed, ex.Message));
389 private async Task<IReadOnlyList<ListElement>> FetchListsAsync()
391 using var dialog = new WaitingDialog(Properties.Resources.ListsGetting);
392 var cancellationToken = dialog.EnableCancellation();
394 var task = this.tw.GetListsApi();
395 await dialog.WaitForAsync(this, task);
397 cancellationToken.ThrowIfCancellationRequested();
399 return TabInformations.GetInstance().SubscribableLists;
402 private void UpdateListsListBox(IEnumerable<ListElement> lists)
404 using (ControlTransaction.Update(this.ListsList))
406 this.ListsList.Items.Clear();
407 foreach (var listItem in lists.Where(x => x.UserId == this.tw.UserId))
409 this.ListsList.Items.Add(listItem);
411 if (this.ListsList.Items.Count > 0)
412 this.ListsList.SelectedIndex = 0;
413 this.ListsList.Focus();
417 private async void UserWeb_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
418 => await MyCommon.OpenInBrowserAsync(this, this.UserWeb.Text);
420 private class NewListElement : ListElement
422 public bool IsCreated { get; private set; } = false;
424 public NewListElement(Twitter tw)
427 public override async Task Refresh()
431 await base.Refresh().ConfigureAwait(false);
435 await this.tw.CreateListApi(this.Name, !this.IsPublic, this.Description)
436 .ConfigureAwait(false);
438 this.IsCreated = true;
442 public override string ToString()
445 return base.ToString();
451 private void ListManage_Validating(object sender, CancelEventArgs e)
453 if (this.EditCheckBox.Checked)
456 this.CancelButton.PerformClick();